diff --git a/AUTHORS b/AUTHORS index 2dd1239cb..6f98d2038 100644 --- a/AUTHORS +++ b/AUTHORS @@ -3,7 +3,7 @@ GNSS-SDR Authorship The GNSS-SDR project is hosted and sponsored by the Centre Tecnològic de Telecomunicacions de Catalunya (CTTC), a non-profit research foundation located -in Castelldefels (40.396764 N, 3.713379 E), 20 km south of Barcelona, Spain. +in Castelldefels (41.27504 N, 1.987709 E), 20 km south of Barcelona, Spain. GNSS-SDR is the by-product of GNSS research conducted at the Communications Systems Division of CTTC, and it is the combined effort of students, software engineers and researchers from different institutions around the World. @@ -50,6 +50,7 @@ Daniel Fehr daniel.co@bluewin.ch Contributor David Pubill david.pubill@cttc.cat Contributor Fran Fabra fabra@ice.csic.es Contributor Gabriel Araujo gabriel.araujo.5000@gmail.com Contributor +Gerald LaMountain gerald@gece.neu.edu Contributor Leonardo Tonetto tonetto.dev@gmail.com Contributor Mara Branzanti mara.branzanti@gmail.com Contributor Marc Molina marc.molina.pena@gmail.com Contributor diff --git a/CMakeLists.txt b/CMakeLists.txt index b3ef3dd27..5f6568200 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ ######################################################################## if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) message(WARNING "In-tree build is bad practice. Try 'cd build && cmake ../' ") -endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) +endif() cmake_minimum_required(VERSION 2.8) project(gnss-sdr CXX C) @@ -31,11 +31,11 @@ file(RELATIVE_PATH RELATIVE_CMAKE_CALL ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRE if(NOT CMAKE_PREFIX_PATH) if(DEFINED ENV{PYBOMBS_PREFIX}) set(CMAKE_PREFIX_PATH $ENV{PYBOMBS_PREFIX}) - endif(DEFINED ENV{PYBOMBS_PREFIX}) + endif() if(DEFINED ENV{SNAP}) set(CMAKE_PREFIX_PATH $ENV{SNAP}) - endif(DEFINED ENV{SNAP}) -endif(NOT CMAKE_PREFIX_PATH) + endif() +endif() @@ -45,7 +45,7 @@ endif(NOT CMAKE_PREFIX_PATH) ######################################################################## # Support of optional RF front-ends option(ENABLE_UHD "Enable the use of UHD (driver for all USRP devices)" ON) -option(ENABLE_OSMOSDR "Enable the use of OsmoSDR and other front-ends (RTL-based dongles, HackRF, bladeRF, etc.) as signal source (experimental)" OFF) +option(ENABLE_OSMOSDR "Enable the use of OsmoSDR and other front-ends (RTL-based dongles, HackRF, bladeRF, etc.) as signal source" OFF) option(ENABLE_FLEXIBAND "Enable the use of the signal source adater for the Teleorbit Flexiband GNURadio driver" OFF) option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal source (experimental)" OFF) option(ENABLE_GN3S "Enable the use of the GN3S dongle as signal source (experimental)" OFF) @@ -72,21 +72,22 @@ option(ENABLE_OWN_ARMADILLO "Download and build Armadillo locally" OFF) option(ENABLE_LOG "Enable logging" ON) if(ENABLE_PACKAGING) set(ENABLE_GENERIC_ARCH ON) -endif(ENABLE_PACKAGING) +endif() # Testing option(ENABLE_UNIT_TESTING "Build unit tests" ON) +option(ENABLE_UNIT_TESTING_MINIMAL "Build a minimal set of unit tests" OFF) option(ENABLE_UNIT_TESTING_EXTRA "Download external files and build extra unit tests" OFF) option(ENABLE_SYSTEM_TESTING "Build system tests" OFF) option(ENABLE_SYSTEM_TESTING_EXTRA "Download external tools and build extra system tests" OFF) if(ENABLE_SYSTEM_TESTING_EXTRA) set(ENABLE_SYSTEM_TESTING ON) -endif(ENABLE_SYSTEM_TESTING_EXTRA) +endif() option(ENABLE_OWN_GPSTK "Force to download, build and link GPSTk for system tests, even if it is already installed" OFF) option(ENABLE_INSTALL_TESTS "Install QA code system-wide" OFF) if(ENABLE_FPGA) set(ENABLE_INSTALL_TESTS ON) -endif(ENABLE_FPGA) +endif() @@ -97,28 +98,27 @@ set(THIS_IS_A_RELEASE ON) # only related to version name, no further implicati if(NOT ${THIS_IS_A_RELEASE}) # Get the current working branch execute_process( - COMMAND git rev-parse --abbrev-ref HEAD - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE GIT_BRANCH - OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND git rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_BRANCH + OUTPUT_STRIP_TRAILING_WHITESPACE ) - # Get the latest abbreviated commit hash of the working branch execute_process( - COMMAND git log -1 --format=%h - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE GIT_COMMIT_HASH - OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND git log -1 --format=%h + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE ) -endif(NOT ${THIS_IS_A_RELEASE}) +endif() set(VERSION_INFO_MAJOR_VERSION 0) -set(VERSION_INFO_API_COMPAT 0) +set(VERSION_INFO_API_COMPAT 0) if(${THIS_IS_A_RELEASE}) set(VERSION_INFO_MINOR_VERSION 10) -else(${THIS_IS_A_RELEASE}) +else() set(VERSION_INFO_MINOR_VERSION 10.git-${GIT_BRANCH}-${GIT_COMMIT_HASH}) -endif(${THIS_IS_A_RELEASE}) +endif() set(VERSION ${VERSION_INFO_MAJOR_VERSION}.${VERSION_INFO_API_COMPAT}.${VERSION_INFO_MINOR_VERSION}) @@ -129,182 +129,195 @@ set(VERSION ${VERSION_INFO_MAJOR_VERSION}.${VERSION_INFO_API_COMPAT}.${VERSION_I ######################################################################## include(ExternalProject) # Detect 64-bits machine -if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - set(ARCH_64BITS TRUE) -endif( CMAKE_SIZEOF_VOID_P EQUAL 8 ) +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(ARCH_64BITS TRUE) +endif() set(OS_IS_MACOSX "") set(OS_IS_LINUX "") # Detect Linux Distribution if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - set(OperatingSystem "Linux") - set(OS_IS_LINUX TRUE) - if(ARCH_64BITS) - set(ARCH_ "(64 bits)") - else(ARCH_64BITS) - set(ARCH_ "(32 bits)") - endif(ARCH_64BITS) - if(EXISTS "/etc/lsb-release") - execute_process(COMMAND cat /etc/lsb-release - COMMAND grep DISTRIB_ID - COMMAND awk -F= "{ print $2 }" - COMMAND tr "\n" " " - COMMAND sed "s/ //" - OUTPUT_VARIABLE LINUX_DISTRIBUTION - RESULT_VARIABLE LINUX_ID_RESULT - ) - execute_process(COMMAND cat /etc/lsb-release - COMMAND grep DISTRIB_RELEASE - COMMAND awk -F= "{ print $2 }" - COMMAND tr "\n" " " - COMMAND sed "s/ //" - OUTPUT_VARIABLE LINUX_VER - RESULT_VARIABLE LINUX_VER_RESULT - ) - endif(EXISTS "/etc/lsb-release") - if(NOT LINUX_DISTRIBUTION) - if(EXISTS "/etc/linuxmint/info") - set(LINUX_DISTRIBUTION "LinuxMint") - execute_process(COMMAND cat /etc/linuxmint/info - COMMAND grep -m1 RELEASE - COMMAND awk -F= "{ print $2 }" - COMMAND tr "\n" " " - COMMAND sed "s/ //" - OUTPUT_VARIABLE LINUX_VER - RESULT_VARIABLE LINUX_VER_RESULT - ) - endif(EXISTS "/etc/linuxmint/info") - endif(NOT LINUX_DISTRIBUTION) - if(NOT LINUX_DISTRIBUTION) - if(EXISTS "/etc/os-release") - execute_process(COMMAND cat /etc/os-release - COMMAND grep -m1 NAME - COMMAND awk -F= "{ print $2 }" - COMMAND tr "\n" " " - COMMAND sed "s/ //" - OUTPUT_VARIABLE LINUX_DISTRIBUTION - RESULT_VARIABLE LINUX_ID_RESULT - ) - execute_process(COMMAND cat /etc/os-release - COMMAND grep VERSION_ID - COMMAND awk -F= "{ print $2 }" - COMMAND tr "\n" " " - COMMAND sed "s/ //" - OUTPUT_VARIABLE LINUX_VER - RESULT_VARIABLE LINUX_VER_RESULT - ) - if(${LINUX_DISTRIBUTION} MATCHES "Debian") - set(LINUX_DISTRIBUTION "Debian") - file(READ /etc/debian_version LINUX_VER) - endif(${LINUX_DISTRIBUTION} MATCHES "Debian") - endif(EXISTS "/etc/os-release") - endif(NOT LINUX_DISTRIBUTION) - if(NOT LINUX_DISTRIBUTION) - if(EXISTS "/etc/redhat-release") - set(LINUX_DISTRIBUTION "Red Hat") - file (READ /etc/redhat-release LINUX_VER) - endif(EXISTS "/etc/redhat-release") - endif(NOT LINUX_DISTRIBUTION) - if(NOT LINUX_DISTRIBUTION) - if(EXISTS "/etc/debian_version") - set(LINUX_DISTRIBUTION "Debian") - file (READ /etc/debian_version LINUX_VER) - endif(EXISTS "/etc/debian_version") - endif(NOT LINUX_DISTRIBUTION) - if(NOT LINUX_DISTRIBUTION) - set(LINUX_DISTRIBUTION "Generic") - set(LINUX_VER "Unknown") - endif(NOT LINUX_DISTRIBUTION) - message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on ${LINUX_DISTRIBUTION} GNU/Linux Release ${LINUX_VER} ${ARCH_}") -endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(OperatingSystem "Linux") + set(OS_IS_LINUX TRUE) + if(ARCH_64BITS) + set(ARCH_ "(64 bits)") + else() + set(ARCH_ "(32 bits)") + endif() + if(EXISTS "/etc/lsb-release") + execute_process(COMMAND cat /etc/lsb-release + COMMAND grep DISTRIB_ID + COMMAND awk -F= "{ print $2 }" + COMMAND tr "\n" " " + COMMAND sed "s/ //" + OUTPUT_VARIABLE LINUX_DISTRIBUTION + RESULT_VARIABLE LINUX_ID_RESULT + ) + execute_process(COMMAND cat /etc/lsb-release + COMMAND grep DISTRIB_RELEASE + COMMAND awk -F= "{ print $2 }" + COMMAND tr "\n" " " + COMMAND sed "s/ //" + OUTPUT_VARIABLE LINUX_VER + RESULT_VARIABLE LINUX_VER_RESULT + ) + endif() + if(NOT LINUX_DISTRIBUTION) + if(EXISTS "/etc/linuxmint/info") + set(LINUX_DISTRIBUTION "LinuxMint") + execute_process(COMMAND cat /etc/linuxmint/info + COMMAND grep -m1 RELEASE + COMMAND awk -F= "{ print $2 }" + COMMAND tr "\n" " " + COMMAND sed "s/ //" + OUTPUT_VARIABLE LINUX_VER + RESULT_VARIABLE LINUX_VER_RESULT + ) + endif() + endif() + if(NOT LINUX_DISTRIBUTION) + if(EXISTS "/etc/os-release") + execute_process(COMMAND cat /etc/os-release + COMMAND grep -m1 NAME + COMMAND awk -F= "{ print $2 }" + COMMAND tr "\n" " " + COMMAND sed "s/ //" + OUTPUT_VARIABLE LINUX_DISTRIBUTION + RESULT_VARIABLE LINUX_ID_RESULT + ) + execute_process(COMMAND cat /etc/os-release + COMMAND grep VERSION_ID + COMMAND awk -F= "{ print $2 }" + COMMAND tr "\n" " " + COMMAND sed "s/ //" + OUTPUT_VARIABLE LINUX_VER + RESULT_VARIABLE LINUX_VER_RESULT + ) + if(${LINUX_DISTRIBUTION} MATCHES "Debian") + set(LINUX_DISTRIBUTION "Debian") + file(READ /etc/debian_version LINUX_VER) + endif() + endif() + endif() + if(NOT LINUX_DISTRIBUTION) + if(EXISTS "/etc/redhat-release") + set(LINUX_DISTRIBUTION "Red Hat") + file(READ /etc/redhat-release LINUX_VER) + endif() + endif() + if(NOT LINUX_DISTRIBUTION) + if(EXISTS "/etc/debian_version") + set(LINUX_DISTRIBUTION "Debian") + file(READ /etc/debian_version LINUX_VER) + endif() + endif() + if(NOT LINUX_DISTRIBUTION) + set(LINUX_DISTRIBUTION "Generic") + set(LINUX_VER "Unknown") + endif() + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on ${LINUX_DISTRIBUTION} GNU/Linux Release ${LINUX_VER} ${ARCH_}") +endif() if(NOT LINUX_DISTRIBUTION) set(LINUX_DISTRIBUTION "Unknown") -endif(NOT LINUX_DISTRIBUTION) +endif() # Detect macOS / Mac OS X Version if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(OperatingSystem "Mac OS X") - set(OS_IS_MACOSX TRUE) - exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION) - string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION}) - if(${DARWIN_VERSION} MATCHES "17") - set(MACOS_HIGH_SIERRA TRUE) - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14") - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") - message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on macOS High Sierra 10.13") - endif(${DARWIN_VERSION} MATCHES "17") - if(${DARWIN_VERSION} MATCHES "16") - set(MACOS_SIERRA TRUE) - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14") - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") - message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on macOS Sierra 10.12") - endif(${DARWIN_VERSION} MATCHES "16") - if(${DARWIN_VERSION} MATCHES "15") - set(MACOSX_EL_CAPITAN TRUE) - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11") - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") - message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.11 El Capitan") - endif(${DARWIN_VERSION} MATCHES "15") - if(${DARWIN_VERSION} MATCHES "14") - set(MACOSX_YOSEMITE TRUE) - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11") - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") - message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.10 Yosemite") - endif(${DARWIN_VERSION} MATCHES "14") - if(${DARWIN_VERSION} MATCHES "13") - set(MACOSX_MAVERICKS TRUE) - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11") - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") - set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION="com.apple.compilers.llvm.clang.1_0") - message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.9 Mavericks") - endif(${DARWIN_VERSION} MATCHES "13") - if(${DARWIN_VERSION} MATCHES "12") - message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.8 Mountain Lion") - endif(${DARWIN_VERSION} MATCHES "12") - if(${DARWIN_VERSION} MATCHES "11") - message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.7 Lion") - endif(${DARWIN_VERSION} MATCHES "11") - if(${DARWIN_VERSION} MATCHES "10") - message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.6 Snow Leopard") - endif(${DARWIN_VERSION} MATCHES "10") -endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(OperatingSystem "Mac OS X") + set(OS_IS_MACOSX TRUE) + execute_process(COMMAND uname -v OUTPUT_VARIABLE DARWIN_VERSION) + string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION}) + if(${DARWIN_VERSION} MATCHES "18") + set(MACOS_MOJAVE TRUE) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on macOS Mojave 10.14") + endif() + if(${DARWIN_VERSION} MATCHES "17") + set(MACOS_HIGH_SIERRA TRUE) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on macOS High Sierra 10.13") + endif() + if(${DARWIN_VERSION} MATCHES "16") + set(MACOS_SIERRA TRUE) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on macOS Sierra 10.12") + endif() + if(${DARWIN_VERSION} MATCHES "15") + set(MACOSX_EL_CAPITAN TRUE) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.11 El Capitan") + endif() + if(${DARWIN_VERSION} MATCHES "14") + set(MACOSX_YOSEMITE TRUE) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.10 Yosemite") + endif() + if(${DARWIN_VERSION} MATCHES "13") + set(MACOSX_MAVERICKS TRUE) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION="com.apple.compilers.llvm.clang.1_0") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.9 Mavericks") + endif() + if(${DARWIN_VERSION} MATCHES "12") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.8 Mountain Lion") + endif() + if(${DARWIN_VERSION} MATCHES "11") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.7 Lion") + endif() + if(${DARWIN_VERSION} MATCHES "10") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on Mac OS X 10.6 Snow Leopard") + endif() +endif() -#select the release build type by default to get optimization flags +# Define extra build types and select Release by default to get optimization flags +include(GnsssdrBuildTypes) +# Available options: +# - None: nothing set +# - Debug: -O2 -g +# - Release: -O3 +# - RelWithDebInfo: -O3 -g +# - MinSizeRel: -Os +# - Coverage: -Wall -pedantic -pthread -g -O0 -fprofile-arcs -ftest-coverage +# - NoOptWithASM: -O0 -g -save-temps +# - O2WithASM: -O2 -g -save-temps +# - O3WithASM: -O3 -g -save-temps +# - ASAN: -Wall -Wextra -g -O2 -fsanitize=address -fno-omit-frame-pointer if(NOT CMAKE_BUILD_TYPE) - if(ENABLE_GPERFTOOLS OR ENABLE_GPROF) - set(CMAKE_BUILD_TYPE "RelWithDebInfo") - message(STATUS "Build type not specified: defaulting to RelWithDebInfo.") - else(ENABLE_GPERFTOOLS OR ENABLE_GPROF) - set(CMAKE_BUILD_TYPE "Release") - message(STATUS "Build type not specified: defaulting to Release.") - endif(ENABLE_GPERFTOOLS OR ENABLE_GPROF) -else(NOT CMAKE_BUILD_TYPE) - message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.") -endif(NOT CMAKE_BUILD_TYPE) + if(ENABLE_GPERFTOOLS OR ENABLE_GPROF) + set(CMAKE_BUILD_TYPE "RelWithDebInfo") + message(STATUS "Build type not specified: defaulting to RelWithDebInfo.") + else() + set(CMAKE_BUILD_TYPE "Release") + message(STATUS "Build type not specified: defaulting to Release.") + endif() +else() + message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.") +endif() +gnsssdr_check_build_type(${CMAKE_BUILD_TYPE}) set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") -# Append -O2 optimization flag for Debug builds -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2") - # allow 'large' files in 32 bit builds if(UNIX) - add_definitions( -D_LARGEFILE_SOURCE - -D_FILE_OFFSET_BITS=64 - -D_LARGE_FILES - ) -endif(UNIX) + add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES) +endif() # Determine if we are using make or ninja if(CMAKE_MAKE_PROGRAM MATCHES "make") - set(CMAKE_MAKE_PROGRAM_PRETTY_NAME "make") -endif(CMAKE_MAKE_PROGRAM MATCHES "make") + set(CMAKE_MAKE_PROGRAM_PRETTY_NAME "make") +endif() if(CMAKE_MAKE_PROGRAM MATCHES "ninja") - set(CMAKE_MAKE_PROGRAM_PRETTY_NAME "ninja") -endif(CMAKE_MAKE_PROGRAM MATCHES "ninja") + set(CMAKE_MAKE_PROGRAM_PRETTY_NAME "ninja") +endif() if(NOT CMAKE_MAKE_PROGRAM_PRETTY_NAME) - set(CMAKE_MAKE_PROGRAM_PRETTY_NAME "${CMAKE_MAKE_PROGRAM}") -endif(NOT CMAKE_MAKE_PROGRAM_PRETTY_NAME) + set(CMAKE_MAKE_PROGRAM_PRETTY_NAME "${CMAKE_MAKE_PROGRAM}") +endif() @@ -318,6 +331,7 @@ set(GNSSSDR_APPLECLANG_MIN_VERSION "500") set(GNSSSDR_GNURADIO_MIN_VERSION "3.7.3") set(GNSSSDR_BOOST_MIN_VERSION "1.45") set(GNSSSDR_PYTHON_MIN_VERSION "2.7") +set(GNSSSDR_PYTHON3_MIN_VERSION "3.4") set(GNSSSDR_MAKO_MIN_VERSION "0.4.2") set(GNSSSDR_ARMADILLO_MIN_VERSION "5.300.0") set(GNSSSDR_MATIO_MIN_VERSION "1.5.3") @@ -327,23 +341,28 @@ set(GNSSSDR_MATIO_MIN_VERSION "1.5.3") ################################################################################ # Versions to download and build (but not installed) if not found ################################################################################ -set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.1") +set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2") set(GNSSSDR_GLOG_LOCAL_VERSION "0.3.5") -set(GNSSSDR_ARMADILLO_LOCAL_VERSION "unstable") -set(GNSSSDR_GTEST_LOCAL_VERSION "1.8.0") +set(GNSSSDR_ARMADILLO_LOCAL_VERSION "9.200.x") +set(GNSSSDR_GTEST_LOCAL_VERSION "1.8.1") set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master") -set(GNSSSDR_GPSTK_LOCAL_VERSION "2.10") -set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.12") +set(GNSSSDR_GPSTK_LOCAL_VERSION "2.10.6") +set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.13") +set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.9") + +if(CMAKE_VERSION VERSION_LESS "3.0.2") # Fix for CentOS 7 + set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.1") +endif() ################################################################################ -# Check cmake version +# Check CMake version ################################################################################ if(CMAKE_VERSION VERSION_LESS ${GNSSSDR_CMAKE_MIN_VERSION}) - message(STATUS "Your CMake version is too old and does not support some features required by GNSS-SDR. CMake version must be at least ${GNSSSDR_CMAKE_MIN_VERSION}. For more information check https://github.com/joakimkarlsson/bandit/issues/40") - message(FATAL_ERROR "Fatal error: CMake >= ${GNSSSDR_CMAKE_MIN_VERSION} required.") -endif(CMAKE_VERSION VERSION_LESS ${GNSSSDR_CMAKE_MIN_VERSION}) + message(STATUS "Your CMake version is too old and does not support some features required by GNSS-SDR. CMake version must be at least ${GNSSSDR_CMAKE_MIN_VERSION}.") + message(FATAL_ERROR "Fatal error: CMake >= ${GNSSSDR_CMAKE_MIN_VERSION} required.") +endif() @@ -351,16 +370,11 @@ endif(CMAKE_VERSION VERSION_LESS ${GNSSSDR_CMAKE_MIN_VERSION}) # Check compiler version ################################################################################ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${GNSSSDR_GCC_MIN_VERSION}) - message(STATUS "Your GCC version is too old and does not support some C++ features required by GNSS-SDR. GCC version must be at least ${GNSSSDR_GCC_MIN_VERSION}") - if(${LINUX_DISTRIBUTION} MATCHES "Ubuntu") - if(${LINUX_VER} MATCHES "12.04") - message(STATUS "For instructions on how to upgrade GCC, check https://askubuntu.com/a/271561") - endif(${LINUX_VER} MATCHES "12.04") - endif(${LINUX_DISTRIBUTION} MATCHES "Ubuntu") - message(FATAL_ERROR "Fatal error: GCC >= ${GNSSSDR_GCC_MIN_VERSION} required.") - endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${GNSSSDR_GCC_MIN_VERSION}) -endif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${GNSSSDR_GCC_MIN_VERSION}) + message(STATUS "Your GCC version is too old and does not support some C++ features required by GNSS-SDR. GCC version must be at least ${GNSSSDR_GCC_MIN_VERSION}") + message(FATAL_ERROR "Fatal error: GCC >= ${GNSSSDR_GCC_MIN_VERSION} required.") + endif() +endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") execute_process(COMMAND @@ -376,20 +390,20 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # retrieve the compiler's version from it string(REGEX MATCH "clang version [0-9.]+" CLANG_OTHER_VERSION ${_err}) string(REGEX MATCH "[0-9.]+" CLANG_VERSION ${CLANG_OTHER_VERSION}) - else("${IS_APPLE}" STREQUAL "") + else() set(MIN_VERSION ${GNSSSDR_APPLECLANG_MIN_VERSION}) set(APPLE_STR "Apple ") # retrieve the compiler's version from it string(REGEX MATCH "(clang-[0-9.]+)" CLANG_APPLE_VERSION ${_err}) string(REGEX MATCH "[0-9.]+" CLANG_VERSION ${CLANG_APPLE_VERSION}) - endif("${IS_APPLE}" STREQUAL "") + endif() if(${CLANG_VERSION} VERSION_LESS "${MIN_VERSION}") message(WARNING "\nThe compiler selected to build GNSS-SDR (${APPLE_STR}Clang version ${CLANG_VERSION} : ${CMAKE_CXX_COMPILER}) is older than that officially supported (${MIN_VERSION} minimum). This build may or not work. We highly recommend using Apple Clang version ${APPLECLANG_MIN_VERSION} or more recent, or Clang version ${CLANG_MIN_VERSION} or more recent.") - endif(${CLANG_VERSION} VERSION_LESS "${MIN_VERSION}") - else(${_res} STREQUAL "0") + endif() + else() message(WARNING "\nCannot determine the version of the compiler selected to build GNSS-SDR (${APPLE_STR}Clang : ${CMAKE_CXX_COMPILER}). This build may or not work. We highly recommend using Apple Clang version ${APPLECLANG_MIN_VERSION} or more recent, or Clang version ${CLANG_MIN_VERSION} or more recent.") - endif(${_res} STREQUAL "0") -endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + endif() +endif() @@ -399,10 +413,10 @@ endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if(NOT OS_IS_MACOSX) if(CMAKE_CROSSCOMPILING) set(IS_ARM TRUE) - else(CMAKE_CROSSCOMPILING) + else() include(TestForARM) - endif(CMAKE_CROSSCOMPILING) -endif(NOT OS_IS_MACOSX) + endif() +endif() @@ -410,8 +424,8 @@ endif(NOT OS_IS_MACOSX) # Check for availability of SSE ################################################################################ if(NOT ENABLE_GENERIC_ARCH) - include(TestForSSE) -endif(NOT ENABLE_GENERIC_ARCH) + include(TestForSSE) +endif() @@ -420,17 +434,17 @@ endif(NOT ENABLE_GENERIC_ARCH) ################################################################################ if(CMAKE_VERSION VERSION_LESS 3.1) find_package(Threads REQUIRED) - link_libraries(${CMAKE_THREAD_LIBS_INIT}) -else(CMAKE_VERSION VERSION_LESS 3.1) + set(THREAD_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) +else() set(CMAKE_THREAD_PREFER_PTHREAD TRUE) if(CMAKE_CROSSCOMPILING) set(THREADS_PREFER_PTHREAD_FLAG FALSE) - else(CMAKE_CROSSCOMPILING) + else() set(THREADS_PREFER_PTHREAD_FLAG TRUE) - endif(CMAKE_CROSSCOMPILING) + endif() find_package(Threads REQUIRED) - link_libraries(Threads::Threads) -endif(CMAKE_VERSION VERSION_LESS 3.1) + set(THREAD_LIBRARIES Threads::Threads) +endif() @@ -441,28 +455,28 @@ enable_testing() if(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING) if(EXISTS $ENV{GTEST_DIR}) set(GTEST_DIR $ENV{GTEST_DIR}) - endif(EXISTS $ENV{GTEST_DIR}) + endif() if(GTEST_DIR) message(STATUS "Googletest root folder set at ${GTEST_DIR}") find_path(LIBGTEST_DEV_DIR NAMES src/gtest-all.cc PATHS ${GTEST_DIR}) if(LIBGTEST_DEV_DIR) - message (STATUS "Googletest has been found.") - else(LIBGTEST_DEV_DIR) - message (FATAL_ERROR " Googletest source code has not been found at ${GTEST_DIR}.") - endif(LIBGTEST_DEV_DIR) + message(STATUS "Googletest has been found.") + else() + message(FATAL_ERROR " Googletest source code has not been found at ${GTEST_DIR}.") + endif() find_path(GTEST_INCLUDE_DIRS NAMES gtest/gtest.h PATHS ${GTEST_DIR}/include) - else(GTEST_DIR) - find_path(LIBGTEST_DEV_DIR NAMES src/gtest-all.cc PATHS /usr/src/googletest/googletest /usr/src/gtest /usr/include/gtest /opt/local/src/gtest-1.7.0 ) + else() + find_path(LIBGTEST_DEV_DIR NAMES src/gtest-all.cc PATHS /usr/src/googletest/googletest /usr/src/gtest /usr/include/gtest /opt/local/src/gtest-1.7.0) find_path(GTEST_INCLUDE_DIRS NAMES gtest/gtest.h PATHS /usr/include /opt/local/src/gtest-1.7.0/include) if(LIBGTEST_DEV_DIR) - message (STATUS "Googletest package has been found.") - else(LIBGTEST_DEV_DIR) - message (STATUS " Googletest has not been found.") - message (STATUS " Googletest v${GNSSSDR_GTEST_LOCAL_VERSION} will be downloaded and built automatically ") - message (STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'. ") - endif(LIBGTEST_DEV_DIR) - endif(GTEST_DIR) -endif(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING) + message(STATUS "Googletest package has been found.") + else() + message(STATUS " Googletest has not been found.") + message(STATUS " Googletest v${GNSSSDR_GTEST_LOCAL_VERSION} will be downloaded and built automatically ") + message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'. ") + endif() + endif() +endif() @@ -471,7 +485,7 @@ endif(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING) ################################################################################ if(UNIX AND EXISTS "/usr/lib64") list(APPEND BOOST_LIBRARYDIR "/usr/lib64") # Fedora 64-bit fix -endif(UNIX AND EXISTS "/usr/lib64") +endif() set(Boost_ADDITIONAL_VERSIONS "1.45.0" "1.45" "1.46.0" "1.46" "1.48.0" "1.48" "1.49.0" "1.49" "1.50.0" "1.50" "1.51.0" "1.51" "1.53.0" "1.53" "1.54.0" "1.54" @@ -480,13 +494,14 @@ set(Boost_ADDITIONAL_VERSIONS "1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69" "1.70.0" "1.70" "1.71.0" "1.71" "1.72.0" "1.72" "1.73.0" "1.73" "1.74.0" "1.74" "1.75.0" "1.75" "1.76.0" "1.76" "1.77.0" "1.77" "1.78.0" "1.78" "1.79.0" "1.79" + "1.80.0" "1.80" "1.81.0" "1.81" "1.82.0" "1.82" "1.83.0" "1.83" "1.84.0" "1.84" ) set(Boost_USE_MULTITHREAD ON) set(Boost_USE_STATIC_LIBS OFF) find_package(Boost COMPONENTS date_time system filesystem thread serialization chrono REQUIRED) if(NOT Boost_FOUND) - message(FATAL_ERROR "Fatal error: Boost (version >=${GNSSSDR_BOOST_MIN_VERSION}) required.") -endif(NOT Boost_FOUND) + message(FATAL_ERROR "Fatal error: Boost (version >=${GNSSSDR_BOOST_MIN_VERSION}) required.") +endif() @@ -494,29 +509,28 @@ endif(NOT Boost_FOUND) # GNU Radio - https://gnuradio.org ################################################################################ set(GR_REQUIRED_COMPONENTS RUNTIME ANALOG BLOCKS FFT FILTER PMT) -find_package(Gnuradio) +find_package(GNURADIO) if(PC_GNURADIO_RUNTIME_VERSION) - if(PC_GNURADIO_RUNTIME_VERSION VERSION_LESS ${GNSSSDR_GNURADIO_MIN_VERSION}) - set(GNURADIO_RUNTIME_FOUND) - message(STATUS "The GNU Radio version installed in your system is too old.") - endif(PC_GNURADIO_RUNTIME_VERSION VERSION_LESS ${GNSSSDR_GNURADIO_MIN_VERSION}) -endif(PC_GNURADIO_RUNTIME_VERSION) + if(PC_GNURADIO_RUNTIME_VERSION VERSION_LESS ${GNSSSDR_GNURADIO_MIN_VERSION}) + set(GNURADIO_RUNTIME_FOUND) + message(STATUS "The GNU Radio version installed in your system is too old.") + endif() +endif() if(NOT GNURADIO_RUNTIME_FOUND) - message(STATUS "CMake cannot find GNU Radio >= ${GNSSSDR_GNURADIO_MIN_VERSION}") - if(OS_IS_LINUX) - message("Go to https://github.com/gnuradio/pybombs") - message("and follow the instructions to install GNU Radio in your system.") - message(FATAL_ERROR "GNU Radio ${GNSSSDR_GNURADIO_MIN_VERSION} or later is required to build gnss-sdr") - endif(OS_IS_LINUX) - if(OS_IS_MACOSX) - message("You can install it easily via Macports:") - message(" sudo port install gnuradio ") - message("Alternatively, you can use homebrew:") - message(" brew tap odrisci/gnuradio") - message(" brew install gnuradio" ) - message(FATAL_ERROR "GNU Radio ${GNSSSDR_GNURADIO_MIN_VERSION} or later is required to build gnss-sdr") - endif(OS_IS_MACOSX) -endif(NOT GNURADIO_RUNTIME_FOUND) + message(STATUS "CMake cannot find GNU Radio >= ${GNSSSDR_GNURADIO_MIN_VERSION}") + if(OS_IS_LINUX) + message("Go to https://github.com/gnuradio/pybombs") + message("and follow the instructions to install GNU Radio in your system.") + message(FATAL_ERROR "GNU Radio ${GNSSSDR_GNURADIO_MIN_VERSION} or later is required to build gnss-sdr") + endif() + if(OS_IS_MACOSX) + message("You can install it easily via Macports:") + message(" sudo port install gnuradio ") + message("Alternatively, you can use homebrew:") + message(" brew install gnuradio") + message(FATAL_ERROR "GNU Radio ${GNSSSDR_GNURADIO_MIN_VERSION} or later is required to build gnss-sdr") + endif() +endif() if(NOT GNURADIO_ANALOG_FOUND) message(FATAL_ERROR "*** The gnuradio-analog library v${GNSSSDR_GNURADIO_MIN_VERSION} or later is required to build gnss-sdr") @@ -539,7 +553,7 @@ endif() ################################################################################ # VOLK - Vector-Optimized Library of Kernels ################################################################################ -find_package(Volk) +find_package(VOLK) if(NOT VOLK_FOUND) message(FATAL_ERROR "*** VOLK is required to build gnss-sdr") endif() @@ -549,7 +563,7 @@ endif() ################################################################################ # Log4cpp - http://log4cpp.sourceforge.net/ ################################################################################ -find_package(Log4cpp) +find_package(LOG4CPP) if(NOT LOG4CPP_FOUND) message(FATAL_ERROR "*** Log4cpp is required to build gnss-sdr") endif() @@ -559,118 +573,122 @@ endif() ################################################################################ # volk_gnsssdr module - GNSS-SDR's own VOLK library ################################################################################ -find_package(VolkGnssSdr) - -if(NOT VOLK_GNSSSDR_FOUND) +find_package(VOLKGNSSSDR) +if(NOT VOLKGNSSSDR_FOUND) message(STATUS " volk_gnsssdr will be built along with gnss-sdr when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'") ############################### # Find Python required modules ############################### - include(SetupPython) #sets PYTHON_EXECUTABLE and PYTHON_DASH_B - GNSSSDR_PYTHON_CHECK_MODULE("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND) - GNSSSDR_PYTHON_CHECK_MODULE("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND) - GNSSSDR_PYTHON_CHECK_MODULE("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) + include(SetupPython) # sets PYTHON_EXECUTABLE and search for required modules if(NOT PYTHON_MIN_VER_FOUND) message(FATAL_ERROR "Python ${GNSSSDR_PYTHON_MIN_VERSION} or greater required to build VOLK_GNSSSDR") endif() + if(${PYTHON3}) + set(PYTHON_NAME "python3") + else() + set(PYTHON_NAME "python") + endif() + # Mako if(NOT MAKO_FOUND) - message(STATUS "Mako templates not found. See http://www.makotemplates.org/ ") + message(STATUS "Mako template library not found. See http://www.makotemplates.org/ ") message(STATUS " You can try to install it by typing:") if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(STATUS " sudo yum install python-mako") + message(STATUS " sudo yum install ${PYTHON_NAME}-mako") elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") - message(STATUS " sudo zypper install python-Mako") - else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(STATUS " sudo apt-get install python-mako") - endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + message(STATUS " sudo zypper install ${PYTHON_NAME}-Mako") + else() + message(STATUS " sudo apt-get install ${PYTHON_NAME}-mako") + endif() message(FATAL_ERROR "Mako templates required to build VOLK_GNSSSDR") - endif(NOT MAKO_FOUND) + endif() # Six if(NOT SIX_FOUND) message(STATUS "python-six not found. See https://pythonhosted.org/six/ ") message(STATUS " You can try to install it by typing:") if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(STATUS " sudo yum install python-six") + message(STATUS " sudo yum install ${PYTHON_NAME}-six") elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") - message(STATUS " sudo zypper install python-six") - else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(STATUS " sudo apt-get install python-six") - endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + message(STATUS " sudo zypper install ${PYTHON_NAME}-six") + else() + message(STATUS " sudo apt-get install ${PYTHON_NAME}-six") + endif() message(FATAL_ERROR "six - python 2 and 3 compatibility library required to build VOLK_GNSSSDR") - endif(NOT SIX_FOUND) + endif() set(READ_ENVIRO "") if(ENABLE_PACKAGING) - if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) + if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) set(STRIP_VOLK_GNSSSDR_PROFILE "-DENABLE_STRIP=ON -DCMAKE_VERBOSE_MAKEFILE=ON") - endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) - set(READ_ENVIRO ${CMAKE_COMMAND} -E environment) - endif(ENABLE_PACKAGING) + endif() + if(NOT DEFINED ENV{PROTECT_PASSWORDS}) + set(READ_ENVIRO ${CMAKE_COMMAND} -E environment) + endif() + endif() set(VOLK_GNSSSDR_BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}") if(PYTHON_EXECUTABLE) set(USE_THIS_PYTHON "-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}") - endif(PYTHON_EXECUTABLE) + endif() if(OS_IS_MACOSX) if(CMAKE_GENERATOR STREQUAL Xcode) set(VOLK_GNSSSDR_BUILD_COMMAND "xcodebuild" "-configuration" "Debug" "-target") - endif(CMAKE_GENERATOR STREQUAL Xcode) - endif(OS_IS_MACOSX) + endif() + endif() if(CMAKE_CROSSCOMPILING) set(VOLK_GNSSSDR_COMPILER "") - else(CMAKE_CROSSCOMPILING) + else() set(VOLK_GNSSSDR_COMPILER -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}) - endif(CMAKE_CROSSCOMPILING) + endif() set(VOLK_GNSSSDR_CMAKE_ARGS ${VOLK_GNSSSDR_COMPILER} - -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install - -DENABLE_STATIC_LIBS=ON - -DENABLE_PROFILING=${ENABLE_PROFILING} - -DCMAKE_INCLUDE_PATH=${Boost_INCLUDE_DIR} - -DENABLE_ORC=OFF - ${STRIP_VOLK_GNSSSDR_PROFILE} - ${USE_THIS_PYTHON} ) + -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install + -DENABLE_STATIC_LIBS=ON + -DENABLE_PROFILING=${ENABLE_PROFILING} + -DCMAKE_INCLUDE_PATH=${Boost_INCLUDE_DIR} + -DENABLE_ORC=OFF + ${STRIP_VOLK_GNSSSDR_PROFILE} + ${USE_THIS_PYTHON}) if(EXISTS $ENV{OECORE_TARGET_SYSROOT}) set(VOLK_GNSSSDR_CMAKE_ARGS ${VOLK_GNSSSDR_CMAKE_ARGS} - -DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/Toolchains/oe-sdk_cross.cmake - -DCROSSCOMPILE_MULTILIB=TRUE ) - endif(EXISTS $ENV{OECORE_TARGET_SYSROOT}) + -DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/Toolchains/oe-sdk_cross.cmake + -DCROSSCOMPILE_MULTILIB=TRUE) + endif() if(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add(volk_gnsssdr_module - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/build - CMAKE_ARGS ${READ_ENVIRO} ${VOLK_GNSSSDR_CMAKE_ARGS} - DOWNLOAD_COMMAND "" - UPDATE_COMMAND "" - PATCH_COMMAND "" - BUILD_COMMAND ${READ_ENVIRO} ${VOLK_GNSSSDR_BUILD_COMMAND} volk_gnsssdr_profile - INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install - ) - else(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add(volk_gnsssdr_module - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/build - CMAKE_ARGS ${READ_ENVIRO} ${VOLK_GNSSSDR_CMAKE_ARGS} - DOWNLOAD_COMMAND "" - UPDATE_COMMAND "" - PATCH_COMMAND "" - BUILD_COMMAND ${READ_ENVIRO} ${VOLK_GNSSSDR_BUILD_COMMAND} volk_gnsssdr_profile - BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}volk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX} - ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile - INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install - ) - endif(CMAKE_VERSION VERSION_LESS 3.2) + ExternalProject_Add(volk_gnsssdr_module + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/build + CMAKE_ARGS ${READ_ENVIRO} ${VOLK_GNSSSDR_CMAKE_ARGS} + DOWNLOAD_COMMAND "" + UPDATE_COMMAND "" + PATCH_COMMAND "" + BUILD_COMMAND ${READ_ENVIRO} ${VOLK_GNSSSDR_BUILD_COMMAND} volk_gnsssdr_profile + INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install + ) + else() + ExternalProject_Add(volk_gnsssdr_module + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/build + CMAKE_ARGS ${READ_ENVIRO} ${VOLK_GNSSSDR_CMAKE_ARGS} + DOWNLOAD_COMMAND "" + UPDATE_COMMAND "" + PATCH_COMMAND "" + BUILD_COMMAND ${READ_ENVIRO} ${VOLK_GNSSSDR_BUILD_COMMAND} volk_gnsssdr_profile + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}volk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX} + ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile + INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install + ) + endif() find_package(ORC) if(NOT ORC_FOUND) - set(ORC_LIBRARIES "") - set(ORC_INCLUDE_DIRS "") - endif(NOT ORC_FOUND) + set(ORC_LIBRARIES "") + set(ORC_INCLUDE_DIRS "") + endif() add_library(volk_gnsssdr UNKNOWN IMPORTED) set_property(TARGET volk_gnsssdr PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install/lib/libvolk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}) @@ -678,20 +696,20 @@ if(NOT VOLK_GNSSSDR_FOUND) set(VOLK_GNSSSDR_LIBRARIES volk_gnsssdr ${ORC_LIBRARIES}) if(CMAKE_VERSION VERSION_LESS 3.2) - add_custom_command(TARGET volk_gnsssdr_module POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile + add_custom_command(TARGET volk_gnsssdr_module POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile ${CMAKE_SOURCE_DIR}/install/volk_gnsssdr_profile) - else(CMAKE_VERSION VERSION_LESS 3.2) - add_custom_command(TARGET volk_gnsssdr_module POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile + else() + add_custom_command(TARGET volk_gnsssdr_module POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile ${CMAKE_SOURCE_DIR}/install/volk_gnsssdr_profile - BYPRODUCTS ${CMAKE_SOURCE_DIR}/install/volk_gnsssdr_profile) - endif(CMAKE_VERSION VERSION_LESS 3.2) + BYPRODUCTS ${CMAKE_SOURCE_DIR}/install/volk_gnsssdr_profile) + endif() add_custom_command(TARGET volk_gnsssdr_module POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr-config-info - ${CMAKE_SOURCE_DIR}/install/volk_gnsssdr-config-info) -endif(NOT VOLK_GNSSSDR_FOUND) + ${CMAKE_SOURCE_DIR}/install/volk_gnsssdr-config-info) +endif() @@ -699,59 +717,57 @@ endif(NOT VOLK_GNSSSDR_FOUND) # gflags - https://github.com/gflags/gflags ################################################################################ set(LOCAL_GFLAGS false) -find_package(GFlags) -if (NOT GFlags_FOUND) - message (STATUS " gflags library has not been found.") - message (STATUS " gflags v${GNSSSDR_GFLAGS_LOCAL_VERSION} will be downloaded and built automatically ") - message (STATUS " when doing 'make'. ") +find_package(GFLAGS) +if(NOT GFLAGS_FOUND) + message(STATUS " gflags library has not been found.") + message(STATUS " gflags v${GNSSSDR_GFLAGS_LOCAL_VERSION} will be downloaded and built automatically ") + message(STATUS " when doing 'make'. ") - if(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add( - gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - GIT_REPOSITORY git://github.com/gflags/gflags.git - GIT_TAG v${GNSSSDR_GFLAGS_LOCAL_VERSION} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/gflags/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - CMAKE_ARGS -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DBUILD_gflags_nothreads_LIB=OFF -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND "" - ) - else(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add( - gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - GIT_REPOSITORY git://github.com/gflags/gflags.git - GIT_TAG v${GNSSSDR_GFLAGS_LOCAL_VERSION} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/gflags/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - CMAKE_ARGS -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DBUILD_gflags_nothreads_LIB=OFF -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} - BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND "" - ) - endif(CMAKE_VERSION VERSION_LESS 3.2) + if(CMAKE_VERSION VERSION_LESS 3.2) + ExternalProject_Add(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + GIT_REPOSITORY git://github.com/gflags/gflags.git + GIT_TAG v${GNSSSDR_GFLAGS_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/gflags/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + CMAKE_ARGS -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DBUILD_gflags_nothreads_LIB=OFF -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + else() + ExternalProject_Add(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + GIT_REPOSITORY git://github.com/gflags/gflags.git + GIT_TAG v${GNSSSDR_GFLAGS_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/gflags/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + CMAKE_ARGS -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DBUILD_gflags_nothreads_LIB=OFF -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + endif() - set(GFlags_INCLUDE_DIRS - ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/include CACHE PATH "Local Gflags headers" - ) + set(GFlags_INCLUDE_DIRS + ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/include CACHE PATH "Local Gflags headers" + ) - add_library(gflags UNKNOWN IMPORTED) - set_property(TARGET gflags PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX}) - add_dependencies(gflags gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) - set(GFlags_LIBS gflags) - file(GLOB GFlags_SHARED_LIBS "${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_SHARED_LIBRARY_SUFFIX}*") - set(GFlags_LIBRARY gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) - set(GFlags_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib ) - link_directories(${GFlags_LIBRARY_PATH}) - set(GFlags_lib ${GFlags_LIBS} CACHE FILEPATH "Local Gflags library") - set(GFlags_LIBRARY_PATH ${GFlags_LIBS}) - set(LOCAL_GFLAGS true CACHE STRING "GFlags downloaded and built automatically" FORCE) -endif(NOT GFlags_FOUND) + add_library(gflags UNKNOWN IMPORTED) + set_property(TARGET gflags PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX}) + add_dependencies(gflags gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) + set(GFlags_LIBS gflags) + file(GLOB GFlags_SHARED_LIBS "${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_SHARED_LIBRARY_SUFFIX}*") + set(GFlags_LIBRARY gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) + set(GFlags_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib) + link_directories(${GFlags_LIBRARY_PATH}) + set(GFlags_lib ${GFlags_LIBS} CACHE FILEPATH "Local Gflags library") + set(GFlags_LIBRARY_PATH ${GFlags_LIBS}) + set(LOCAL_GFLAGS true CACHE STRING "GFlags downloaded and built automatically" FORCE) +endif() @@ -759,34 +775,34 @@ endif(NOT GFlags_FOUND) # glog - https://github.com/google/glog ################################################################################ if(NOT ${ENABLE_OWN_GLOG}) - find_package(GLOG) - if(GLOG_INCLUDE_DIRS) + find_package(GLOG) + if(GLOG_INCLUDE_DIRS) set(GLOG_FOUND ON) - endif(GLOG_INCLUDE_DIRS) -endif(NOT ${ENABLE_OWN_GLOG}) + endif() +endif() set(glog_RELEASE ${GNSSSDR_GLOG_LOCAL_VERSION}) -if (NOT GLOG_FOUND OR ${LOCAL_GFLAGS}) - message (STATUS " glog library has not been found") - if(NOT GFlags_FOUND) - message(STATUS " or it is likely not linked to gflags.") - endif(NOT GFlags_FOUND) - message (STATUS " glog v${GNSSSDR_GLOG_LOCAL_VERSION} will be downloaded and built automatically ") - message (STATUS " when doing 'make'. ") - if(NOT ${LOCAL_GFLAGS}) - add_library(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} UNKNOWN IMPORTED) - set_property(TARGET gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} PROPERTY IMPORTED_LOCATION "${GFlags_LIBS}") - endif(NOT ${LOCAL_GFLAGS}) - set(TARGET_GFLAGS gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) - if(${LOCAL_GFLAGS}) - set(GFLAGS_LIBRARIES_TO_LINK ${GFlags_SHARED_LIBS}) - set(GFLAGS_LIBRARY_DIR_TO_LINK ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib) - else(${LOCAL_GFLAGS}) - set(GFLAGS_LIBRARIES_TO_LINK ${GFlags_LIBS}) - set(GFLAGS_LIBRARY_DIR_TO_LINK ${GFlags_LIBRARY_DIRS}) - endif(${LOCAL_GFLAGS}) +if(NOT GLOG_FOUND OR ${LOCAL_GFLAGS}) + message(STATUS " glog library has not been found") + if(NOT GFLAGS_FOUND) + message(STATUS " or it is likely not linked to gflags.") + endif() + message(STATUS " glog v${GNSSSDR_GLOG_LOCAL_VERSION} will be downloaded and built automatically ") + message(STATUS " when doing 'make'. ") + if(NOT ${LOCAL_GFLAGS}) + add_library(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} UNKNOWN IMPORTED) + set_property(TARGET gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} PROPERTY IMPORTED_LOCATION "${GFlags_LIBS}") + endif() + set(TARGET_GFLAGS gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) + if(${LOCAL_GFLAGS}) + set(GFLAGS_LIBRARIES_TO_LINK ${GFlags_SHARED_LIBS}) + set(GFLAGS_LIBRARY_DIR_TO_LINK ${CMAKE_CURRENT_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib) + else() + set(GFLAGS_LIBRARIES_TO_LINK ${GFlags_LIBS}) + set(GFLAGS_LIBRARY_DIR_TO_LINK ${GFlags_LIBRARY_DIRS}) + endif() - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/tmp/configure_with_gflags + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/tmp/configure_with_gflags "#!/bin/sh export CPPFLAGS=-I${GFlags_INCLUDE_DIRS} export LDFLAGS=-L${GFLAGS_LIBRARY_DIR_TO_LINK} @@ -801,8 +817,8 @@ autoreconf -vfi cd ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure") - else(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/tmp/configure_with_gflags + else() + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/tmp/configure_with_gflags "#!/bin/sh export CPPFLAGS=-I${GFlags_INCLUDE_DIRS} export LDFLAGS=-L${GFLAGS_LIBRARY_DIR_TO_LINK} @@ -813,98 +829,95 @@ automake --add-missing autoreconf -vfi cd ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure") + endif() - endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + file(COPY ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/tmp/configure_with_gflags + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ + GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) - file(COPY ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/tmp/configure_with_gflags - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ - GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + set(GLOG_CONFIGURE ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure_with_gflags) - set(GLOG_CONFIGURE ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure_with_gflags) + # Ensure that aclocal and libtool are present + if(OS_IS_LINUX) + if(EXISTS "/usr/bin/libtoolize") + if(EXISTS "/usr/bin/aclocal" OR EXISTS "/usr/bin/aclocal-1.16" OR EXISTS "/usr/bin/aclocal-1.15" OR EXISTS "/usr/bin/aclocal-1.14" OR EXISTS "/usr/bin/aclocal-1.13" OR EXISTS "/usr/bin/aclocal-1.11" OR EXISTS "/usr/bin/aclocal-1.10") + # Everything ok, we can move on + else() + message(" aclocal has not been found.") + message(" You can try to install it by typing:") + if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + message(" sudo yum groupinstall 'Development Tools'") + elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") + message(" sudo zypper install automake") + else() + message(" sudo apt-get install automake") + endif() + message(FATAL_ERROR "aclocal is required to build glog from source") + endif() + else() + message(" libtool has not been found.") + message(" You can try to install it by typing:") + if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + message(" sudo yum groupinstall 'Development Tools'") + elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") + message(" sudo zypper install libtoool") + else() + message(" sudo apt-get install libtool") + endif() + message(FATAL_ERROR "libtool is required to build glog from source") + endif() + endif() - # Ensure that aclocal and libtool are present - if(OS_IS_LINUX) - if(EXISTS "/usr/bin/libtoolize") - if(EXISTS "/usr/bin/aclocal" OR EXISTS "/usr/bin/aclocal-1.16" OR EXISTS "/usr/bin/aclocal-1.15" OR EXISTS "/usr/bin/aclocal-1.14" OR EXISTS "/usr/bin/aclocal-1.13" OR EXISTS "/usr/bin/aclocal-1.11" OR EXISTS "/usr/bin/aclocal-1.10") - # Everything ok, we can move on - else(EXISTS "/usr/bin/aclocal" OR EXISTS "/usr/bin/aclocal-1.16" OR EXISTS "/usr/bin/aclocal-1.15" OR EXISTS "/usr/bin/aclocal-1.14" OR EXISTS "/usr/bin/aclocal-1.13" OR EXISTS "/usr/bin/aclocal-1.11" OR EXISTS "/usr/bin/aclocal-1.10") - message(" aclocal has not been found.") - message(" You can try to install it by typing:") - if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(" sudo yum groupinstall 'Development Tools'") - elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") - message(" sudo zypper install automake") - else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(" sudo apt-get install automake") - endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(FATAL_ERROR "aclocal is required to build glog from source") - endif(EXISTS "/usr/bin/aclocal" OR EXISTS "/usr/bin/aclocal-1.16" OR EXISTS "/usr/bin/aclocal-1.15" OR EXISTS "/usr/bin/aclocal-1.14" OR EXISTS "/usr/bin/aclocal-1.13" OR EXISTS "/usr/bin/aclocal-1.11" OR EXISTS "/usr/bin/aclocal-1.10") - else(EXISTS "/usr/bin/libtoolize") - message(" libtool has not been found.") - message(" You can try to install it by typing:") - if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(" sudo yum groupinstall 'Development Tools'") - elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") - message(" sudo zypper install libtoool") - else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(" sudo apt-get install libtool") - endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(FATAL_ERROR "libtool is required to build glog from source") - endif(EXISTS "/usr/bin/libtoolize") - endif(OS_IS_LINUX) + if(CMAKE_VERSION VERSION_LESS 3.2) + ExternalProject_Add(glog-${GNSSSDR_GLOG_LOCAL_VERSION} + DEPENDS ${TARGET_GFLAGS} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/google/glog/ + GIT_TAG v${GNSSSDR_GLOG_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + CONFIGURE_COMMAND ${GLOG_CONFIGURE} --prefix= + BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}" + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + else() + ExternalProject_Add(glog-${GNSSSDR_GLOG_LOCAL_VERSION} + DEPENDS ${TARGET_GFLAGS} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/google/glog/ + GIT_TAG v${GNSSSDR_GLOG_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + CONFIGURE_COMMAND ${GLOG_CONFIGURE} --prefix= + BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}" + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/.libs/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + endif() - if(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add( - glog-${GNSSSDR_GLOG_LOCAL_VERSION} - DEPENDS ${TARGET_GFLAGS} - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - GIT_REPOSITORY https://github.com/google/glog/ - GIT_TAG v${GNSSSDR_GLOG_LOCAL_VERSION} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - CONFIGURE_COMMAND ${GLOG_CONFIGURE} --prefix= - BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}" - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND "" - ) - else(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add( - glog-${GNSSSDR_GLOG_LOCAL_VERSION} - DEPENDS ${TARGET_GFLAGS} - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - GIT_REPOSITORY https://github.com/google/glog/ - GIT_TAG v${GNSSSDR_GLOG_LOCAL_VERSION} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - CONFIGURE_COMMAND ${GLOG_CONFIGURE} --prefix= - BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}" - BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/.libs/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND "" - ) - endif(CMAKE_VERSION VERSION_LESS 3.2) - - # Set up variables - set(GLOG_INCLUDE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src/ - ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src - ) - set(GLOG_LIBRARIES - ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/.libs/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} - ) - set(LOCAL_GLOG true CACHE STRING "Glog downloaded and built automatically" FORCE) -else(NOT GLOG_FOUND OR ${LOCAL_GFLAGS}) - add_library(glog-${GNSSSDR_GLOG_LOCAL_VERSION} UNKNOWN IMPORTED) - set_property(TARGET glog-${GNSSSDR_GLOG_LOCAL_VERSION} PROPERTY IMPORTED_LOCATION "${GLOG_LIBRARIES}") -endif(NOT GLOG_FOUND OR ${LOCAL_GFLAGS}) + # Set up variables + set(GLOG_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src/ + ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src + ) + set(GLOG_LIBRARIES + ${CMAKE_CURRENT_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/.libs/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + set(LOCAL_GLOG true CACHE STRING "Glog downloaded and built automatically" FORCE) +else() + add_library(glog-${GNSSSDR_GLOG_LOCAL_VERSION} UNKNOWN IMPORTED) + set_property(TARGET glog-${GNSSSDR_GLOG_LOCAL_VERSION} PROPERTY IMPORTED_LOCATION "${GLOG_LIBRARIES}") +endif() if(NOT ENABLE_LOG) - message(STATUS "Logging is not enabled") - add_definitions(-DGOOGLE_STRIP_LOG=1) -endif(NOT ENABLE_LOG) + message(STATUS "Logging is not enabled") + add_definitions(-DGOOGLE_STRIP_LOG=1) +endif() @@ -918,11 +931,11 @@ if(NOT BLAS) message(" You can try to install it by typing:") if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") message(" sudo yum install blas-devel") - else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + else() message(" sudo apt-get install libblas-dev") - endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + endif() message(FATAL_ERROR "BLAS is required to build gnss-sdr") -endif(NOT BLAS) +endif() @@ -938,11 +951,11 @@ if(NOT LAPACK) message(" sudo yum install lapack-devel") elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(" sudo zypper install lapack-devel") - else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + else() message(" sudo apt-get install liblapack-dev") - endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + endif() message(FATAL_ERROR "LAPACK is required to build gnss-sdr") -endif(NOT LAPACK) +endif() @@ -954,81 +967,79 @@ if(ARMADILLO_FOUND) if(${ARMADILLO_VERSION_STRING} VERSION_LESS ${GNSSSDR_ARMADILLO_MIN_VERSION}) set(ARMADILLO_FOUND false) set(ENABLE_OWN_ARMADILLO true) - endif(${ARMADILLO_VERSION_STRING} VERSION_LESS ${GNSSSDR_ARMADILLO_MIN_VERSION}) -endif(ARMADILLO_FOUND) + endif() +endif() if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO) - message(STATUS " Armadillo has not been found.") - message(STATUS " Armadillo ${GNSSSDR_ARMADILLO_LOCAL_VERSION} will be downloaded and built automatically") - message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'. ") - set(armadillo_BRANCH ${GNSSSDR_ARMADILLO_LOCAL_VERSION}) - set(armadillo_RELEASE ${armadillo_BRANCH}) + message(STATUS " Armadillo has not been found.") + message(STATUS " Armadillo ${GNSSSDR_ARMADILLO_LOCAL_VERSION} will be downloaded and built automatically") + message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'. ") + set(armadillo_BRANCH ${GNSSSDR_ARMADILLO_LOCAL_VERSION}) + set(armadillo_RELEASE ${armadillo_BRANCH}) - ############################################# - # Check if GFORTRAN is found in the system - ############################################# - if(NOT OS_IS_MACOSX) - find_package(GFORTRAN) - if(NOT GFORTRAN) - message(STATUS "The gfortran library has not been found.") - message(STATUS " You can try to install it by typing:") - if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(STATUS " sudo yum install gcc-fortran") - elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") - message(STATUS " sudo zypper install gcc-fortran") - else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(STATUS " sudo apt-get install gfortran") - endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(FATAL_ERROR "gfortran is required to build gnss-sdr") - endif(NOT GFORTRAN) - endif(NOT OS_IS_MACOSX) + ############################################# + # Check if GFORTRAN is found in the system + ############################################# + if(NOT OS_IS_MACOSX) + find_package(GFORTRAN) + if(NOT GFORTRAN) + message(STATUS "The gfortran library has not been found.") + message(STATUS " You can try to install it by typing:") + if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + message(STATUS " sudo yum install gcc-fortran") + elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") + message(STATUS " sudo zypper install gcc-fortran") + else() + message(STATUS " sudo apt-get install gfortran") + endif() + message(FATAL_ERROR "gfortran is required to build gnss-sdr") + endif() + endif() - ############################################# - # Download and build Armadillo - ############################################# - if(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add( - armadillo-${armadillo_RELEASE} - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE} - GIT_REPOSITORY https://gitlab.com/conradsnicta/armadillo-code.git - GIT_TAG ${armadillo_BRANCH} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/armadillo/armadillo-${armadillo_RELEASE} - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE} - CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_FLAGS=-std=c++11 - BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} - UPDATE_COMMAND "" - INSTALL_COMMAND "" - ) - else(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add( - armadillo-${armadillo_RELEASE} - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE} - GIT_REPOSITORY https://gitlab.com/conradsnicta/armadillo-code.git - GIT_TAG ${armadillo_BRANCH} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/armadillo/armadillo-${armadillo_RELEASE} - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE} - CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_FLAGS=-std=c++11 - BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} - BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo${CMAKE_STATIC_LIBRARY_SUFFIX} - UPDATE_COMMAND "" - INSTALL_COMMAND "" - ) - endif(CMAKE_VERSION VERSION_LESS 3.2) + ############################################# + # Download and build Armadillo + ############################################# + if(CMAKE_VERSION VERSION_LESS 3.2) + ExternalProject_Add(armadillo-${armadillo_RELEASE} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE} + GIT_REPOSITORY https://gitlab.com/conradsnicta/armadillo-code.git + GIT_TAG ${armadillo_BRANCH} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/armadillo/armadillo-${armadillo_RELEASE} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE} + CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_FLAGS=-std=c++11 + BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} + UPDATE_COMMAND "" + INSTALL_COMMAND "" + ) + else() + ExternalProject_Add(armadillo-${armadillo_RELEASE} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE} + GIT_REPOSITORY https://gitlab.com/conradsnicta/armadillo-code.git + GIT_TAG ${armadillo_BRANCH} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/armadillo/armadillo-${armadillo_RELEASE} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE} + CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_FLAGS=-std=c++11 + BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo${CMAKE_STATIC_LIBRARY_SUFFIX} + UPDATE_COMMAND "" + INSTALL_COMMAND "" + ) + endif() - # Set up variables - ExternalProject_Get_Property(armadillo-${armadillo_RELEASE} binary_dir) - set(ARMADILLO_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/armadillo/armadillo-${armadillo_RELEASE}/include ) - if(NOT GFORTRAN) - set(GFORTRAN "") - endif(NOT GFORTRAN) - set(ARMADILLO_LIBRARIES ${BLAS} ${LAPACK} ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(LOCAL_ARMADILLO true CACHE STRING "Armadillo downloaded and built automatically" FORCE) - set(ARMADILLO_VERSION_STRING ${armadillo_RELEASE}) -else(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO) - set(armadillo_RELEASE ${ARMADILLO_VERSION_STRING}) - add_library(armadillo-${armadillo_RELEASE} UNKNOWN IMPORTED) - set_property(TARGET armadillo-${armadillo_RELEASE} PROPERTY IMPORTED_LOCATION "${ARMADILLO_LIBRARIES}") -endif(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO) + # Set up variables + ExternalProject_Get_Property(armadillo-${armadillo_RELEASE} binary_dir) + set(ARMADILLO_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/armadillo/armadillo-${armadillo_RELEASE}/include) + if(NOT GFORTRAN) + set(GFORTRAN "") + endif() + set(ARMADILLO_LIBRARIES ${BLAS} ${LAPACK} ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo${CMAKE_STATIC_LIBRARY_SUFFIX}) + set(LOCAL_ARMADILLO true CACHE STRING "Armadillo downloaded and built automatically" FORCE) + set(ARMADILLO_VERSION_STRING ${armadillo_RELEASE}) +else() + set(armadillo_RELEASE ${ARMADILLO_VERSION_STRING}) + add_library(armadillo-${armadillo_RELEASE} UNKNOWN IMPORTED) + set_property(TARGET armadillo-${armadillo_RELEASE} PROPERTY IMPORTED_LOCATION "${ARMADILLO_LIBRARIES}") +endif() @@ -1037,60 +1048,60 @@ endif(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO) ################################################################################ find_package(GnuTLS) find_library(GNUTLS_OPENSSL_LIBRARY NAMES gnutls-openssl libgnutls-openssl.so.27 - HINTS /usr/lib - /usr/lib64 - /usr/local/lib - /usr/local/lib64 - /opt/local/lib - /usr/lib/x86_64-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/i386-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/i386-gnu - /usr/lib/i686-gnu - /usr/lib/i686-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i686-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/sh4-linux-gnu - ) + HINTS /usr/lib + /usr/lib64 + /usr/local/lib + /usr/local/lib64 + /opt/local/lib + /usr/lib/x86_64-linux-gnu + /usr/lib/aarch64-linux-gnu + /usr/lib/arm-linux-gnueabihf + /usr/lib/arm-linux-gnueabi + /usr/lib/i386-linux-gnu + /usr/lib/alpha-linux-gnu + /usr/lib/hppa-linux-gnu + /usr/lib/i386-gnu + /usr/lib/i686-gnu + /usr/lib/i686-linux-gnu + /usr/lib/x86_64-kfreebsd-gnu + /usr/lib/i686-kfreebsd-gnu + /usr/lib/m68k-linux-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/mipsel-linux-gnu + /usr/lib/powerpc-linux-gnu + /usr/lib/powerpc-linux-gnuspe + /usr/lib/powerpc64-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/lib/sparc64-linux-gnu + /usr/lib/x86_64-linux-gnux32 + /usr/lib/sh4-linux-gnu +) if(NOT GNUTLS_OPENSSL_LIBRARY) - message(STATUS "Looking for OpenSSL instead...") - find_package(OpenSSL) - if(OPENSSL_FOUND) + message(STATUS "Looking for OpenSSL instead...") + find_package(OpenSSL) + if(OPENSSL_FOUND) set(GNUTLS_INCLUDE_DIR ${OPENSSL_INCLUDE_DIR}) set(GNUTLS_LIBRARIES "") set(GNUTLS_OPENSSL_LIBRARY ${OPENSSL_SSL_LIBRARY}) - else(OPENSSL_FOUND) - message(" The GnuTLS library with openssl compatibility enabled has not been found.") - message(" You can try to install the required libraries by typing:") - if(OS_IS_LINUX) + else() + message(" The GnuTLS library with openssl compatibility enabled has not been found.") + message(" You can try to install the required libraries by typing:") + if(OS_IS_LINUX) if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") message(" sudo yum install openssl-devel") - else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + else() message(" sudo apt-get install libgnutls-openssl-dev") - endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - endif(OS_IS_LINUX) - if(OS_IS_MACOSX) + endif() + endif() + if(OS_IS_MACOSX) message(" sudo port install gnutls") - endif(OS_IS_MACOSX) - message(FATAL_ERROR "GnuTLS libraries with openssl compatibility are required to build gnss-sdr") - endif(OPENSSL_FOUND) -endif(NOT GNUTLS_OPENSSL_LIBRARY) + endif() + message(FATAL_ERROR "GnuTLS libraries with openssl compatibility are required to build gnss-sdr") + endif() +endif() @@ -1100,8 +1111,8 @@ endif(NOT GNUTLS_OPENSSL_LIBRARY) find_package(MATIO) if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERSION}) if(MATIO_FOUND) - message(STATUS " Matio installed version (${MATIO_VERSION_STRING}) is too old (>= ${GNSSSDR_MATIO_MIN_VERSION} is required).") - endif(MATIO_FOUND) + message(STATUS " Matio installed version (${MATIO_VERSION_STRING}) is too old (>= ${GNSSSDR_MATIO_MIN_VERSION} is required).") + endif() message(STATUS " Matio v${GNSSSDR_MATIO_LOCAL_VERSION} will be downloaded and built automatically") message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'. ") find_package(ZLIB) @@ -1115,26 +1126,26 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS message(" sudo yum groupinstall 'Development Tools'") elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(" sudo zypper install libtoool") - else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + else() message(" sudo apt-get install libtool") - endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + endif() message(FATAL_ERROR "libtool is required to build matio from source") - endif(NOT EXISTS "/usr/bin/libtoolize") + endif() if(EXISTS "/usr/bin/aclocal" OR EXISTS "/usr/bin/aclocal-1.16" OR EXISTS "/usr/bin/aclocal-1.15" OR EXISTS "/usr/bin/aclocal-1.14" OR EXISTS "/usr/bin/aclocal-1.13" OR EXISTS "/usr/bin/aclocal-1.11" OR EXISTS "/usr/bin/aclocal-1.10") message(STATUS "Automake found.") - else(EXISTS "/usr/bin/aclocal" OR EXISTS "/usr/bin/aclocal-1.16" OR EXISTS "/usr/bin/aclocal-1.15" OR EXISTS "/usr/bin/aclocal-1.14" OR EXISTS "/usr/bin/aclocal-1.13" OR EXISTS "/usr/bin/aclocal-1.11" OR EXISTS "/usr/bin/aclocal-1.10") + else() message(" aclocal has not been found.") message(" You can try to install it by typing:") if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") message(" sudo yum groupinstall 'Development Tools'") elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(" sudo zypper install automake") - else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + else() message(" sudo apt-get install automake") - endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + endif() message(FATAL_ERROR "aclocal is required to build matio from source") - endif(EXISTS "/usr/bin/aclocal" OR EXISTS "/usr/bin/aclocal-1.16" OR EXISTS "/usr/bin/aclocal-1.15" OR EXISTS "/usr/bin/aclocal-1.14" OR EXISTS "/usr/bin/aclocal-1.13" OR EXISTS "/usr/bin/aclocal-1.11" OR EXISTS "/usr/bin/aclocal-1.10") - endif(OS_IS_LINUX) + endif() + endif() find_package(HDF5) if(HDF5_FOUND) list(GET HDF5_LIBRARIES 0 HDF5_FIRST_DIR) @@ -1143,58 +1154,102 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS if(OS_IS_MACOSX) if(EXISTS /opt/local/include/hdf5.h) set(HDF5_BASE_DIR /opt/local) - endif(EXISTS /opt/local/include/hdf5.h) + endif() if(EXISTS /usr/local/include/hdf5.h) set(HDF5_BASE_DIR /usr/local) - endif(EXISTS /usr/local/include/hdf5.h) - endif(OS_IS_MACOSX) + endif() + endif() if(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add( - matio-${GNSSSDR_MATIO_LOCAL_VERSION} - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/matio - GIT_REPOSITORY https://github.com/tbeu/matio - GIT_TAG v${GNSSSDR_MATIO_LOCAL_VERSION} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION} - UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/autogen.sh - CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_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= - BUILD_COMMAND make - ) - else(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add( - matio-${GNSSSDR_MATIO_LOCAL_VERSION} - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/matio - GIT_REPOSITORY https://github.com/tbeu/matio - GIT_TAG v${GNSSSDR_MATIO_LOCAL_VERSION} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION} - UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/autogen.sh - CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_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= - BUILD_COMMAND make - BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX} - ) - endif(CMAKE_VERSION VERSION_LESS 3.2) - set(MATIO_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX} ${HDF5_LIBRARIES} ${ZLIB_LIBRARIES} ) - set(MATIO_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/matio/include ) + ExternalProject_Add(matio-${GNSSSDR_MATIO_LOCAL_VERSION} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/matio + GIT_REPOSITORY https://github.com/tbeu/matio + GIT_TAG v${GNSSSDR_MATIO_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION} + UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/autogen.sh + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_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= + BUILD_COMMAND make + ) + else() + ExternalProject_Add(matio-${GNSSSDR_MATIO_LOCAL_VERSION} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/matio + GIT_REPOSITORY https://github.com/tbeu/matio + GIT_TAG v${GNSSSDR_MATIO_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION} + UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/autogen.sh + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_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= + BUILD_COMMAND make + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + endif() + set(MATIO_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX} ${HDF5_LIBRARIES} ${ZLIB_LIBRARIES}) + set(MATIO_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/matio/include) set(MATIO_LOCAL true) - else(HDF5_FOUND) + else() message(STATUS " The hdf5 library has not been found in your system.") message(STATUS " Please try to install it by doing:") if(OS_IS_MACOSX) message(STATUS " $ sudo port install hdf5") message(STATUS " or") message(STATUS " $ brew install hdf5") - endif(OS_IS_MACOSX) + endif() if(OS_IS_LINUX) message(STATUS " $ sudo apt-get install libhdf5-dev") - endif(OS_IS_LINUX) + endif() message(FATAL_ERROR "*** The hdf5 library is required to build gnss-sdr") - endif(HDF5_FOUND) - else(ZLIB_FOUND) + endif() + else() message(FATAL_ERROR "*** The zlib library is required to build gnss-sdr") - endif(ZLIB_FOUND) -endif(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERSION}) + endif() +endif() +################################################################################ +# PugiXML - https://pugixml.org/ +################################################################################ +find_package(PUGIXML QUIET) +if(PUGIXML_FOUND) + message(STATUS "PugiXML has been found.") +else() + message(STATUS " PugiXML v${GNSSSDR_PUGIXML_LOCAL_VERSION} will be downloaded and built automatically when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'.") + set(PUGIXML_COMPILER -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}) + set(TOOLCHAIN_ARG "") + if(EXISTS $ENV{OECORE_TARGET_SYSROOT}) + set(PUGIXML_COMPILER "") + set(TOOLCHAIN_ARG "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/Toolchains/oe-sdk_cross.cmake") + endif() + if(CMAKE_VERSION VERSION_LESS 3.2) + ExternalProject_Add(pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/zeux/pugixml + GIT_TAG v${GNSSSDR_PUGIXML_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/pugixml/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + CMAKE_ARGS ${PUGIXML_COMPILER} ${TOOLCHAIN_ARG} + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + else() + ExternalProject_Add(pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/zeux/pugixml + GIT_TAG v${GNSSSDR_PUGIXML_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/pugixml/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + CMAKE_ARGS ${PUGIXML_COMPILER} ${TOOLCHAIN_ARG} + UPDATE_COMMAND "" + PATCH_COMMAND "" + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}pugixml${CMAKE_STATIC_LIBRARY_SUFFIX} + INSTALL_COMMAND "" + ) + endif() + set(PUGIXML_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}pugixml${CMAKE_STATIC_LIBRARY_SUFFIX}) + set(PUGIXML_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/pugixml/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION}/src) + set(PUGIXML_LOCAL true) +endif() + + ################################################################################ # USRP Hardware Driver (UHD) - OPTIONAL ################################################################################ @@ -1205,11 +1260,11 @@ if(ENABLE_UHD) message(STATUS " The USRP Hardware Driver (UHD) signal source will not be built,") message(STATUS " so all USRP-based front-ends will not be usable.") message(STATUS " Please check https://files.ettus.com/manual/") - else(NOT UHD_FOUND) + else() set(GR_REQUIRED_COMPONENTS UHD) find_package(Gnuradio) - endif(NOT UHD_FOUND) -endif(ENABLE_UHD) + endif() +endif() ################################################################################ @@ -1217,62 +1272,62 @@ endif(ENABLE_UHD) ################################################################################ find_package(Doxygen) if(DOXYGEN_FOUND) - message(STATUS "Doxygen found.") - message(STATUS "You can build the documentation with '${CMAKE_MAKE_PROGRAM_PRETTY_NAME} doc'." ) - message(STATUS "When done, point your browser to ${CMAKE_BINARY_DIR}/html/index.html") - set(HAVE_DOT ${DOXYGEN_DOT_FOUND}) - file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir) - file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir) - find_package(LATEX) - if (PDFLATEX_COMPILER) - set(GENERATE_PDF_DOCUMENTATION "YES") - set(GNSSSDR_USE_MATHJAX "NO") - else(PDFLATEX_COMPILER) - set(GENERATE_PDF_DOCUMENTATION "NO") - set(GNSSSDR_USE_MATHJAX "YES") - endif(PDFLATEX_COMPILER) - configure_file(${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.in - ${CMAKE_BINARY_DIR}/docs/doxygen/Doxyfile - @ONLY - ) - add_custom_target(doc - ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/docs/doxygen/Doxyfile - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Generating API documentation with Doxygen." VERBATIM - ) - if(LATEX_COMPILER) - message(STATUS "'${CMAKE_MAKE_PROGRAM_PRETTY_NAME} pdfmanual' will generate a manual at ${CMAKE_BINARY_DIR}/docs/GNSS-SDR_manual.pdf") - add_custom_target(pdfmanual - COMMAND ${CMAKE_MAKE_PROGRAM} - COMMAND ${CMAKE_COMMAND} -E copy refman.pdf ${CMAKE_BINARY_DIR}/docs/GNSS-SDR_manual.pdf - COMMAND ${CMAKE_MAKE_PROGRAM} clean - DEPENDS doc - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/docs/latex - COMMENT "Generating PDF manual with Doxygen." VERBATIM - ) - endif(LATEX_COMPILER) - message(STATUS "'${CMAKE_MAKE_PROGRAM_PRETTY_NAME} doc-clean' will clean the documentation.") - add_custom_target(doc-clean - COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/docs/html - COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/docs/latex - COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/docs/GNSS-SDR_manual.pdf - COMMENT "Cleaning documentation." VERBATIM - ) -else(DOXYGEN_FOUND) - message(STATUS " Doxygen has not been found in your system.") - message(STATUS " You can get nice code documentation by using it!") - message(STATUS " Get it from http://www.stack.nl/~dimitri/doxygen/index.html") - if(OS_IS_LINUX) - if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(STATUS " or simply by doing 'sudo yum install doxygen-latex'.") - else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(STATUS " or simply by doing 'sudo apt-get install doxygen-latex'.") - endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - endif(OS_IS_LINUX) - if(OS_IS_MACOSX) - message(STATUS " or simply by doing 'sudo port install doxygen +latex'.") - endif(OS_IS_MACOSX) -endif(DOXYGEN_FOUND) + message(STATUS "Doxygen found.") + message(STATUS "You can build the documentation with '${CMAKE_MAKE_PROGRAM_PRETTY_NAME} doc'.") + message(STATUS "When done, point your browser to ${CMAKE_BINARY_DIR}/html/index.html") + set(HAVE_DOT ${DOXYGEN_DOT_FOUND}) + file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir) + file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir) + find_package(LATEX) + if(PDFLATEX_COMPILER) + set(GENERATE_PDF_DOCUMENTATION "YES") + set(GNSSSDR_USE_MATHJAX "NO") + else() + set(GENERATE_PDF_DOCUMENTATION "NO") + set(GNSSSDR_USE_MATHJAX "YES") + endif() + configure_file(${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.in + ${CMAKE_BINARY_DIR}/docs/doxygen/Doxyfile + @ONLY + ) + add_custom_target(doc + ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/docs/doxygen/Doxyfile + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen." VERBATIM + ) + if(LATEX_COMPILER) + message(STATUS "'${CMAKE_MAKE_PROGRAM_PRETTY_NAME} pdfmanual' will generate a manual at ${CMAKE_BINARY_DIR}/docs/GNSS-SDR_manual.pdf") + add_custom_target(pdfmanual + COMMAND ${CMAKE_MAKE_PROGRAM} + COMMAND ${CMAKE_COMMAND} -E copy refman.pdf ${CMAKE_BINARY_DIR}/docs/GNSS-SDR_manual.pdf + COMMAND ${CMAKE_MAKE_PROGRAM} clean + DEPENDS doc + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/docs/latex + COMMENT "Generating PDF manual with Doxygen." VERBATIM + ) + endif() + message(STATUS "'${CMAKE_MAKE_PROGRAM_PRETTY_NAME} doc-clean' will clean the documentation.") + add_custom_target(doc-clean + COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/docs/html + COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/docs/latex + COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/docs/GNSS-SDR_manual.pdf + COMMENT "Cleaning documentation." VERBATIM + ) +else() + message(STATUS " Doxygen has not been found in your system.") + message(STATUS " You can get nice code documentation by using it!") + message(STATUS " Get it from http://www.stack.nl/~dimitri/doxygen/index.html") + if(OS_IS_LINUX) + if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + message(STATUS " or simply by doing 'sudo yum install doxygen-latex'.") + else() + message(STATUS " or simply by doing 'sudo apt-get install doxygen-latex'.") + endif() + endif() + if(OS_IS_MACOSX) + message(STATUS " or simply by doing 'sudo port install doxygen +latex'.") + endif() +endif() @@ -1280,28 +1335,28 @@ endif(DOXYGEN_FOUND) # OpenCL (OPTIONAL) ############################################################################### if(ENABLE_OPENCL) - find_package(OpenCL) + find_package(OPENCL) if($ENV{DISABLE_OPENCL}) set(DISABLE_OPENCL TRUE) - endif($ENV{DISABLE_OPENCL}) + endif() if(DISABLE_OPENCL) set(OPENCL_FOUND FALSE) - else(DISABLE_OPENCL) + else() if(OPENCL_FOUND) message(STATUS "OpenCL has been found and will be used by some processing blocks") message(STATUS "You can disable OpenCL use by doing 'cmake -DENABLE_OPENCL=OFF ../' ") - endif(OPENCL_FOUND) - endif(DISABLE_OPENCL) + endif() + endif() if(ENABLE_GENERIC_ARCH) set(OPENCL_FOUND FALSE) message(STATUS "ENABLE_GENERIC_ARCH is set to ON so the use of OpenCL has been disabled.") - endif(ENABLE_GENERIC_ARCH) + endif() if(NOT OPENCL_FOUND) message(STATUS "Processing blocks using OpenCL will not be built.") - endif(NOT OPENCL_FOUND) -else(ENABLE_OPENCL) + endif() +else() set(OPENCL_FOUND FALSE) -endif(ENABLE_OPENCL) +endif() @@ -1309,41 +1364,43 @@ endif(ENABLE_OPENCL) # CUDA (OPTIONAL) ############################################################################### if($ENV{CUDA_GPU_ACCEL}) - message(STATUS "CUDA_GPU_ACCEL environment variable found." ) + message(STATUS "CUDA_GPU_ACCEL environment variable found.") set(ENABLE_CUDA ON) -endif($ENV{CUDA_GPU_ACCEL}) +endif() if(ENABLE_CUDA) - FIND_PACKAGE(CUDA REQUIRED) - message(STATUS "NVIDIA CUDA GPU Acceleration will be enabled." ) - message(STATUS "You can disable it with 'cmake -DENABLE_CUDA=OFF ../'" ) -else(ENABLE_CUDA) - message(STATUS "NVIDIA CUDA GPU Acceleration will be not enabled." ) - message(STATUS "Enable it with 'cmake -DENABLE_CUDA=ON ../' to add support for GPU-based acceleration using CUDA." ) -endif(ENABLE_CUDA) + find_package(CUDA REQUIRED) + message(STATUS "NVIDIA CUDA GPU Acceleration will be enabled.") + message(STATUS "You can disable it with 'cmake -DENABLE_CUDA=OFF ../'") +else() + message(STATUS "NVIDIA CUDA GPU Acceleration will be not enabled.") + message(STATUS "Enable it with 'cmake -DENABLE_CUDA=ON ../' to add support for GPU-based acceleration using CUDA.") +endif() + + ############################################################################### # CUSTOM UDP PACKET SOURCE (OPTIONAL) ############################################################################### if(ENABLE_RAW_UDP) - message(STATUS "High-optimized custom UDP ip packet source will be enabled." ) - message(STATUS "You can disable it with 'cmake -DENABLE_RAW_UDP=OFF ../'" ) -else(ENABLE_RAW_UDP) - message(STATUS "High-optimized custom UDP ip packet source will be enabled." ) - message(STATUS "You can disable it with 'cmake -DENABLE_RAW_UDP=OFF ../'" ) -endif(ENABLE_RAW_UDP) + message(STATUS "High-optimized custom UDP ip packet source will be enabled.") + message(STATUS "You can disable it with 'cmake -DENABLE_RAW_UDP=OFF ../'") +else() + message(STATUS "High-optimized custom UDP ip packet source will be enabled.") + message(STATUS "You can disable it with 'cmake -DENABLE_RAW_UDP=OFF ../'") +endif() ############################################################################### # FPGA (OPTIONAL) ############################################################################### if(ENABLE_FPGA) - message(STATUS "FPGA Acceleration will be enabled." ) - message(STATUS "You can disable it with 'cmake -DENABLE_FPGA=OFF ../'" ) -else(ENABLE_FPGA) - message(STATUS "Fpga Acceleration will be not enabled." ) - message(STATUS "Enable it with 'cmake -DENABLE_FPGA=ON ../' to add support for GPU-based acceleration using the FPGA." ) -endif(ENABLE_FPGA) + message(STATUS "FPGA Acceleration will be enabled.") + message(STATUS "You can disable it with 'cmake -DENABLE_FPGA=OFF ../'") +else() + message(STATUS "Fpga Acceleration will be not enabled.") + message(STATUS "Enable it with 'cmake -DENABLE_FPGA=ON ../' to add support for GPU-based acceleration using the FPGA.") +endif() @@ -1351,77 +1408,77 @@ endif(ENABLE_FPGA) # Setup of optional drivers ################################################################################ if($ENV{GN3S_DRIVER}) - message(STATUS "GN3S_DRIVER environment variable found." ) + message(STATUS "GN3S_DRIVER environment variable found.") set(ENABLE_GN3S ON) -endif($ENV{GN3S_DRIVER}) +endif() if(GN3S_DRIVER) set(ENABLE_GN3S ON) -endif(GN3S_DRIVER) +endif() if(ENABLE_GN3S) - message(STATUS "The GN3S driver will be compiled.") - message(STATUS "You can disable it with 'cmake -DENABLE_GN3S=OFF ../'" ) -else(ENABLE_GN3S) - 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(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() if($ENV{RAW_ARRAY_DRIVER}) - message(STATUS "RAW_ARRAY_DRIVER environment variable found." ) + message(STATUS "RAW_ARRAY_DRIVER environment variable found.") set(ENABLE_ARRAY ON) -endif($ENV{RAW_ARRAY_DRIVER}) +endif() if(RAW_ARRAY_DRIVER) set(ENABLE_ARRAY ON) -endif(RAW_ARRAY_DRIVER) +endif() if(ENABLE_ARRAY) - message(STATUS "CTTC's Antenna Array front-end driver will be compiled." ) - message(STATUS "You can disable it with 'cmake -DENABLE_ARRAY=OFF ../'" ) + message(STATUS "CTTC's Antenna Array front-end driver will be compiled.") + message(STATUS "You can disable it with 'cmake -DENABLE_ARRAY=OFF ../'") # copy firmware to install folder # Build project gr-dbfcttc -else(ENABLE_ARRAY) - message(STATUS "The (optional) CTTC's Antenna Array front-end driver is not enabled." ) - message(STATUS "Enable it with 'cmake -DENABLE_ARRAY=ON ../' to add support for the CTTC experimental array front-end." ) -endif(ENABLE_ARRAY) +else() + message(STATUS "The (optional) CTTC's Antenna Array front-end driver is not enabled.") + message(STATUS "Enable it with 'cmake -DENABLE_ARRAY=ON ../' to add support for the CTTC experimental array front-end.") +endif() if($ENV{RTLSDR_DRIVER}) - message(STATUS "RTLSDR_DRIVER environment variable found." ) + message(STATUS "RTLSDR_DRIVER environment variable found.") set(ENABLE_OSMOSDR ON) -endif($ENV{RTLSDR_DRIVER}) +endif() if(ENABLE_OSMOSDR) - find_package(GrOsmoSDR) + find_package(GROSMOSDR) if(GROSMOSDR_FOUND) - message(STATUS "The driver for OsmoSDR and other front-ends (HackRF, bladeRF, Realtek's RTL2832U-based dongles, etc.) will be compiled." ) - message(STATUS "You can disable it with 'cmake -DENABLE_OSMOSDR=OFF ../'" ) - else(GROSMOSDR_FOUND) + message(STATUS "The driver for OsmoSDR and other front-ends (HackRF, bladeRF, Realtek's RTL2832U-based dongles, etc.) will be compiled.") + message(STATUS "You can disable it with 'cmake -DENABLE_OSMOSDR=OFF ../'") + else() if(ENABLE_PACKAGING) - message(WARNING "gr-osmosdr has not been found. Source blocks depending on it will NOT be built.") - else(ENABLE_PACKAGING) - message(FATAL_ERROR "gr-osmosdr required to build gnss-sdr with the optional OSMOSDR driver") - endif(ENABLE_PACKAGING) - endif(GROSMOSDR_FOUND) -else(ENABLE_OSMOSDR) - message(STATUS "The (optional) driver for OsmoSDR and related front-ends is not enabled." ) - message(STATUS "Enable it with 'cmake -DENABLE_OSMOSDR=ON ../' to add support for OsmoSDR and other front-ends (HackRF, bladeRF, Realtek's RTL2832U-based USB dongles, etc.)" ) -endif(ENABLE_OSMOSDR) + message(WARNING "gr-osmosdr has not been found. Source blocks depending on it will NOT be built.") + else() + message(FATAL_ERROR "gr-osmosdr required to build gnss-sdr with the optional OSMOSDR driver") + endif() + endif() +else() + message(STATUS "The (optional) driver for OsmoSDR and related front-ends is not enabled.") + message(STATUS "Enable it with 'cmake -DENABLE_OSMOSDR=ON ../' to add support for OsmoSDR and other front-ends (HackRF, bladeRF, Realtek's RTL2832U-based USB dongles, etc.)") +endif() if($ENV{FLEXIBAND_DRIVER}) - message(STATUS "FLEXIBAND_DRIVER environment variable found." ) + message(STATUS "FLEXIBAND_DRIVER environment variable found.") set(ENABLE_FLEXIBAND ON) -endif($ENV{FLEXIBAND_DRIVER}) +endif() if(FLEXIBAND_DRIVER) set(ENABLE_FLEXIBAND ON) -endif(FLEXIBAND_DRIVER) +endif() if(ENABLE_FLEXIBAND) - message(STATUS "The Teleorbit Flexiband front-end source will be compiled." ) - message(STATUS "You can disable it with 'cmake -DENABLE_FLEXIBAND=OFF ../'" ) -else(ENABLE_FLEXIBAND) - message(STATUS "The (optional) Teleorbit Flexiband front-end driver adapter is not enabled." ) - message(STATUS "Enable it with 'cmake -DENABLE_FLEXIBAND=ON ../' to add support for the Teleorbit Flexiband front-end." ) -endif(ENABLE_FLEXIBAND) + message(STATUS "The Teleorbit Flexiband front-end source will be compiled.") + message(STATUS "You can disable it with 'cmake -DENABLE_FLEXIBAND=OFF ../'") +else() + message(STATUS "The (optional) Teleorbit Flexiband front-end driver adapter is not enabled.") + message(STATUS "Enable it with 'cmake -DENABLE_FLEXIBAND=ON ../' to add support for the Teleorbit Flexiband front-end.") +endif() @@ -1429,28 +1486,28 @@ endif(ENABLE_FLEXIBAND) # GPerftools - https://github.com/gperftools/gperftools (OPTIONAL) ################################################################################ if(ENABLE_GPERFTOOLS) - find_package(Gperftools) - if ( NOT GPERFTOOLS_FOUND ) + find_package(GPERFTOOLS) + if(NOT GPERFTOOLS_FOUND) message(STATUS "Although ENABLE_GPERFTOOLS has been set to ON, GPerftools has not been found.") message(STATUS "Binaries will be compiled without 'tcmalloc' and 'profiler' libraries.") message(STATUS "You can install GPerftools from https://github.com/gperftools/gperftools") - else( NOT GPERFTOOLS_FOUND ) - message(STATUS "GPerftools libraries found." ) + else() + message(STATUS "GPerftools libraries found.") message(STATUS "Binaries will be compiled with 'tcmalloc' and 'profiler' libraries.") - endif( NOT GPERFTOOLS_FOUND ) -endif(ENABLE_GPERFTOOLS) + endif() +endif() if(ENABLE_GPERFTOOLS) # Set GPerftools related flags if it is available # See https://github.com/gperftools/gperftools/blob/master/README if(GPERFTOOLS_FOUND) - if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) + if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free") - endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) + endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -fno-builtin") - endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - endif(GPERFTOOLS_FOUND) -endif(ENABLE_GPERFTOOLS) + endif() + endif() +endif() @@ -1458,12 +1515,10 @@ endif(ENABLE_GPERFTOOLS) # GNU gprof (OPTIONAL) - https://sourceware.org/binutils/docs/gprof/ ######################################################################## if(ENABLE_GPROF) - #if(CMAKE_COMPILER_IS_GNUCXX) - set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -pg") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg") - #endif(CMAKE_COMPILER_IS_GNUCXX) -endif(ENABLE_GPROF) + set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -pg") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg") +endif() ######################################################################## @@ -1472,18 +1527,18 @@ endif(ENABLE_GPROF) # Support of C++17 is still not possible due to pm_remez.h (solved in GNU Radio 3.8) # Enable C++14 support in GCC >= 6.1.1 # Fallback to C++11 when using GCC < 6.1.1 -if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) +if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.1.1") set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++11") - else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.1.1") + else() # if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0.0") set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++14") # else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0.0") # set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++17") # endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0.0") - endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.1.1") + endif() set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -Wall -Wextra") #Add warning flags: For "-Wall" see https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html -endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) +endif() # Support of C++17 is still not possible due to pm_remez.h (solved in GNU Radio 3.8) # Enable C++14 support in Clang >= 3.5.0 or AppleClang >= 600 @@ -1493,69 +1548,68 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # See https://trac.macports.org/wiki/XcodeVersionInfo for Apple Clang version equivalences if(CLANG_VERSION VERSION_LESS "600") set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++11") - else(CLANG_VERSION VERSION_LESS "600") + else() # if(CLANG_VERSION VERSION_LESS "900") - set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++14") + set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++14") # else(CLANG_VERSION VERSION_LESS "900") - # set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++17") + # set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++17") # endif(CLANG_VERSION VERSION_LESS "900") - endif(CLANG_VERSION VERSION_LESS "600") - else(OS_IS_MACOSX) + endif() + else() if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.5.0") set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++11") - else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.5.0") + else() # if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0.0") - set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++14") + set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++14") # else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0.0") - # set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++17") + # set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++17") # endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0.0") - endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.5.0") - endif(OS_IS_MACOSX) + endif() + endif() if(OS_IS_MACOSX) set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -stdlib=libc++") - endif(OS_IS_MACOSX) -endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + endif() +endif() -if(NOT (CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) +if(NOT ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) AND NOT WIN32) if(NOT (CMAKE_VERSION VERSION_LESS "3.1")) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 14) - endif(NOT (CMAKE_VERSION VERSION_LESS "3.1")) -endif(NOT (CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) + endif() +endif() # Processor-architecture related flags # See https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html -if (NOT ARCH_COMPILER_FLAGS) - if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) - if(OS_IS_MACOSX) - set(ARCH_COMPILER_FLAGS "-march=corei7 -mfpmath=sse") - else(OS_IS_MACOSX) - if(NOT ${ENABLE_GENERIC_ARCH}) - if(IS_ARM) # ARM-specific options (https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html) - if(NOT CMAKE_CROSSCOMPILING) - if(ARM_VERSION STREQUAL "arm") - # Unknown arm version - try our best to detect - set(ARCH_COMPILER_FLAGS "-mcpu=native") - else(ARM_VERSION STREQUAL "arm") - set(ARCH_COMPILER_FLAGS "-march=${ARM_VERSION}") - endif(ARM_VERSION STREQUAL "arm") - endif(NOT CMAKE_CROSSCOMPILING) - else(IS_ARM) - set(ARCH_COMPILER_FLAGS "-march=native -mfpmath=sse") - endif(IS_ARM) - endif(NOT ${ENABLE_GENERIC_ARCH}) - endif(OS_IS_MACOSX) - endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) -endif (NOT ARCH_COMPILER_FLAGS) +if(NOT ARCH_COMPILER_FLAGS) + if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) + if(OS_IS_MACOSX) + set(ARCH_COMPILER_FLAGS "-march=corei7 -mfpmath=sse") + else() + if(NOT ${ENABLE_GENERIC_ARCH}) + if(IS_ARM) # ARM-specific options (https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html) + if(NOT CMAKE_CROSSCOMPILING) + if(ARM_VERSION STREQUAL "arm") + # Unknown arm version - try our best to detect + set(ARCH_COMPILER_FLAGS "-mcpu=native") + else() + set(ARCH_COMPILER_FLAGS "-march=${ARM_VERSION}") + endif() + endif() + else() + set(ARCH_COMPILER_FLAGS "-march=native -mfpmath=sse") + endif() + endif() + endif() + endif() +endif() set(MY_CXX_FLAGS "${MY_CXX_FLAGS} ${ARCH_COMPILER_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_CXX_FLAGS}") -if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) +if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) # https://gcc.gnu.org/wiki/Visibility add_definitions(-fvisibility=hidden) -endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) +endif() diff --git a/MANIFEST.md b/MANIFEST.md index d98411e9f..ea64ec678 100644 --- a/MANIFEST.md +++ b/MANIFEST.md @@ -12,11 +12,17 @@ author: - et altri (see AUTHORS file for a list of contributors) copyright_owner: - The Authors -dependencies: gnuradio (>= 3.7.3), armadillo, gflags, glog, gnutls, matio +dependencies: + - gnuradio (>= 3.7.3) + - armadillo + - gflags + - glog + - gnutls + - matio license: GPLv3+ repo: https://github.com/gnss-sdr/gnss-sdr website: https://gnss-sdr.org -icon: https://raw.githubusercontent.com/gnss-sdr/gnss-sdr/master/docs/doxygen/images/gnss-sdr_logo.png +icon: https://gnss-sdr.org/assets/images/logo400x400.jpg --- Global Navigation Satellite Systems receiver defined by software. It performs all the signal processing from raw signal samples up to the computation of the Position-Velocity-Time solution, diff --git a/README.md b/README.md index 9fe634565..184f67102 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,11 @@ $ sudo apt-get install build-essential cmake git libboost-dev libboost-date-time libboost-system-dev libboost-filesystem-dev libboost-thread-dev libboost-chrono-dev \ libboost-serialization-dev liblog4cpp5-dev libuhd-dev gnuradio-dev gr-osmosdr \ libblas-dev liblapack-dev libarmadillo-dev libgflags-dev libgoogle-glog-dev \ - libgnutls-openssl-dev libpcap-dev python-mako python-six libmatio-dev googletest + libgnutls-openssl-dev libpcap-dev python-mako python-six libmatio-dev libpugixml-dev \ + libgtest-dev ~~~~~~ -Please note that `googletest` was named `libgtest-dev` in distributions older than Debian 9 "stretch" and Ubuntu 17.04 "zesty". +Please note that the required files from `libgtest-dev` were moved to `googletest` in Debian 9 "stretch" and Ubuntu 18.04 "bionic", and moved back again to `libgtest-dev` in Debian 10 "buster" and Ubuntu 18.10 "cosmic". **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 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 the `libmatio-dev` package and install `libtool`, `automake` and `libhdf5-dev` instead. A recent version of the library will be downloaded and built automatically if CMake does not find it installed. @@ -85,7 +86,7 @@ $ sudo yum install make automake gcc gcc-c++ kernel-devel cmake git boost-devel boost-date-time boost-system boost-filesystem boost-thread boost-chrono \ boost-serialization log4cpp-devel gnuradio-devel gr-osmosdr-devel \ blas-devel lapack-devel matio-devel armadillo-devel gflags-devel \ - glog-devel openssl-devel libpcap-devel python-mako python-six + glog-devel openssl-devel libpcap-devel python-mako python-six pugixml-devel ~~~~~~ Once you have installed these packages, you can jump directly to [download the source code and build GNSS-SDR](#download-and-build-linux). @@ -102,7 +103,7 @@ $ sudo yum install make automake gcc gcc-c++ kernel-devel libtool \ hdf5-devel cmake git boost-devel boost-date-time boost-system \ boost-filesystem boost-thread boost-chrono boost-serialization \ log4cpp-devel gnuradio-devel gr-osmosdr-devel blas-devel lapack-devel \ - armadillo-devel openssl-devel libpcap-devel python-mako python-six + armadillo-devel openssl-devel libpcap-devel python-mako python-six pugixml-devel ~~~~~~ Once you have installed these packages, you can jump directly to [download the source code and build GNSS-SDR](#download-and-build-linux). @@ -113,7 +114,7 @@ If you are using Arch Linux (with base-devel group installed): ~~~~~~ $ pacman -S cmake git boost boost-libs log4cpp libvolk gnuradio gnuradio-osmosdr \ - blas lapack gflags google-glog openssl python2-mako python2-six \ + blas lapack gflags google-glog openssl pugixml python-mako python-six \ libmatio libpcap gtest ~~~~~~ @@ -186,9 +187,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 https://sourceforge.net/projects/arma/files/armadillo-8.500.1.tar.xz -$ tar xvfz armadillo-8.500.1.tar.xz -$ cd armadillo-8.500.1 +$ wget https://sourceforge.net/projects/arma/files/armadillo-9.100.5.tar.xz +$ tar xvfz armadillo-9.100.5.tar.xz +$ cd armadillo-9.100.5 $ cmake . $ make $ sudo make install @@ -201,9 +202,9 @@ The full stop separated from ```cmake``` by a space is important. [CMake](https: #### Install [Gflags](https://github.com/gflags/gflags "Gflags' Homepage"), a commandline flags processing module for C++: ~~~~~~ -$ wget https://github.com/gflags/gflags/archive/v2.2.1.tar.gz -$ tar xvfz v2.2.1.tar.gz -$ cd gflags-2.2.1 +$ wget https://github.com/gflags/gflags/archive/v2.2.2.tar.gz +$ tar xvfz v2.2.2.tar.gz +$ cd gflags-2.2.2 $ cmake -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -DBUILD_gflags_nothreads_LIB=OFF . $ make $ sudo make install @@ -229,20 +230,20 @@ $ sudo ldconfig #### Build the [Google C++ Testing Framework](https://github.com/google/googletest "Googletest Homepage"), also known as Google Test: ~~~~~~ -$ wget https://github.com/google/googletest/archive/release-1.8.0.zip -$ unzip release-1.8.0.zip -$ cd googletest-release-1.8.0 -$ cmake -DBUILD_GTEST=ON -DBUILD_GMOCK=OFF . +$ wget https://github.com/google/googletest/archive/release-1.8.1.zip +$ unzip release-1.8.1.zip +$ cd googletest-release-1.8.1 +$ cmake -DINSTALL_GTEST=OFF -DBUILD_GMOCK=OFF . $ make ~~~~~~ Please **DO NOT install** Google Test (do *not* type ```sudo make install```). Every user needs to compile his tests using the same compiler flags used to compile the installed Google Test libraries; otherwise he may run into undefined behaviors (i.e. the tests can behave strangely and may even crash for no obvious reasons). The reason is that C++ has this thing called the One-Definition Rule: if two C++ source files contain different definitions of the same class/function/variable, and you link them together, you violate the rule. The linker may or may not catch the error (in many cases it is not required by the C++ standard to catch the violation). If it does not, you get strange run-time behaviors that are unexpected and hard to debug. If you compile Google Test and your test code using different compiler flags, they may see different definitions of the same class/function/variable (e.g. due to the use of ```#if``` in Google Test). Therefore, for your sanity, we recommend to avoid installing pre-compiled Google Test libraries. Instead, each project should compile Google Test itself such that it can be sure that the same flags are used for both Google Test and the tests. The building system of GNSS-SDR does the compilation and linking of googletest to its own tests; it is only required that you tell the system where the googletest folder that you downloaded resides. Just add to your ```$HOME/.bashrc``` file the following line: ~~~~~~ -export GTEST_DIR=/home/username/googletest-release-1.8.0/googletest +export GTEST_DIR=/home/username/googletest-release-1.8.1/googletest ~~~~~~ -changing `/home/username/googletest-release-1.8.0/googletest` by the actual directory where you built googletest. +changing `/home/username/googletest-release-1.8.1/googletest` by the actual directory where you built googletest. @@ -516,10 +517,7 @@ More details can be found in our tutorial about [GNSS-SDR configuration options macOS and Mac OS X --------- - -### macOS 10.13 (High Sierra) and 10.12 (Sierra), Mac OS X 10.11 (El Capitan), 10.10 (Yosemite) and 10.9 (Mavericks). - -If you still have not installed [Xcode](https://developer.apple.com/xcode/ "Xcode"), do it now from the App Store (it's free). You will also need the Xcode Command Line Tools. Launch the Terminal, found in /Applications/Utilities/, and type: +GNSS-SDR can be built on MacOS or Mac OS X, starting from 10.9 (Mavericks) and including 10.14 (Mojave). If you still have not installed [Xcode](https://developer.apple.com/xcode/ "Xcode"), do it now from the App Store (it's free). You will also need the Xcode Command Line Tools. Launch the Terminal, found in /Applications/Utilities/, and type: ~~~~~~ $ xcode-select --install @@ -550,6 +548,7 @@ $ sudo port install google-glog +gflags $ sudo port install py27-mako $ sudo port install py27-six $ sudo port install matio +$ sudo port install pugixml ~~~~~~ You also might need to activate a Python installation. The list of installed versions can be retrieved with: @@ -558,7 +557,7 @@ You also might need to activate a Python installation. The list of installed ver $ port select list python ~~~~~~ -and you can activate a certain version (2.7 works well) by typing: +and you can activate a certain version by typing: ~~~~~~ $ sudo port select --set python python27 @@ -589,6 +588,7 @@ $ brew install armadillo $ brew install glog gflags gnutls $ brew install gnuradio $ brew install libmatio +$ brew install pugixml $ pip install mako $ pip install six ~~~~~~ diff --git a/cmake/Modules/CMakeParseArgumentsCopy.cmake b/cmake/Modules/CMakeParseArgumentsCopy.cmake deleted file mode 100644 index 7ce4c49ae..000000000 --- a/cmake/Modules/CMakeParseArgumentsCopy.cmake +++ /dev/null @@ -1,138 +0,0 @@ -# CMAKE_PARSE_ARGUMENTS( args...) -# -# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for -# parsing the arguments given to that macro or function. -# It processes the arguments and defines a set of variables which hold the -# values of the respective options. -# -# The argument contains all options for the respective macro, -# i.e. keywords which can be used when calling the macro without any value -# following, like e.g. the OPTIONAL keyword of the install() command. -# -# The argument contains all keywords for this macro -# which are followed by one value, like e.g. DESTINATION keyword of the -# install() command. -# -# The argument contains all keywords for this macro -# which can be followed by more than one value, like e.g. the TARGETS or -# FILES keywords of the install() command. -# -# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the -# keywords listed in , and -# a variable composed of the given -# followed by "_" and the name of the respective keyword. -# These variables will then hold the respective value from the argument list. -# For the keywords this will be TRUE or FALSE. -# -# All remaining arguments are collected in a variable -# _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether -# your macro was called with unrecognized parameters. -# -# As an example here a my_install() macro, which takes similar arguments as the -# real install() command: -# -# function(MY_INSTALL) -# set(options OPTIONAL FAST) -# set(oneValueArgs DESTINATION RENAME) -# set(multiValueArgs TARGETS CONFIGURATIONS) -# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) -# ... -# -# Assume my_install() has been called like this: -# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) -# -# After the cmake_parse_arguments() call the macro will have set the following -# variables: -# MY_INSTALL_OPTIONAL = TRUE -# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() -# MY_INSTALL_DESTINATION = "bin" -# MY_INSTALL_RENAME = "" (was not used) -# MY_INSTALL_TARGETS = "foo;bar" -# MY_INSTALL_CONFIGURATIONS = "" (was not used) -# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" -# -# You can the continue and process these variables. -# -# Keywords terminate lists of values, e.g. if directly after a one_value_keyword -# another recognized keyword follows, this is interpreted as the beginning of -# the new option. -# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in -# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would -# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. - -#============================================================================= -# Copyright 2010 Alexander Neundorf -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - - -if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) - return() -endif() -set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) - - -function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) - # first set all result variables to empty/FALSE - foreach(arg_name ${_singleArgNames} ${_multiArgNames}) - set(${prefix}_${arg_name}) - endforeach(arg_name) - - foreach(option ${_optionNames}) - set(${prefix}_${option} FALSE) - endforeach(option) - - set(${prefix}_UNPARSED_ARGUMENTS) - - set(insideValues FALSE) - set(currentArgName) - - # now iterate over all arguments and fill the result variables - foreach(currentArg ${ARGN}) - list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword - list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword - list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword - - if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) - if(insideValues) - if("${insideValues}" STREQUAL "SINGLE") - set(${prefix}_${currentArgName} ${currentArg}) - set(insideValues FALSE) - elseif("${insideValues}" STREQUAL "MULTI") - list(APPEND ${prefix}_${currentArgName} ${currentArg}) - endif() - else(insideValues) - list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) - endif(insideValues) - else() - if(NOT ${optionIndex} EQUAL -1) - set(${prefix}_${currentArg} TRUE) - set(insideValues FALSE) - elseif(NOT ${singleArgIndex} EQUAL -1) - set(currentArgName ${currentArg}) - set(${prefix}_${currentArgName}) - set(insideValues "SINGLE") - elseif(NOT ${multiArgIndex} EQUAL -1) - set(currentArgName ${currentArg}) - set(${prefix}_${currentArgName}) - set(insideValues "MULTI") - endif() - endif() - - endforeach(currentArg) - - # propagate the result variables to the caller: - foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) - set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) - endforeach(arg_name) - set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) - -endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs) diff --git a/cmake/Modules/FindGFLAGS.cmake b/cmake/Modules/FindGFLAGS.cmake new file mode 100644 index 000000000..76a832ca5 --- /dev/null +++ b/cmake/Modules/FindGFLAGS.cmake @@ -0,0 +1,102 @@ +# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors) +# +# This file is part of GNSS-SDR. +# +# GNSS-SDR is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GNSS-SDR is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNSS-SDR. If not, see . + +# - Try to find GFlags +# +# The following variables are optionally searched for defaults +# GFlags_ROOT_DIR: Base directory where all GFlags components are found +# +# The following are set after configuration is done: +# GFlags_FOUND +# GFlags_INCLUDE_DIRS +# GFlags_LIBS +# GFlags_LIBRARY_DIRS + +if(APPLE) + find_path(GFlags_ROOT_DIR + libgflags.dylib + PATHS + /opt/local/lib + /usr/local/lib + ) +else() + find_path(GFlags_ROOT_DIR + libgflags.so + HINTS + /usr/local/lib + /usr/lib/x86_64-linux-gnu + /usr/lib/i386-linux-gnu + /usr/lib/arm-linux-gnueabihf + /usr/lib/arm-linux-gnueabi + /usr/lib/aarch64-linux-gnu + /usr/lib/mipsel-linux-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/powerpc-linux-gnu + /usr/lib/powerpc64-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/powerpc-linux-gnuspe + /usr/lib/hppa-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/lib/i386-gnu + /usr/lib/hppa-linux-gnu + /usr/lib/x86_64-kfreebsd-gnu + /usr/lib/i386-kfreebsd-gnu + /usr/lib/m68k-linux-gnu + /usr/lib/sh4-linux-gnu + /usr/lib/sparc64-linux-gnu + /usr/lib/x86_64-linux-gnux32 + /usr/lib/alpha-linux-gnu + /usr/lib64 + /usr/lib + ) +endif() + +if(GFlags_ROOT_DIR) + # We are testing only a couple of files in the include directories + find_path(GFlags_INCLUDE_DIRS + gflags/gflags.h + HINTS + /opt/local/include + /usr/local/include + /usr/include + ${GFlags_ROOT_DIR}/src + ) + + # Find the libraries + set(GFlags_LIBRARY_DIRS ${GFlags_ROOT_DIR}) + + find_library(GFlags_lib gflags ${GFlags_LIBRARY_DIRS}) + if(EXISTS ${GFlags_INCLUDE_DIRS}/gflags/gflags_gflags.h) + set(GFLAGS_GREATER_20 TRUE) + else() + set(GFLAGS_GREATER_20 FALSE) + endif() + # set up include and link directory + include_directories(${GFlags_INCLUDE_DIRS}) + link_directories(${GFlags_LIBRARY_DIRS}) + message(STATUS "gflags library found at ${GFlags_lib}") + set(GFlags_LIBS ${GFlags_lib}) + set(GFlags_FOUND true) + mark_as_advanced(GFlags_INCLUDE_DIRS) +else() + message(STATUS "Cannot find gflags") + set(GFlags_FOUND false) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GFLAGS DEFAULT_MSG GFlags_LIBS GFlags_INCLUDE_DIRS) diff --git a/cmake/Modules/FindGFORTRAN.cmake b/cmake/Modules/FindGFORTRAN.cmake index eec7a4265..f3299fefb 100644 --- a/cmake/Modules/FindGFORTRAN.cmake +++ b/cmake/Modules/FindGFORTRAN.cmake @@ -15,126 +15,134 @@ # You should have received a copy of the GNU General Public License # along with GNSS-SDR. If not, see . - find_library(GFORTRAN NAMES gfortran - PATHS /usr/lib - /usr/lib64 - /usr/local/lib - /usr/local/lib/i386 - /usr/lib/gcc/x86_64-linux-gnu - /usr/lib/gcc/i686-linux-gnu - /usr/lib/gcc/i386-linux-gnu - /usr/lib/gcc/x86_64-linux-gnu/4.6 # Ubuntu 12.04 - /usr/lib/gcc/i686-linux-gnu/4.6 - /usr/lib/gcc/x86_64-linux-gnu/4.7 - /usr/lib/gcc/i686-linux-gnu/4.7 - /usr/lib/gcc/x86_64-linux-gnu/4.8 - /usr/lib/gcc/i686-linux-gnu/4.8 - /usr/lib/gcc/x86_64-linux-gnu/4.9 - /usr/lib/gcc/i686-linux-gnu/4.9 - /usr/lib/gcc/x86_64-redhat-linux/4.7.2 # Fedora 18 - /usr/lib/gcc/i686-redhat-linux/4.7.2 - /usr/lib/gcc/x86_64-redhat-linux/4.8.1 # Fedora 19 - /usr/lib/gcc/x86_64-redhat-linux/4.8.3 # Fedora 20 - /usr/lib/gcc/x86_64-redhat-linux/4.9.1 # Fedora 21 - /usr/lib/gcc/i686-redhat-linux/4.8.1 - /usr/lib/gcc/i686-redhat-linux/4.8.3 - /usr/lib/gcc/i686-redhat-linux/4.9.1 - /usr/lib/gcc/x86_64-redhat-linux/4.4.4 # CentOS 6 - /usr/lib/gcc/i686-redhat-linux/4.4.4 - /usr/lib/gcc/x86_64-redhat-linux/4.8.2 - /usr/lib/gcc/i686-redhat-linux/4.8.2 - /usr/lib/gcc/x86_64-redhat-linux/7 - /usr/lib/gcc/i686-redhat-linux/7 - /usr/lib/gcc/armv7hl-redhat-linux-gnueabi/7 - /usr/lib/gcc/aarch64-redhat-linux/7 - /usr/lib/gcc/i586-suse-linux/4.8 # OpenSUSE 13.1 - /usr/lib/gcc/i586-suse-linux/4.9 - /usr/lib/gcc/x86_64-suse-linux/4.8 - /usr/lib/gcc/x86_64-suse-linux/4.9 - /usr/lib/gcc/i486-linux-gnu # Debian 7 - /usr/lib/gcc/i486-linux-gnu/4.4 - /usr/lib/gcc/i486-linux-gnu/4.6 - /usr/lib/gcc/i486-linux-gnu/4.7 - /usr/lib/gcc/i486-linux-gnu/4.8 - /usr/lib/gcc/i486-linux-gnu/4.9 - /usr/lib/gcc/i586-linux-gnu/4.9 - /usr/lib/gcc/arm-linux-gnueabihf/4.4 # Debian armhf - /usr/lib/gcc/arm-linux-gnueabihf/4.5 - /usr/lib/gcc/arm-linux-gnueabihf/4.6 - /usr/lib/gcc/arm-linux-gnueabihf/4.7 - /usr/lib/gcc/arm-linux-gnueabihf/4.8 - /usr/lib/gcc/arm-linux-gnueabihf/4.9 - /usr/lib/gcc/aarch64-linux-gnu/4.9 # Debian arm64 - /usr/lib/gcc/arm-linux-gnueabi/4.7 # Debian armel - /usr/lib/gcc/arm-linux-gnueabi/4.9 - /usr/lib/gcc/x86_64-linux-gnu/5 - /usr/lib/gcc/i686-linux-gnu/5 - /usr/lib/gcc/arm-linux-gnueabi/5 - /usr/lib/gcc/arm-linux-gnueabihf/5 - /usr/lib/gcc/aarch64-linux-gnu/5 - /usr/lib/gcc/x86_64-linux-gnu/6 # Ubuntu 16.10 - /usr/lib/gcc/alpha-linux-gnu/6 - /usr/lib/gcc/aarch64-linux-gnu/6 - /usr/lib/gcc/arm-linux-gnueabi/6 - /usr/lib/gcc/arm-linux-gnueabihf/6 - /usr/lib/gcc/hppa-linux-gnu/6 - /usr/lib/gcc/i686-gnu/6 - /usr/lib/gcc/i686-linux-gnu/6 - /usr/lib/gcc/x86_64-kfreebsd-gnu/6 - /usr/lib/gcc/i686-kfreebsd-gnu/6 - /usr/lib/gcc/m68k-linux-gnu/6 - /usr/lib/gcc/mips-linux-gnu/6 - /usr/lib/gcc/mips64el-linux-gnuabi64/6 - /usr/lib/gcc/mipsel-linux-gnu/6 - /usr/lib/gcc/powerpc-linux-gnu/6 - /usr/lib/gcc/powerpc-linux-gnuspe/6 - /usr/lib/gcc/powerpc64-linux-gnu/6 - /usr/lib/gcc/powerpc64le-linux-gnu/6 - /usr/lib/gcc/s390x-linux-gnu/6 - /usr/lib/gcc/sparc64-linux-gnu/6 - /usr/lib/gcc/x86_64-linux-gnux32/6 - /usr/lib/gcc/sh4-linux-gnu/6 - /usr/lib/gcc/x86_64-linux-gnu/7 # Debian 9 Buster - /usr/lib/gcc/alpha-linux-gnu/7 - /usr/lib/gcc/aarch64-linux-gnu/7 - /usr/lib/gcc/arm-linux-gnueabi/7 - /usr/lib/gcc/arm-linux-gnueabihf/7 - /usr/lib/gcc/hppa-linux-gnu/7 - /usr/lib/gcc/i686-gnu/7 - /usr/lib/gcc/i686-linux-gnu/7 - /usr/lib/gcc/x86_64-kfreebsd-gnu/7 - /usr/lib/gcc/i686-kfreebsd-gnu/7 - /usr/lib/gcc/m68k-linux-gnu/7 - /usr/lib/gcc/mips-linux-gnu/7 - /usr/lib/gcc/mips64el-linux-gnuabi64/7 - /usr/lib/gcc/mipsel-linux-gnu/7 - /usr/lib/gcc/powerpc-linux-gnu/7 - /usr/lib/gcc/powerpc-linux-gnuspe/7 - /usr/lib/gcc/powerpc64-linux-gnu/7 - /usr/lib/gcc/powerpc64le-linux-gnu/7 - /usr/lib/gcc/s390x-linux-gnu/7 - /usr/lib/gcc/sparc64-linux-gnu/7 - /usr/lib/gcc/x86_64-linux-gnux32/7 - /usr/lib/gcc/sh4-linux-gnu/7 - /usr/lib/x86_64-linux-gnu # libgfortran4 - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/aarch64-linux-gnu - /usr/lib/i386-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - ) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(GFORTRAN DEFAULT_MSG GFORTRAN) \ No newline at end of file +find_library(GFORTRAN NAMES gfortran + PATHS /usr/lib + /usr/lib64 + /usr/local/lib + /usr/local/lib/i386 + /usr/lib/gcc/x86_64-linux-gnu + /usr/lib/gcc/i686-linux-gnu + /usr/lib/gcc/i386-linux-gnu + /usr/lib/gcc/x86_64-linux-gnu/4.6 # Ubuntu 12.04 + /usr/lib/gcc/i686-linux-gnu/4.6 + /usr/lib/gcc/x86_64-linux-gnu/4.7 + /usr/lib/gcc/i686-linux-gnu/4.7 + /usr/lib/gcc/x86_64-linux-gnu/4.8 + /usr/lib/gcc/i686-linux-gnu/4.8 + /usr/lib/gcc/x86_64-linux-gnu/4.9 + /usr/lib/gcc/i686-linux-gnu/4.9 + /usr/lib/gcc/x86_64-redhat-linux/4.7.2 # Fedora 18 + /usr/lib/gcc/i686-redhat-linux/4.7.2 + /usr/lib/gcc/x86_64-redhat-linux/4.8.1 # Fedora 19 + /usr/lib/gcc/x86_64-redhat-linux/4.8.3 # Fedora 20 + /usr/lib/gcc/x86_64-redhat-linux/4.9.1 # Fedora 21 + /usr/lib/gcc/i686-redhat-linux/4.8.1 + /usr/lib/gcc/i686-redhat-linux/4.8.3 + /usr/lib/gcc/i686-redhat-linux/4.9.1 + /usr/lib/gcc/x86_64-redhat-linux/4.4.4 # CentOS 6 + /usr/lib/gcc/i686-redhat-linux/4.4.4 + /usr/lib/gcc/x86_64-redhat-linux/4.8.2 + /usr/lib/gcc/i686-redhat-linux/4.8.2 + /usr/lib/gcc/x86_64-redhat-linux/7 + /usr/lib/gcc/i686-redhat-linux/7 + /usr/lib/gcc/armv7hl-redhat-linux-gnueabi/7 + /usr/lib/gcc/aarch64-redhat-linux/7 + /usr/lib/gcc/i586-suse-linux/4.8 # OpenSUSE 13.1 + /usr/lib/gcc/i586-suse-linux/4.9 + /usr/lib/gcc/x86_64-suse-linux/4.8 + /usr/lib/gcc/x86_64-suse-linux/4.9 + /usr/lib/gcc/i486-linux-gnu # Debian 7 + /usr/lib/gcc/i486-linux-gnu/4.4 + /usr/lib/gcc/i486-linux-gnu/4.6 + /usr/lib/gcc/i486-linux-gnu/4.7 + /usr/lib/gcc/i486-linux-gnu/4.8 + /usr/lib/gcc/i486-linux-gnu/4.9 + /usr/lib/gcc/i586-linux-gnu/4.9 + /usr/lib/gcc/arm-linux-gnueabihf/4.4 # Debian armhf + /usr/lib/gcc/arm-linux-gnueabihf/4.5 + /usr/lib/gcc/arm-linux-gnueabihf/4.6 + /usr/lib/gcc/arm-linux-gnueabihf/4.7 + /usr/lib/gcc/arm-linux-gnueabihf/4.8 + /usr/lib/gcc/arm-linux-gnueabihf/4.9 + /usr/lib/gcc/aarch64-linux-gnu/4.9 # Debian arm64 + /usr/lib/gcc/arm-linux-gnueabi/4.7 # Debian armel + /usr/lib/gcc/arm-linux-gnueabi/4.9 + /usr/lib/gcc/x86_64-linux-gnu/5 + /usr/lib/gcc/i686-linux-gnu/5 + /usr/lib/gcc/arm-linux-gnueabi/5 + /usr/lib/gcc/arm-linux-gnueabihf/5 + /usr/lib/gcc/aarch64-linux-gnu/5 + /usr/lib/gcc/x86_64-linux-gnu/6 # Ubuntu 16.10 + /usr/lib/gcc/alpha-linux-gnu/6 + /usr/lib/gcc/aarch64-linux-gnu/6 + /usr/lib/gcc/arm-linux-gnueabi/6 + /usr/lib/gcc/arm-linux-gnueabihf/6 + /usr/lib/gcc/hppa-linux-gnu/6 + /usr/lib/gcc/i686-gnu/6 + /usr/lib/gcc/i686-linux-gnu/6 + /usr/lib/gcc/x86_64-kfreebsd-gnu/6 + /usr/lib/gcc/i686-kfreebsd-gnu/6 + /usr/lib/gcc/m68k-linux-gnu/6 + /usr/lib/gcc/mips-linux-gnu/6 + /usr/lib/gcc/mips64el-linux-gnuabi64/6 + /usr/lib/gcc/mipsel-linux-gnu/6 + /usr/lib/gcc/powerpc-linux-gnu/6 + /usr/lib/gcc/powerpc-linux-gnuspe/6 + /usr/lib/gcc/powerpc64-linux-gnu/6 + /usr/lib/gcc/powerpc64le-linux-gnu/6 + /usr/lib/gcc/s390x-linux-gnu/6 + /usr/lib/gcc/sparc64-linux-gnu/6 + /usr/lib/gcc/x86_64-linux-gnux32/6 + /usr/lib/gcc/sh4-linux-gnu/6 + /usr/lib/gcc/x86_64-linux-gnu/7 # Debian 9 Buster + /usr/lib/gcc/alpha-linux-gnu/7 + /usr/lib/gcc/aarch64-linux-gnu/7 + /usr/lib/gcc/arm-linux-gnueabi/7 + /usr/lib/gcc/arm-linux-gnueabihf/7 + /usr/lib/gcc/hppa-linux-gnu/7 + /usr/lib/gcc/i686-gnu/7 + /usr/lib/gcc/i686-linux-gnu/7 + /usr/lib/gcc/x86_64-kfreebsd-gnu/7 + /usr/lib/gcc/i686-kfreebsd-gnu/7 + /usr/lib/gcc/m68k-linux-gnu/7 + /usr/lib/gcc/mips-linux-gnu/7 + /usr/lib/gcc/mips64el-linux-gnuabi64/7 + /usr/lib/gcc/mipsel-linux-gnu/7 + /usr/lib/gcc/powerpc-linux-gnu/7 + /usr/lib/gcc/powerpc-linux-gnuspe/7 + /usr/lib/gcc/powerpc64-linux-gnu/7 + /usr/lib/gcc/powerpc64le-linux-gnu/7 + /usr/lib/gcc/s390x-linux-gnu/7 + /usr/lib/gcc/sparc64-linux-gnu/7 + /usr/lib/gcc/x86_64-linux-gnux32/7 + /usr/lib/gcc/sh4-linux-gnu/7 + /usr/lib/x86_64-linux-gnu # libgfortran4 + /usr/lib/i386-linux-gnu + /usr/lib/arm-linux-gnueabi + /usr/lib/arm-linux-gnueabihf + /usr/lib/aarch64-linux-gnu + /usr/lib/i386-gnu + /usr/lib/x86_64-kfreebsd-gnu + /usr/lib/i386-kfreebsd-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/mipsel-linux-gnu + /usr/lib/powerpc-linux-gnu + /usr/lib/powerpc64-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/lib/sh4-linux-gnu + /usr/lib/sparc64-linux-gnu + /usr/lib/x86_64-linux-gnux32 + /usr/lib/alpha-linux-gnu + /usr/lib/gcc/x86_64-linux-gnu/8 # libgfortran8 + /usr/lib/gcc/aarch64-linux-gnu/8 + /usr/lib/gcc/arm-linux-gnueabihf/8 + /usr/lib/gcc/i686-linux-gnu/8 + /usr/lib/gcc/powerpc64le-linux-gnu/8 + /usr/lib/gcc/s390x-linux-gnu/8 + /usr/lib/gcc/alpha-linux-gnu/8 +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GFORTRAN DEFAULT_MSG GFORTRAN) diff --git a/cmake/Modules/FindGFlags.cmake b/cmake/Modules/FindGFlags.cmake deleted file mode 100644 index a0ca5ac79..000000000 --- a/cmake/Modules/FindGFlags.cmake +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors) -# -# This file is part of GNSS-SDR. -# -# GNSS-SDR is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# GNSS-SDR is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNSS-SDR. If not, see . - -# - Try to find GFlags -# -# The following variables are optionally searched for defaults -# GFlags_ROOT_DIR: Base directory where all GFlags components are found -# -# The following are set after configuration is done: -# GFlags_FOUND -# GFlags_INCLUDE_DIRS -# GFlags_LIBS -# GFlags_LIBRARY_DIRS - -cmake_minimum_required(VERSION 2.6) - -if(APPLE) - FIND_PATH(GFlags_ROOT_DIR - libgflags.dylib - PATHS - /opt/local/lib - /usr/local/lib - ) -else(APPLE) - FIND_PATH(GFlags_ROOT_DIR - libgflags.so - HINTS - /usr/local/lib - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib64 - /usr/lib - ) -endif(APPLE) - -IF(GFlags_ROOT_DIR) - # We are testing only a couple of files in the include directories - FIND_PATH(GFlags_INCLUDE_DIRS - gflags/gflags.h - HINTS - /opt/local/include - /usr/local/include - /usr/include - ${GFlags_ROOT_DIR}/src - ) - - # Find the libraries - SET(GFlags_LIBRARY_DIRS ${GFlags_ROOT_DIR}) - - FIND_LIBRARY(GFlags_lib gflags ${GFlags_LIBRARY_DIRS}) - if(EXISTS ${GFlags_INCLUDE_DIRS}/gflags/gflags_gflags.h) - set(GFLAGS_GREATER_20 TRUE) - else(EXISTS ${GFlags_INCLUDE_DIRS}/gflags/gflags_gflags.h) - set(GFLAGS_GREATER_20 FALSE) - endif(EXISTS ${GFlags_INCLUDE_DIRS}/gflags/gflags_gflags.h) - # set up include and link directory - include_directories(${GFlags_INCLUDE_DIRS}) - link_directories(${GFlags_LIBRARY_DIRS}) - message(STATUS "gflags library found at ${GFlags_lib}") - SET(GFlags_LIBS ${GFlags_lib}) - SET(GFlags_FOUND true) - MARK_AS_ADVANCED(GFlags_INCLUDE_DIRS) -ELSE(GFlags_ROOT_DIR) - MESSAGE(STATUS "Cannot find gflags") - SET(GFlags_FOUND false) -ENDIF(GFlags_ROOT_DIR) - diff --git a/cmake/Modules/FindGLOG.cmake b/cmake/Modules/FindGLOG.cmake index 7c50d8805..50231f585 100644 --- a/cmake/Modules/FindGLOG.cmake +++ b/cmake/Modules/FindGLOG.cmake @@ -28,20 +28,20 @@ # GLOG_ROOT - Can be set to Glog install path or Windows build path # -if (NOT DEFINED GLOG_ROOT) - set (GLOG_ROOT /usr /usr/local) -endif (NOT DEFINED GLOG_ROOT) +if(NOT DEFINED GLOG_ROOT) + set(GLOG_ROOT /usr /usr/local) +endif() if(MSVC) - set(LIB_PATHS ${GLOG_ROOT} ${GLOG_ROOT}/Release) -else(MSVC) - set (LIB_PATHS ${GLOG_ROOT} ${GLOG_ROOT}/lib) -endif(MSVC) + set(LIB_PATHS ${GLOG_ROOT} ${GLOG_ROOT}/Release) +else() + set(LIB_PATHS ${GLOG_ROOT} ${GLOG_ROOT}/lib) +endif() macro(_FIND_GLOG_LIBRARIES _var) - find_library(${_var} - NAMES ${ARGN} - PATHS ${LIB_PATHS} + find_library(${_var} + NAMES ${ARGN} + PATHS ${LIB_PATHS} /usr/local/lib /usr/lib/x86_64-linux-gnu /usr/lib/i386-linux-gnu @@ -70,46 +70,46 @@ macro(_FIND_GLOG_LIBRARIES _var) /usr/lib PATH_SUFFIXES lib ) - mark_as_advanced(${_var}) + mark_as_advanced(${_var}) endmacro() macro(_GLOG_APPEND_LIBRARIES _list _release) set(_debug ${_release}_DEBUG) if(${_debug}) - set(${_list} ${${_list}} optimized ${${_release}} debug ${${_debug}}) + set(${_list} ${${_list}} optimized ${${_release}} debug ${${_debug}}) else() - set(${_list} ${${_list}} ${${_release}}) + set(${_list} ${${_list}} ${${_release}}) endif() endmacro() if(MSVC) - find_path(GLOG_INCLUDE_DIR NAMES raw_logging.h - PATHS - ${GLOG_ROOT}/src/windows - ${GLOG_ROOT}/src/windows/glog - ) -else(MSVC) - # Linux/OS X builds - find_path(GLOG_INCLUDE_DIR NAMES raw_logging.h - PATHS - ${GLOG_ROOT}/include/glog - /usr/include/glog - /opt/local/include/glog # default location in Macports - ) -endif(MSVC) + find_path(GLOG_INCLUDE_DIR NAMES raw_logging.h + PATHS + ${GLOG_ROOT}/src/windows + ${GLOG_ROOT}/src/windows/glog + ) +else() + # Linux/OS X builds + find_path(GLOG_INCLUDE_DIR NAMES raw_logging.h + PATHS + ${GLOG_ROOT}/include/glog + /usr/include/glog + /opt/local/include/glog # default location in Macports + ) +endif() # Find the libraries if(MSVC) - _FIND_GLOG_LIBRARIES(GLOG_LIBRARIES libglog.lib) -else(MSVC) - # Linux/OS X builds - if(UNIX) - _FIND_GLOG_LIBRARIES(GLOG_LIBRARIES libglog.so) - endif(UNIX) - if(APPLE) - _FIND_GLOG_LIBRARIES(GLOG_LIBRARIES libglog.dylib) - endif(APPLE) -endif(MSVC) + _find_glog_libraries(GLOG_LIBRARIES libglog.lib) +else() + # Linux/OS X builds + if(UNIX) + _find_glog_libraries(GLOG_LIBRARIES libglog.so) + endif() + if(APPLE) + _find_glog_libraries(GLOG_LIBRARIES libglog.dylib) + endif() +endif() if(GLOG_FOUND) message(STATUS "glog library found at ${GLOG_LIBRARIES}") @@ -117,21 +117,20 @@ endif() # handle the QUIETLY and REQUIRED arguments and set GLOG_FOUND to TRUE if # all listed variables are TRUE -include("${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake") -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Glog DEFAULT_MSG - GLOG_LIBRARIES) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GLOG DEFAULT_MSG GLOG_LIBRARIES) if(MSVC) - string(REGEX REPLACE "/glog$" "" VAR_WITHOUT ${GLOG_INCLUDE_DIR}) - string(REGEX REPLACE "/windows$" "" VAR_WITHOUT ${VAR_WITHOUT}) - set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIRS} "${VAR_WITHOUT}") - string(REGEX REPLACE "/libglog.lib" "" GLOG_LIBRARIES_DIR ${GLOG_LIBRARIES}) -else(MSVC) - # Linux/OS X builds - set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR}) - string(REGEX REPLACE "/libglog.so" "" GLOG_LIBRARIES_DIR ${GLOG_LIBRARIES}) -endif(MSVC) + string(REGEX REPLACE "/glog$" "" VAR_WITHOUT ${GLOG_INCLUDE_DIR}) + string(REGEX REPLACE "/windows$" "" VAR_WITHOUT ${VAR_WITHOUT}) + set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIRS} "${VAR_WITHOUT}") + string(REGEX REPLACE "/libglog.lib" "" GLOG_LIBRARIES_DIR ${GLOG_LIBRARIES}) +else() + # Linux/OS X builds + set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR}) + string(REGEX REPLACE "/libglog.so" "" GLOG_LIBRARIES_DIR ${GLOG_LIBRARIES}) +endif() if(GLOG_FOUND) - # _GLOG_APPEND_LIBRARIES(GLOG GLOG_LIBRARIES) + # _GLOG_APPEND_LIBRARIES(GLOG GLOG_LIBRARIES) endif() diff --git a/cmake/Modules/FindGNSSSIMULATOR.cmake b/cmake/Modules/FindGNSSSIMULATOR.cmake new file mode 100644 index 000000000..5d4294548 --- /dev/null +++ b/cmake/Modules/FindGNSSSIMULATOR.cmake @@ -0,0 +1,27 @@ +# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors) +# +# This file is part of GNSS-SDR. +# +# GNSS-SDR is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GNSS-SDR is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNSS-SDR. If not, see . + +find_program(SW_GENERATOR_BIN gnss_sim + PATHS /usr/bin + /usr/local/bin + /opt/local/bin + ${CMAKE_INSTALL_PREFIX}/bin + PATH_SUFFIXES bin) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GNSSSIMULATOR DEFAULT_MSG SW_GENERATOR_BIN) +mark_as_advanced(SW_GENERATOR_BIN) diff --git a/cmake/Modules/FindGnuradio.cmake b/cmake/Modules/FindGNURADIO.cmake similarity index 66% rename from cmake/Modules/FindGnuradio.cmake rename to cmake/Modules/FindGNURADIO.cmake index 0205d5d82..c6811ba7f 100644 --- a/cmake/Modules/FindGnuradio.cmake +++ b/cmake/Modules/FindGNURADIO.cmake @@ -19,15 +19,14 @@ # Find GNU Radio ######################################################################## -INCLUDE(FindPkgConfig) -INCLUDE(FindPackageHandleStandardArgs) +include(FindPkgConfig) +include(FindPackageHandleStandardArgs) # if GR_REQUIRED_COMPONENTS is not defined, it will be set to the following list if(NOT GR_REQUIRED_COMPONENTS) set(GR_REQUIRED_COMPONENTS RUNTIME ANALOG BLOCKS DIGITAL FFT FILTER PMT FEC TRELLIS UHD) endif() - # Allows us to use all .cmake files in this directory list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_LIST_DIR}) @@ -35,18 +34,17 @@ list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_LIST_DIR}) set(GNURADIO_ALL_LIBRARIES "") set(GNURADIO_ALL_INCLUDE_DIRS "") -MACRO(LIST_CONTAINS var value) - SET(${var}) - FOREACH(value2 ${ARGN}) - IF (${value} STREQUAL ${value2}) - SET(${var} TRUE) - ENDIF(${value} STREQUAL ${value2}) - ENDFOREACH(value2) -ENDMACRO(LIST_CONTAINS) +macro(LIST_CONTAINS var value) + set(${var}) + foreach(value2 ${ARGN}) + if(${value} STREQUAL ${value2}) + set(${var} TRUE) + endif() + endforeach() +endmacro() function(GR_MODULE EXTVAR PCNAME INCFILE LIBFILE) - - LIST_CONTAINS(REQUIRED_MODULE ${EXTVAR} ${GR_REQUIRED_COMPONENTS}) + list_contains(REQUIRED_MODULE ${EXTVAR} ${GR_REQUIRED_COMPONENTS}) if(NOT REQUIRED_MODULE) #message("Ignoring GNU Radio Module ${EXTVAR}") return() @@ -55,7 +53,7 @@ function(GR_MODULE EXTVAR PCNAME INCFILE LIBFILE) message(STATUS "Checking for GNU Radio Module: ${EXTVAR}") # check for .pc hints - PKG_CHECK_MODULES(PC_GNURADIO_${EXTVAR} ${PCNAME}) + pkg_check_modules(PC_GNURADIO_${EXTVAR} ${PCNAME}) if(NOT PC_GNURADIO_${EXTVAR}_FOUND) set(PC_GNURADIO_${EXTVAR}_LIBRARIES ${LIBFILE}) @@ -67,7 +65,7 @@ function(GR_MODULE EXTVAR PCNAME INCFILE LIBFILE) set(PC_LIBDIR ${PC_GNURADIO_${EXTVAR}_LIBDIR}) # look for include files - FIND_PATH( + find_path( ${INCVAR_NAME} NAMES ${INCFILE} HINTS $ENV{GNURADIO_RUNTIME_DIR}/include @@ -81,7 +79,7 @@ function(GR_MODULE EXTVAR PCNAME INCFILE LIBFILE) # look for libs foreach(libname ${PC_GNURADIO_${EXTVAR}_LIBRARIES}) - FIND_LIBRARY( + find_library( ${LIBVAR_NAME}_${libname} NAMES ${libname} ${libname}-${PC_GNURADIO_RUNTIME_VERSION} HINTS $ENV{GNURADIO_RUNTIME_DIR}/lib @@ -118,8 +116,8 @@ function(GR_MODULE EXTVAR PCNAME INCFILE LIBFILE) /usr/lib ${GNURADIO_INSTALL_PREFIX}/lib ) - list(APPEND ${LIBVAR_NAME} ${${LIBVAR_NAME}_${libname}}) - endforeach(libname) + list(APPEND ${LIBVAR_NAME} ${${LIBVAR_NAME}_${libname}}) + endforeach() set(${LIBVAR_NAME} ${${LIBVAR_NAME}} PARENT_SCOPE) @@ -131,43 +129,42 @@ function(GR_MODULE EXTVAR PCNAME INCFILE LIBFILE) set(GNURADIO_ALL_INCLUDE_DIRS ${GNURADIO_ALL_INCLUDE_DIRS} ${GNURADIO_${EXTVAR}_INCLUDE_DIRS} PARENT_SCOPE) set(GNURADIO_ALL_LIBRARIES ${GNURADIO_ALL_LIBRARIES} ${GNURADIO_${EXTVAR}_LIBRARIES} PARENT_SCOPE) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_${EXTVAR} DEFAULT_MSG GNURADIO_${EXTVAR}_LIBRARIES GNURADIO_${EXTVAR}_INCLUDE_DIRS) + find_package_handle_standard_args(GNURADIO_${EXTVAR} DEFAULT_MSG GNURADIO_${EXTVAR}_LIBRARIES GNURADIO_${EXTVAR}_INCLUDE_DIRS) message(STATUS "GNURADIO_${EXTVAR}_FOUND = ${GNURADIO_${EXTVAR}_FOUND}") set(GNURADIO_${EXTVAR}_FOUND ${GNURADIO_${EXTVAR}_FOUND} PARENT_SCOPE) # generate an error if the module is missing if(NOT GNURADIO_${EXTVAR}_FOUND) - message(STATUS "Required GNU Radio Component: ${EXTVAR} missing!") + message(STATUS "Required GNU Radio Component: ${EXTVAR} missing!") endif() - MARK_AS_ADVANCED(GNURADIO_${EXTVAR}_LIBRARIES GNURADIO_${EXTVAR}_INCLUDE_DIRS) - + mark_as_advanced(GNURADIO_${EXTVAR}_LIBRARIES GNURADIO_${EXTVAR}_INCLUDE_DIRS) endfunction() -GR_MODULE(RUNTIME gnuradio-runtime gnuradio/top_block.h gnuradio-runtime) -GR_MODULE(ANALOG gnuradio-analog gnuradio/analog/api.h gnuradio-analog) -GR_MODULE(AUDIO gnuradio-audio gnuradio/audio/api.h gnuradio-audio) -GR_MODULE(BLOCKS gnuradio-blocks gnuradio/blocks/api.h gnuradio-blocks) -GR_MODULE(CHANNELS gnuradio-channels gnuradio/channels/api.h gnuradio-channels) -GR_MODULE(DIGITAL gnuradio-digital gnuradio/digital/api.h gnuradio-digital) -GR_MODULE(FCD gnuradio-fcd gnuradio/fcd_api.h gnuradio-fcd) -GR_MODULE(FEC gnuradio-fec gnuradio/fec/api.h gnuradio-fec) -GR_MODULE(FFT gnuradio-fft gnuradio/fft/api.h gnuradio-fft) -GR_MODULE(FILTER gnuradio-filter gnuradio/filter/api.h gnuradio-filter) -GR_MODULE(NOAA gnuradio-noaa gnuradio/noaa/api.h gnuradio-noaa) -GR_MODULE(PAGER gnuradio-pager gnuradio/pager/api.h gnuradio-pager) -GR_MODULE(QTGUI gnuradio-qtgui gnuradio/qtgui/api.h gnuradio-qtgui) -GR_MODULE(TRELLIS gnuradio-trellis gnuradio/trellis/api.h gnuradio-trellis) -GR_MODULE(UHD gnuradio-uhd gnuradio/uhd/api.h gnuradio-uhd) -GR_MODULE(VOCODER gnuradio-vocoder gnuradio/vocoder/api.h gnuradio-vocoder) -GR_MODULE(WAVELET gnuradio-wavelet gnuradio/wavelet/api.h gnuradio-wavelet) -GR_MODULE(WXGUI gnuradio-wxgui gnuradio/wxgui/api.h gnuradio-wxgui) -GR_MODULE(PMT gnuradio-runtime pmt/pmt.h gnuradio-pmt) +gr_module(RUNTIME gnuradio-runtime gnuradio/top_block.h gnuradio-runtime) +gr_module(ANALOG gnuradio-analog gnuradio/analog/api.h gnuradio-analog) +gr_module(AUDIO gnuradio-audio gnuradio/audio/api.h gnuradio-audio) +gr_module(BLOCKS gnuradio-blocks gnuradio/blocks/api.h gnuradio-blocks) +gr_module(CHANNELS gnuradio-channels gnuradio/channels/api.h gnuradio-channels) +gr_module(DIGITAL gnuradio-digital gnuradio/digital/api.h gnuradio-digital) +gr_module(FCD gnuradio-fcd gnuradio/fcd_api.h gnuradio-fcd) +gr_module(FEC gnuradio-fec gnuradio/fec/api.h gnuradio-fec) +gr_module(FFT gnuradio-fft gnuradio/fft/api.h gnuradio-fft) +gr_module(FILTER gnuradio-filter gnuradio/filter/api.h gnuradio-filter) +gr_module(NOAA gnuradio-noaa gnuradio/noaa/api.h gnuradio-noaa) +gr_module(PAGER gnuradio-pager gnuradio/pager/api.h gnuradio-pager) +gr_module(QTGUI gnuradio-qtgui gnuradio/qtgui/api.h gnuradio-qtgui) +gr_module(TRELLIS gnuradio-trellis gnuradio/trellis/api.h gnuradio-trellis) +gr_module(UHD gnuradio-uhd gnuradio/uhd/api.h gnuradio-uhd) +gr_module(VOCODER gnuradio-vocoder gnuradio/vocoder/api.h gnuradio-vocoder) +gr_module(WAVELET gnuradio-wavelet gnuradio/wavelet/api.h gnuradio-wavelet) +gr_module(WXGUI gnuradio-wxgui gnuradio/wxgui/api.h gnuradio-wxgui) +gr_module(PMT gnuradio-runtime pmt/pmt.h gnuradio-pmt) list(REMOVE_DUPLICATES GNURADIO_ALL_INCLUDE_DIRS) list(REMOVE_DUPLICATES GNURADIO_ALL_LIBRARIES) - # Trick to find out that GNU Radio is >= 3.7.4 if pkgconfig is not present +# Trick to find out that GNU Radio is >= 3.7.4 if pkgconfig is not present if(NOT PC_GNURADIO_RUNTIME_VERSION) find_file(GNURADIO_VERSION_GREATER_THAN_373 NAMES gnuradio/blocks/tsb_vector_sink_f.h @@ -178,20 +175,20 @@ if(NOT PC_GNURADIO_RUNTIME_VERSION) /usr/include ${GNURADIO_INSTALL_PREFIX}/include ) - if(GNURADIO_VERSION_GREATER_THAN_373) - set(PC_GNURADIO_RUNTIME_VERSION "3.7.4+") - endif(GNURADIO_VERSION_GREATER_THAN_373) + if(GNURADIO_VERSION_GREATER_THAN_373) + set(PC_GNURADIO_RUNTIME_VERSION "3.7.4+") + endif() - find_file(GNURADIO_VERSION_GREATER_THAN_38 - NAMES gnuradio/filter/mmse_resampler_cc.h - HINTS $ENV{GNURADIO_RUNTIME_DIR}/include - ${CMAKE_INSTALL_PREFIX}/include - ${GNURADIO_INSTALL_PREFIX}/include - PATHS /usr/local/include - /usr/include - ${GNURADIO_INSTALL_PREFIX}/include - ) - if(GNURADIO_VERSION_GREATER_THAN_38) - set(PC_GNURADIO_RUNTIME_VERSION "3.8.0+") - endif(GNURADIO_VERSION_GREATER_THAN_38) -endif(NOT PC_GNURADIO_RUNTIME_VERSION) + find_file(GNURADIO_VERSION_GREATER_THAN_38 + NAMES gnuradio/filter/mmse_resampler_cc.h + HINTS $ENV{GNURADIO_RUNTIME_DIR}/include + ${CMAKE_INSTALL_PREFIX}/include + ${GNURADIO_INSTALL_PREFIX}/include + PATHS /usr/local/include + /usr/include + ${GNURADIO_INSTALL_PREFIX}/include + ) + if(GNURADIO_VERSION_GREATER_THAN_38) + set(PC_GNURADIO_RUNTIME_VERSION "3.8.0+") + endif() +endif() diff --git a/cmake/Modules/FindGperftools.cmake b/cmake/Modules/FindGPERFTOOLS.cmake similarity index 96% rename from cmake/Modules/FindGperftools.cmake rename to cmake/Modules/FindGPERFTOOLS.cmake index 6e4d955b7..3278caf92 100644 --- a/cmake/Modules/FindGperftools.cmake +++ b/cmake/Modules/FindGPERFTOOLS.cmake @@ -19,7 +19,7 @@ # # Usage of this module as follows: # -# find_package(Gperftools) +# find_package(GPERFTOOLS) # # Variables used by this module, they can change the default behaviour and need # to be set before calling find_package: @@ -54,7 +54,7 @@ set(GPERFTOOLS_LIBRARIES ${GPERFTOOLS_TCMALLOC_AND_PROFILER}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args( - Gperftools + GPERFTOOLS DEFAULT_MSG GPERFTOOLS_LIBRARIES GPERFTOOLS_INCLUDE_DIR @@ -66,4 +66,4 @@ mark_as_advanced( GPERFTOOLS_PROFILER GPERFTOOLS_TCMALLOC_AND_PROFILER GPERFTOOLS_LIBRARIES - GPERFTOOLS_INCLUDE_DIR) \ No newline at end of file + GPERFTOOLS_INCLUDE_DIR) diff --git a/cmake/Modules/FindGPSTK.cmake b/cmake/Modules/FindGPSTK.cmake index 515878d5a..c3270a6eb 100644 --- a/cmake/Modules/FindGPSTK.cmake +++ b/cmake/Modules/FindGPSTK.cmake @@ -19,29 +19,22 @@ # Find the native gpstk includes and library # This module defines # GPSTK_INCLUDE_DIR, where to find Rinex3ObsBase.hpp, etc. -# GPSTK_LIBRARIES, libraries to link against to use GPSTK. # GPSTK_FOUND, If false, do not try to use GPSTK. -# also defined, but not for general use are # GPSTK_LIBRARY, where to find the GPSTK library. -FIND_PATH(GPSTK_INCLUDE_DIR Rinex3ObsBase.hpp - HINTS /usr/include/gpstk - /usr/local/include/gpstk - /opt/local/include/gpstk ) +find_path(GPSTK_INCLUDE_DIR gpstk/Rinex3ObsBase.hpp + HINTS /usr/include + /usr/local/include + /opt/local/include) -SET(GPSTK_NAMES ${GPSTK_NAMES} gpstk libgpstk) -FIND_LIBRARY(GPSTK_LIBRARY NAMES ${GPSTK_NAMES} - HINTS /usr/lib - /usr/local/lib - /opt/local/lib ) +set(GPSTK_NAMES ${GPSTK_NAMES} gpstk libgpstk) +find_library(GPSTK_LIBRARY NAMES ${GPSTK_NAMES} + HINTS /usr/lib + /usr/local/lib + /opt/local/lib) -# handle the QUIETLY and REQUIRED arguments and set GPSTK_FOUND to TRUE if +# handle the QUIETLY and REQUIRED arguments and set GPSTK_FOUND to TRUE if # all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(GPSTK DEFAULT_MSG GPSTK_LIBRARY GPSTK_INCLUDE_DIR) - -IF(GPSTK_FOUND) - SET( GPSTK_LIBRARIES ${GPSTK_LIBRARY} ) -ENDIF(GPSTK_FOUND) - -MARK_AS_ADVANCED(GPSTK_INCLUDE_DIR GPSTK_LIBRARY) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GPSTK DEFAULT_MSG GPSTK_LIBRARY GPSTK_INCLUDE_DIR) +mark_as_advanced(GPSTK_INCLUDE_DIR GPSTK_LIBRARY GPSTK_INCLUDE_DIR) diff --git a/cmake/Modules/FindGrDbfcttc.cmake b/cmake/Modules/FindGRDBFCTTC.cmake similarity index 81% rename from cmake/Modules/FindGrDbfcttc.cmake rename to cmake/Modules/FindGRDBFCTTC.cmake index 0245514d8..4b99f3702 100644 --- a/cmake/Modules/FindGrDbfcttc.cmake +++ b/cmake/Modules/FindGRDBFCTTC.cmake @@ -19,20 +19,20 @@ # Find GR-DBFCTTC Module ######################################################################## -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_GR_DBFCTTC gr-dbfcttc) +include(FindPkgConfig) +pkg_check_modules(PC_GR_DBFCTTC gr-dbfcttc) -FIND_PATH( +find_path( GR_DBFCTTC_INCLUDE_DIRS NAMES dbfcttc/api.h HINTS $ENV{GR_DBFCTTC_DIR}/include ${PC_GR_DBFCTTC_INCLUDEDIR} PATHS ${CMAKE_INSTALL_PREFIX}/include - /usr/include + /usr/include /usr/local/include ) -FIND_LIBRARY( +find_library( GR_DBFCTTC_LIBRARIES NAMES gnuradio-dbfcttc HINTS $ENV{GR_DBFCTTC_DIR}/lib @@ -45,6 +45,6 @@ FIND_LIBRARY( /usr/local/lib64 ) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(GR_DBFCTTC DEFAULT_MSG GR_DBFCTTC_LIBRARIES GR_DBFCTTC_INCLUDE_DIRS) -MARK_AS_ADVANCED(GR_DBFCTTC_LIBRARIES GR_DBFCTTC_INCLUDE_DIRS) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GRDBFCTTC DEFAULT_MSG GR_DBFCTTC_LIBRARIES GR_DBFCTTC_INCLUDE_DIRS) +mark_as_advanced(GR_DBFCTTC_LIBRARIES GR_DBFCTTC_INCLUDE_DIRS) diff --git a/cmake/Modules/FindGrGN3S.cmake b/cmake/Modules/FindGRGN3S.cmake similarity index 83% rename from cmake/Modules/FindGrGN3S.cmake rename to cmake/Modules/FindGRGN3S.cmake index a1340d4a7..119a75eed 100644 --- a/cmake/Modules/FindGrGN3S.cmake +++ b/cmake/Modules/FindGRGN3S.cmake @@ -19,10 +19,10 @@ # Find GR-GN3S Module ######################################################################## -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_GR_GN3S gr-gn3s) +include(FindPkgConfig) +pkg_check_modules(PC_GR_GN3S gr-gn3s) -FIND_PATH( +find_path( GR_GN3S_INCLUDE_DIRS NAMES gn3s/gn3s_api.h HINTS $ENV{GR_GN3S_DIR}/include @@ -32,7 +32,7 @@ FIND_PATH( /usr/include ) -FIND_LIBRARY( +find_library( GR_GN3S_LIBRARIES NAMES gr-gn3s HINTS $ENV{GR_GN3S_DIR}/lib @@ -45,6 +45,6 @@ FIND_LIBRARY( /usr/lib64 ) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(GR_GN3S DEFAULT_MSG GR_GN3S_LIBRARIES GR_GN3S_INCLUDE_DIRS) -MARK_AS_ADVANCED(GR_GN3S_LIBRARIES GR_GN3S_INCLUDE_DIRS) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GRGN3S DEFAULT_MSG GR_GN3S_LIBRARIES GR_GN3S_INCLUDE_DIRS) +mark_as_advanced(GR_GN3S_LIBRARIES GR_GN3S_INCLUDE_DIRS) diff --git a/cmake/Modules/FindGriio.cmake b/cmake/Modules/FindGRIIO.cmake similarity index 88% rename from cmake/Modules/FindGriio.cmake rename to cmake/Modules/FindGRIIO.cmake index 69ee780ec..5575e3122 100644 --- a/cmake/Modules/FindGriio.cmake +++ b/cmake/Modules/FindGRIIO.cmake @@ -15,10 +15,10 @@ # You should have received a copy of the GNU General Public License # along with GNSS-SDR. If not, see . -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_IIO gnuradio-iio) +include(FindPkgConfig) +pkg_check_modules(PC_IIO gnuradio-iio) -FIND_PATH( +find_path( IIO_INCLUDE_DIRS NAMES gnuradio/iio/api.h HINTS $ENV{IIO_DIR}/include @@ -28,7 +28,7 @@ FIND_PATH( /usr/include ) -FIND_LIBRARY( +find_library( IIO_LIBRARIES NAMES gnuradio-iio HINTS $ENV{IIO_DIR}/lib @@ -63,6 +63,6 @@ FIND_LIBRARY( /usr/lib/sh4-linux-gnu ) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(IIO DEFAULT_MSG IIO_LIBRARIES IIO_INCLUDE_DIRS) -MARK_AS_ADVANCED(IIO_LIBRARIES IIO_INCLUDE_DIRS) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GRIIO DEFAULT_MSG IIO_LIBRARIES IIO_INCLUDE_DIRS) +mark_as_advanced(IIO_LIBRARIES IIO_INCLUDE_DIRS) diff --git a/cmake/Modules/FindGrOsmoSDR.cmake b/cmake/Modules/FindGROSMOSDR.cmake similarity index 70% rename from cmake/Modules/FindGrOsmoSDR.cmake rename to cmake/Modules/FindGROSMOSDR.cmake index 254fecef1..e78541806 100644 --- a/cmake/Modules/FindGrOsmoSDR.cmake +++ b/cmake/Modules/FindGROSMOSDR.cmake @@ -19,7 +19,7 @@ # # Usage of this module as follows: # -# find_package(GrOsmoSDR) +# find_package(GROSMOSDR) # # Variables used by this module, they can change the default behaviour and need # to be set before calling find_package: @@ -34,20 +34,19 @@ # GROSMOSDR_LIBRARIES The gr-osmosdr libraries (gnuradio-osmosdr) # GROSMOSDR_INCLUDE_DIR The location of gr-osmosdr headers -if(NOT GROSMOSDR_FOUND) - pkg_check_modules (GROSMOSDR_PKG gnuradio-osmosdr) - find_path(GROSMOSDR_INCLUDE_DIR - NAMES osmosdr/source.h - osmosdr/api.h - PATHS - ${GROSMOSDR_PKG_INCLUDE_DIRS} - /usr/include - /usr/local/include - ) +pkg_check_modules(GROSMOSDR_PKG gnuradio-osmosdr) +find_path(GROSMOSDR_INCLUDE_DIR + NAMES osmosdr/source.h + osmosdr/api.h + PATHS + ${GROSMOSDR_PKG_INCLUDE_DIRS} + /usr/include + /usr/local/include +) - find_library(GROSMOSDR_LIBRARIES - NAMES gnuradio-osmosdr - PATHS +find_library(GROSMOSDR_LIBRARIES + NAMES gnuradio-osmosdr + PATHS ${GROSMOSDR_PKG_LIBRARY_DIRS} /usr/lib /usr/local/lib @@ -75,16 +74,8 @@ if(NOT GROSMOSDR_FOUND) /usr/lib/x86_64-linux-gnux32 /usr/lib/alpha-linux-gnu /usr/lib64 - ) +) - if(GROSMOSDR_INCLUDE_DIR AND GROSMOSDR_LIBRARIES) - set(GROSMOSDR_FOUND TRUE CACHE INTERNAL "gnuradio-osmosdr found") - message(STATUS "Found gnuradio-osmosdr: ${GROSMOSDR_INCLUDE_DIR}, ${GROSMOSDR_LIBRARIES}") - else(GROSMOSDR_INCLUDE_DIR AND GROSMOSDR_LIBRARIES) - set(GROSMOSDR_FOUND FALSE CACHE INTERNAL "gnuradio-osmosdr found") - message(STATUS "gnuradio-osmosdr not found.") - endif(GROSMOSDR_INCLUDE_DIR AND GROSMOSDR_LIBRARIES) - -mark_as_advanced(GROSMOSDR_INCLUDE_DIR GROSMOSDR_LIBRARIES) - -endif(NOT GROSMOSDR_FOUND) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GROSMOSDR DEFAULT_MSG GROSMOSDR_LIBRARIES GROSMOSDR_INCLUDE_DIR) +mark_as_advanced(GROSMOSDR_LIBRARIES GROSMOSDR_INCLUDE_DIR) diff --git a/cmake/Modules/Findlibiio.cmake b/cmake/Modules/FindLIBIIO.cmake similarity index 89% rename from cmake/Modules/Findlibiio.cmake rename to cmake/Modules/FindLIBIIO.cmake index e96d420ce..f8b6d10b9 100644 --- a/cmake/Modules/Findlibiio.cmake +++ b/cmake/Modules/FindLIBIIO.cmake @@ -15,10 +15,10 @@ # You should have received a copy of the GNU General Public License # along with GNSS-SDR. If not, see . -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_LIBIIO libiio) +include(FindPkgConfig) +pkg_check_modules(PC_LIBIIO libiio) -FIND_PATH( +find_path( LIBIIO_INCLUDE_DIRS NAMES iio.h HINTS $ENV{LIBIIO_DIR}/include @@ -29,7 +29,7 @@ FIND_PATH( /opt/local/include ) -FIND_LIBRARY( +find_library( LIBIIO_LIBRARIES NAMES iio libiio.so.0 HINTS $ENV{LIBIIO_DIR}/lib @@ -65,6 +65,6 @@ FIND_LIBRARY( /Library/Frameworks/iio.framework/ ) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBIIO DEFAULT_MSG LIBIIO_LIBRARIES LIBIIO_INCLUDE_DIRS) -MARK_AS_ADVANCED(LIBIIO_LIBRARIES LIBIIO_INCLUDE_DIRS) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LIBIIO DEFAULT_MSG LIBIIO_LIBRARIES LIBIIO_INCLUDE_DIRS) +mark_as_advanced(LIBIIO_LIBRARIES LIBIIO_INCLUDE_DIRS) diff --git a/cmake/Modules/FindLibOsmoSDR.cmake b/cmake/Modules/FindLIBOSMOSDR.cmake similarity index 69% rename from cmake/Modules/FindLibOsmoSDR.cmake rename to cmake/Modules/FindLIBOSMOSDR.cmake index fc7a28b06..72f459e72 100644 --- a/cmake/Modules/FindLibOsmoSDR.cmake +++ b/cmake/Modules/FindLIBOSMOSDR.cmake @@ -19,27 +19,25 @@ # # Usage of this module as follows: # -# find_package(LibOsmoSDR) +# find_package(LIBOSMOSDR) # # # Variables defined by this module: # # LIBOSMOSDR_FOUND System has libosmosdr libs/headers -# LIBOSMOSDR_LIBRARIES The libosmosdr libraries +# LIBOSMOSDR_LIBRARIES The libosmosdr libraries # LIBOSMOSDR_INCLUDE_DIR The location of libosmosdr headers +pkg_check_modules(LIBOSMOSDR_PKG libosmosdr) +find_path(LIBOSMOSDR_INCLUDE_DIR NAMES osmosdr.h + PATHS + ${LIBOSMOSDR_PKG_INCLUDE_DIRS} + /usr/include + /usr/local/include +) -if(NOT LIBOSMOSDR_FOUND) - pkg_check_modules (LIBOSMOSDR_PKG libosmosdr) - find_path(LIBOSMOSDR_INCLUDE_DIR NAMES osmosdr.h - PATHS - ${LIBOSMOSDR_PKG_INCLUDE_DIRS} - /usr/include - /usr/local/include - ) - - find_library(LIBOSMOSDR_LIBRARIES NAMES osmosdr - PATHS +find_library(LIBOSMOSDR_LIBRARIES NAMES osmosdr + PATHS ${LIBOSMOSDR_PKG_LIBRARY_DIRS} /usr/lib /usr/local/lib @@ -69,14 +67,6 @@ if(NOT LIBOSMOSDR_FOUND) /usr/lib64 ) - if(LIBOSMOSDR_INCLUDE_DIR AND LIBOSMOSDR_LIBRARIES) - set(LIBOSMOSDR_FOUND TRUE CACHE INTERNAL "libosmosdr found") - message(STATUS "Found libosmosdr: ${LIBOSMOSDR_INCLUDE_DIR}, ${LIBOSMOSDR_LIBRARIES}") - else(LIBOSMOSDR_INCLUDE_DIR AND LIBOSMOSDR_LIBRARIES) - set(LIBOSMOSDR_FOUND FALSE CACHE INTERNAL "libosmosdr found") - message(STATUS "libosmosdr not found.") - endif(LIBOSMOSDR_INCLUDE_DIR AND LIBOSMOSDR_LIBRARIES) - +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LIBOSMOSDR DEFAULT_MSG LIBOSMOSDR_INCLUDE_DIR LIBOSMOSDR_LIBRARIES) mark_as_advanced(LIBOSMOSDR_INCLUDE_DIR LIBOSMOSDR_LIBRARIES) - -endif(NOT LIBOSMOSDR_FOUND) diff --git a/cmake/Modules/FindLog4cpp.cmake b/cmake/Modules/FindLOG4CPP.cmake similarity index 86% rename from cmake/Modules/FindLog4cpp.cmake rename to cmake/Modules/FindLOG4CPP.cmake index 3b1e7560e..b14ac009a 100644 --- a/cmake/Modules/FindLog4cpp.cmake +++ b/cmake/Modules/FindLOG4CPP.cmake @@ -23,10 +23,10 @@ # LOG4CPP_FOUND - True if LOG4CPP found. -if (LOG4CPP_INCLUDE_DIR) +if(LOG4CPP_INCLUDE_DIR) # Already in cache, be silent set(LOG4CPP_FIND_QUIETLY TRUE) -endif () +endif() find_path(LOG4CPP_INCLUDE_DIR log4cpp/Category.hh /opt/local/include @@ -70,26 +70,17 @@ find_library(LOG4CPP_LIBRARY /opt/local/lib ) - -if (LOG4CPP_INCLUDE_DIR AND LOG4CPP_LIBRARY) +if(LOG4CPP_INCLUDE_DIR AND LOG4CPP_LIBRARY) set(LOG4CPP_FOUND TRUE) set(LOG4CPP_LIBRARIES ${LOG4CPP_LIBRARY} CACHE INTERNAL "" FORCE) set(LOG4CPP_INCLUDE_DIRS ${LOG4CPP_INCLUDE_DIR} CACHE INTERNAL "" FORCE) -else () +else() set(LOG4CPP_FOUND FALSE CACHE INTERNAL "" FORCE) set(LOG4CPP_LIBRARY "" CACHE INTERNAL "" FORCE) set(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE) set(LOG4CPP_INCLUDE_DIR "" CACHE INTERNAL "" FORCE) set(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE) -endif () +endif() -if (LOG4CPP_FOUND) - if (NOT LOG4CPP_FIND_QUIETLY) - message(STATUS "Found LOG4CPP: ${LOG4CPP_LIBRARIES}") - endif () -else () - if (LOG4CPP_FIND_REQUIRED) - message(STATUS "Looked for LOG4CPP libraries named ${LOG4CPPS_NAMES}.") - message(FATAL_ERROR "Could NOT find LOG4CPP library") - endif () -endif () \ No newline at end of file +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LOG4CPP DEFAULT_MSG LOG4CPP_INCLUDE_DIRS LOG4CPP_LIBRARIES) diff --git a/cmake/Modules/FindMATIO.cmake b/cmake/Modules/FindMATIO.cmake index 2bac55ede..e9d66c65b 100644 --- a/cmake/Modules/FindMATIO.cmake +++ b/cmake/Modules/FindMATIO.cmake @@ -21,30 +21,30 @@ # # Once done this will define: # -# MATIO_FOUND - True if MATIO found. -# MATIO_LIBRARIES - MATIO libraries. +# MATIO_FOUND - True if MATIO found. +# MATIO_LIBRARIES - MATIO libraries. # MATIO_INCLUDE_DIRS - where to find matio.h, etc.. # MATIO_VERSION_STRING - version number as a string (e.g.: "1.3.4") -# +# #============================================================================= # Copyright 2015 Avtech Scientific -# +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: -# +# # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. -# +# # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. -# +# # * Neither the names of Kitware, Inc., the Insight Software Consortium, # nor the names of their contributors may be used to endorse or promote # products derived from this software without specific prior written # permission. -# +# # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -66,52 +66,50 @@ find_path(MATIO_INCLUDE_DIR NAMES matio.h DOC "The MATIO include directory") find_library(MATIO_LIBRARY NAMES matio DOC "The MATIO library") if(MATIO_INCLUDE_DIR) - # --------------------------------------------------- - # Extract version information from MATIO - # --------------------------------------------------- + # --------------------------------------------------- + # Extract version information from MATIO + # --------------------------------------------------- - # If the file is missing, set all values to 0 - set(MATIO_MAJOR_VERSION 0) - set(MATIO_MINOR_VERSION 0) - set(MATIO_RELEASE_LEVEL 0) + # If the file is missing, set all values to 0 + set(MATIO_MAJOR_VERSION 0) + set(MATIO_MINOR_VERSION 0) + set(MATIO_RELEASE_LEVEL 0) - # new versions of MATIO have `matio_pubconf.h` - if(EXISTS ${MATIO_INCLUDE_DIR}/matio_pubconf.h) - set(MATIO_CONFIG_FILE "matio_pubconf.h") - else() - set(MATIO_CONFIG_FILE "matioConfig.h") - endif() + # new versions of MATIO have `matio_pubconf.h` + if(EXISTS ${MATIO_INCLUDE_DIR}/matio_pubconf.h) + set(MATIO_CONFIG_FILE "matio_pubconf.h") + else() + set(MATIO_CONFIG_FILE "matioConfig.h") + endif() - if(MATIO_CONFIG_FILE) + if(MATIO_CONFIG_FILE) - # Read and parse MATIO config header file for version number - file(STRINGS "${MATIO_INCLUDE_DIR}/${MATIO_CONFIG_FILE}" _matio_HEADER_CONTENTS REGEX "#define MATIO_((MAJOR|MINOR)_VERSION)|(RELEASE_LEVEL) ") + # Read and parse MATIO config header file for version number + file(STRINGS "${MATIO_INCLUDE_DIR}/${MATIO_CONFIG_FILE}" _matio_HEADER_CONTENTS REGEX "#define MATIO_((MAJOR|MINOR)_VERSION)|(RELEASE_LEVEL) ") - foreach(line ${_matio_HEADER_CONTENTS}) - if(line MATCHES "#define ([A-Z_]+) ([0-9]+)") - set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}") - endif() - endforeach() + foreach(line ${_matio_HEADER_CONTENTS}) + if(line MATCHES "#define ([A-Z_]+) ([0-9]+)") + set("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}") + endif() + endforeach() - unset(_matio_HEADER_CONTENTS) - endif() + unset(_matio_HEADER_CONTENTS) + endif() - set(MATIO_VERSION_STRING "${MATIO_MAJOR_VERSION}.${MATIO_MINOR_VERSION}.${MATIO_RELEASE_LEVEL}") -endif () - -#================== + set(MATIO_VERSION_STRING "${MATIO_MAJOR_VERSION}.${MATIO_MINOR_VERSION}.${MATIO_RELEASE_LEVEL}") +endif() mark_as_advanced(MATIO_INCLUDE_DIR MATIO_LIBRARY) -# handle the QUIETLY and REQUIRED arguments and set MATIO_FOUND to TRUE if +# handle the QUIETLY and REQUIRED arguments and set MATIO_FOUND to TRUE if # all listed variables are TRUE include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(MATIO REQUIRED_VARS MATIO_LIBRARY MATIO_INCLUDE_DIR VERSION_VAR MATIO_VERSION_STRING) +find_package_handle_standard_args(MATIO REQUIRED_VARS MATIO_LIBRARY MATIO_INCLUDE_DIR VERSION_VAR MATIO_VERSION_STRING) if(MATIO_FOUND) set(MATIO_LIBRARIES ${MATIO_LIBRARY}) set(MATIO_INCLUDE_DIRS ${MATIO_INCLUDE_DIR}) -else(MATIO_FOUND) +else() set(MATIO_LIBRARIES) set(MATIO_INCLUDE_DIRS) -endif(MATIO_FOUND) \ No newline at end of file +endif() diff --git a/cmake/Modules/FindOpenBLAS.cmake b/cmake/Modules/FindOPENBLAS.cmake similarity index 53% rename from cmake/Modules/FindOpenBLAS.cmake rename to cmake/Modules/FindOPENBLAS.cmake index 133de9b63..0704a9681 100644 --- a/cmake/Modules/FindOpenBLAS.cmake +++ b/cmake/Modules/FindOPENBLAS.cmake @@ -17,26 +17,28 @@ # - Try to find OpenBLAS library (not headers!) # -# The following environment variable is optionally searched +# The following environment variable is optionally searched # OPENBLAS_HOME: Base directory where all OpenBlas components are found -SET(OPEN_BLAS_SEARCH_PATHS /lib/ - /lib64/ - /usr/lib - /usr/lib64 - /usr/local/lib - /usr/local/lib64 - /opt/OpenBLAS/lib - /opt/local/lib - /usr/lib/openblas-base - $ENV{OPENBLAS_HOME}/lib +set(OPEN_BLAS_SEARCH_PATHS /lib/ + /lib64/ + /usr/lib + /usr/lib64 + /usr/local/lib + /usr/local/lib64 + /opt/OpenBLAS/lib + /opt/local/lib + /usr/lib/openblas-base + $ENV{OPENBLAS_HOME}/lib ) - -FIND_LIBRARY(OPENBLAS NAMES openblas PATHS ${OPEN_BLAS_SEARCH_PATHS}) -IF (OPENBLAS) - SET(OPENBLAS_FOUND ON) - MESSAGE(STATUS "Found OpenBLAS") -ENDIF (OPENBLAS) +find_library(OPENBLAS NAMES openblas PATHS ${OPEN_BLAS_SEARCH_PATHS}) -MARK_AS_ADVANCED(OPENBLAS) +if(OPENBLAS) + set(OPENBLAS_FOUND ON) + message(STATUS "Found OpenBLAS") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OPENBLAS DEFAULT_MSG OPENBLAS) +mark_as_advanced(OPENBLAS) diff --git a/cmake/Modules/FindOPENCL.cmake b/cmake/Modules/FindOPENCL.cmake new file mode 100644 index 000000000..988360c29 --- /dev/null +++ b/cmake/Modules/FindOPENCL.cmake @@ -0,0 +1,110 @@ +# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors) +# +# This file is part of GNSS-SDR. +# +# GNSS-SDR is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GNSS-SDR is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNSS-SDR. If not, see . + +# +# This file taken from FindOpenCL project @ http://gitorious.com/findopencl +# +# - Try to find OpenCL +# This module tries to find an OpenCL implementation on your system. It supports +# AMD / ATI, Apple and NVIDIA implementations, but shoudl work, too. +# +# Once done this will define +# OPENCL_FOUND - system has OpenCL +# OPENCL_INCLUDE_DIRS - the OpenCL include directory +# OPENCL_LIBRARIES - link these to use OpenCL +# +# WIN32 should work, but is untested + +include(FindPackageHandleStandardArgs) + +set(OPENCL_VERSION_STRING "0.1.0") +set(OPENCL_VERSION_MAJOR 0) +set(OPENCL_VERSION_MINOR 1) +set(OPENCL_VERSION_PATCH 0) + +if(APPLE) + find_library(OPENCL_LIBRARIES OpenCL DOC "OpenCL lib for OSX") + find_path(OPENCL_INCLUDE_DIRS OpenCL/cl.h DOC "Include for OpenCL on OSX") + find_path(_OPENCL_CPP_INCLUDE_DIRS OpenCL/cl.hpp DOC "Include for OpenCL CPP bindings on OSX") + +else() + if(WIN32) + find_path(OPENCL_INCLUDE_DIRS CL/cl.h) + find_path(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp) + + # The AMD SDK currently installs both x86 and x86_64 libraries + # This is only a hack to find out architecture + if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64") + set(OPENCL_LIB_DIR "$ENV{ATISTREAMSDKROOT}/lib/x86_64") + set(OPENCL_LIB_DIR "$ENV{ATIINTERNALSTREAMSDKROOT}/lib/x86_64") + else() + set(OPENCL_LIB_DIR "$ENV{ATISTREAMSDKROOT}/lib/x86") + set(OPENCL_LIB_DIR "$ENV{ATIINTERNALSTREAMSDKROOT}/lib/x86") + endif() + + # find out if the user asked for a 64-bit build, and use the corresponding + # 64 or 32 bit NVIDIA library paths to the search: + string(REGEX MATCH "Win64" ISWIN64 ${CMAKE_GENERATOR}) + if("${ISWIN64}" STREQUAL "Win64") + find_library(OPENCL_LIBRARIES OpenCL.lib ${OPENCL_LIB_DIR} $ENV{CUDA_LIB_PATH} $ENV{CUDA_PATH}/lib/x64) + else() + find_library(OPENCL_LIBRARIES OpenCL.lib ${OPENCL_LIB_DIR} $ENV{CUDA_LIB_PATH} $ENV{CUDA_PATH}/lib/Win32) + endif() + + get_filename_component(_OPENCL_INC_CAND ${OPENCL_LIB_DIR}/../../include ABSOLUTE) + + # On Win32 search relative to the library + find_path(OPENCL_INCLUDE_DIRS CL/cl.h PATHS "${_OPENCL_INC_CAND}" $ENV{CUDA_INC_PATH} $ENV{CUDA_PATH}/include) + find_path(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp PATHS "${_OPENCL_INC_CAND}" $ENV{CUDA_INC_PATH} $ENV{CUDA_PATH}/include) + + else() + # Unix style platforms + find_library(OPENCL_LIBRARIES OpenCL + ENV LD_LIBRARY_PATH + ) + + get_filename_component(OPENCL_LIB_DIR ${OPENCL_LIBRARIES} PATH) + get_filename_component(_OPENCL_INC_CAND ${OPENCL_LIB_DIR}/../../include ABSOLUTE) + + # The AMD SDK currently does not place its headers + # in /usr/include, therefore also search relative + # to the library + find_path(OPENCL_INCLUDE_DIRS CL/cl.h PATHS ${_OPENCL_INC_CAND} "/usr/local/cuda/include") + find_path(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp PATHS ${_OPENCL_INC_CAND} "/usr/local/cuda/include") + endif() +endif() + +find_package_handle_standard_args(OPENCL DEFAULT_MSG OPENCL_LIBRARIES OPENCL_INCLUDE_DIRS) + +if(_OPENCL_CPP_INCLUDE_DIRS) + set(OPENCL_HAS_CPP_BINDINGS TRUE) + list(APPEND OPENCL_INCLUDE_DIRS ${_OPENCL_CPP_INCLUDE_DIRS}) + # This is often the same, so clean up + list(REMOVE_DUPLICATES OPENCL_INCLUDE_DIRS) +endif() + +mark_as_advanced( + OPENCL_INCLUDE_DIRS +) + +if(OPENCL_INCLUDE_DIRS AND OPENCL_LIBRARIES) + set( OPENCL_FOUND TRUE ) + add_definitions( -DOPENCL=1 ) +else() + set( OPENCL_FOUND FALSE ) + add_definitions( -DOPENCL=0 ) +endif() diff --git a/cmake/Modules/FindORC.cmake b/cmake/Modules/FindORC.cmake index 2751494ba..7bd013e67 100644 --- a/cmake/Modules/FindORC.cmake +++ b/cmake/Modules/FindORC.cmake @@ -15,52 +15,52 @@ # You should have received a copy of the GNU General Public License # along with GNSS-SDR. If not, see . -FIND_PACKAGE(PkgConfig) -PKG_CHECK_MODULES(PC_ORC "orc-0.4 > 0.4.22") +find_package(PkgConfig) +pkg_check_modules(PC_ORC "orc-0.4 > 0.4.22") -FIND_PROGRAM(ORCC_EXECUTABLE orcc - HINTS ${PC_ORC_TOOLSDIR} - PATHS ${ORC_ROOT}/bin ${CMAKE_INSTALL_PREFIX}/bin) +find_program(ORCC_EXECUTABLE orcc + HINTS ${PC_ORC_TOOLSDIR} + PATHS ${ORC_ROOT}/bin ${CMAKE_INSTALL_PREFIX}/bin) -FIND_PATH(ORC_INCLUDE_DIR NAMES orc/orc.h - HINTS ${PC_ORC_INCLUDEDIR} - PATHS ${ORC_ROOT}/include/orc-0.4 ${CMAKE_INSTALL_PREFIX}/include/orc-0.4) +find_path(ORC_INCLUDE_DIR NAMES orc/orc.h + HINTS ${PC_ORC_INCLUDEDIR} + PATHS ${ORC_ROOT}/include/orc-0.4 ${CMAKE_INSTALL_PREFIX}/include/orc-0.4) -FIND_PATH(ORC_LIBRARY_DIR NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}orc-0.4${CMAKE_SHARED_LIBRARY_SUFFIX} - HINTS ${PC_ORC_LIBDIR} - /usr/local/lib - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib64 - /usr/lib - PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) +find_path(ORC_LIBRARY_DIR NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}orc-0.4${CMAKE_SHARED_LIBRARY_SUFFIX} + HINTS ${PC_ORC_LIBDIR} + /usr/local/lib + /usr/lib/x86_64-linux-gnu + /usr/lib/i386-linux-gnu + /usr/lib/arm-linux-gnueabihf + /usr/lib/arm-linux-gnueabi + /usr/lib/aarch64-linux-gnu + /usr/lib/mipsel-linux-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/powerpc-linux-gnu + /usr/lib/powerpc64-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/hppa-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/lib64 + /usr/lib + PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) -FIND_LIBRARY(ORC_LIB orc-0.4 - HINTS ${PC_ORC_LIBRARY_DIRS} - PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) +find_library(ORC_LIB orc-0.4 + HINTS ${PC_ORC_LIBRARY_DIRS} + PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) -LIST(APPEND ORC_LIBRARY - ${ORC_LIB} +list(APPEND ORC_LIBRARY + ${ORC_LIB} ) -SET(ORC_INCLUDE_DIRS ${ORC_INCLUDE_DIR}) -SET(ORC_LIBRARIES ${ORC_LIBRARY}) -SET(ORC_LIBRARY_DIRS ${ORC_LIBRARY_DIR}) +set(ORC_INCLUDE_DIRS ${ORC_INCLUDE_DIR}) +set(ORC_LIBRARIES ${ORC_LIBRARY}) +set(ORC_LIBRARY_DIRS ${ORC_LIBRARY_DIR}) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(ORC "orc files" ORC_LIBRARY ORC_INCLUDE_DIR ORCC_EXECUTABLE) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ORC "orc files" ORC_LIBRARY ORC_INCLUDE_DIR ORCC_EXECUTABLE) -mark_as_advanced(ORC_INCLUDE_DIR ORC_LIBRARY ORCC_EXECUTABLE) \ No newline at end of file +mark_as_advanced(ORC_INCLUDE_DIR ORC_LIBRARY ORCC_EXECUTABLE) diff --git a/cmake/Modules/FindOpenCL.cmake b/cmake/Modules/FindOpenCL.cmake deleted file mode 100644 index 7b2d3f1dd..000000000 --- a/cmake/Modules/FindOpenCL.cmake +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors) -# -# This file is part of GNSS-SDR. -# -# GNSS-SDR is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# GNSS-SDR is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNSS-SDR. If not, see . - -# -# This file taken from FindOpenCL project @ http://gitorious.com/findopencl -# -# - Try to find OpenCL -# This module tries to find an OpenCL implementation on your system. It supports -# AMD / ATI, Apple and NVIDIA implementations, but shoudl work, too. -# -# Once done this will define -# OPENCL_FOUND - system has OpenCL -# OPENCL_INCLUDE_DIRS - the OpenCL include directory -# OPENCL_LIBRARIES - link these to use OpenCL -# -# WIN32 should work, but is untested - -FIND_PACKAGE( PackageHandleStandardArgs ) - -SET (OPENCL_VERSION_STRING "0.1.0") -SET (OPENCL_VERSION_MAJOR 0) -SET (OPENCL_VERSION_MINOR 1) -SET (OPENCL_VERSION_PATCH 0) - -IF (APPLE) - - FIND_LIBRARY(OPENCL_LIBRARIES OpenCL DOC "OpenCL lib for OSX") - FIND_PATH(OPENCL_INCLUDE_DIRS OpenCL/cl.h DOC "Include for OpenCL on OSX") - FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS OpenCL/cl.hpp DOC "Include for OpenCL CPP bindings on OSX") - -ELSE (APPLE) - - IF (WIN32) - - FIND_PATH(OPENCL_INCLUDE_DIRS CL/cl.h) - FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp) - - # The AMD SDK currently installs both x86 and x86_64 libraries - # This is only a hack to find out architecture - IF( ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64" ) - SET(OPENCL_LIB_DIR "$ENV{ATISTREAMSDKROOT}/lib/x86_64") - SET(OPENCL_LIB_DIR "$ENV{ATIINTERNALSTREAMSDKROOT}/lib/x86_64") - ELSE (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64") - SET(OPENCL_LIB_DIR "$ENV{ATISTREAMSDKROOT}/lib/x86") - SET(OPENCL_LIB_DIR "$ENV{ATIINTERNALSTREAMSDKROOT}/lib/x86") - ENDIF( ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64" ) - - # find out if the user asked for a 64-bit build, and use the corresponding - # 64 or 32 bit NVIDIA library paths to the search: - STRING(REGEX MATCH "Win64" ISWIN64 ${CMAKE_GENERATOR}) - IF("${ISWIN64}" STREQUAL "Win64") - FIND_LIBRARY(OPENCL_LIBRARIES OpenCL.lib ${OPENCL_LIB_DIR} $ENV{CUDA_LIB_PATH} $ENV{CUDA_PATH}/lib/x64) - ELSE("${ISWIN64}" STREQUAL "Win64") - FIND_LIBRARY(OPENCL_LIBRARIES OpenCL.lib ${OPENCL_LIB_DIR} $ENV{CUDA_LIB_PATH} $ENV{CUDA_PATH}/lib/Win32) - ENDIF("${ISWIN64}" STREQUAL "Win64") - - GET_FILENAME_COMPONENT(_OPENCL_INC_CAND ${OPENCL_LIB_DIR}/../../include ABSOLUTE) - - # On Win32 search relative to the library - FIND_PATH(OPENCL_INCLUDE_DIRS CL/cl.h PATHS "${_OPENCL_INC_CAND}" $ENV{CUDA_INC_PATH} $ENV{CUDA_PATH}/include) - FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp PATHS "${_OPENCL_INC_CAND}" $ENV{CUDA_INC_PATH} $ENV{CUDA_PATH}/include) - - ELSE (WIN32) - - # Unix style platforms - FIND_LIBRARY(OPENCL_LIBRARIES OpenCL - ENV LD_LIBRARY_PATH - ) - - GET_FILENAME_COMPONENT(OPENCL_LIB_DIR ${OPENCL_LIBRARIES} PATH) - GET_FILENAME_COMPONENT(_OPENCL_INC_CAND ${OPENCL_LIB_DIR}/../../include ABSOLUTE) - - # The AMD SDK currently does not place its headers - # in /usr/include, therefore also search relative - # to the library - FIND_PATH(OPENCL_INCLUDE_DIRS CL/cl.h PATHS ${_OPENCL_INC_CAND} "/usr/local/cuda/include") - FIND_PATH(_OPENCL_CPP_INCLUDE_DIRS CL/cl.hpp PATHS ${_OPENCL_INC_CAND} "/usr/local/cuda/include") - - ENDIF (WIN32) - -ENDIF (APPLE) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS( OpenCL DEFAULT_MSG OPENCL_LIBRARIES OPENCL_INCLUDE_DIRS ) - -IF( _OPENCL_CPP_INCLUDE_DIRS ) - SET( OPENCL_HAS_CPP_BINDINGS TRUE ) - LIST( APPEND OPENCL_INCLUDE_DIRS ${_OPENCL_CPP_INCLUDE_DIRS} ) - # This is often the same, so clean up - LIST( REMOVE_DUPLICATES OPENCL_INCLUDE_DIRS ) -ENDIF( _OPENCL_CPP_INCLUDE_DIRS ) - -MARK_AS_ADVANCED( - OPENCL_INCLUDE_DIRS -) - -IF( OPENCL_INCLUDE_DIRS AND OPENCL_LIBRARIES ) - SET( OPENCL_FOUND TRUE ) - add_definitions( -DOPENCL=1 ) -ELSE( OPENCL_INCLUDE_DIRS AND OPENCL_LIBRARIES ) - SET( OPENCL_FOUND FALSE ) - add_definitions( -DOPENCL=0 ) -ENDIF( OPENCL_INCLUDE_DIRS AND OPENCL_LIBRARIES ) diff --git a/cmake/Modules/FindPCAP.cmake b/cmake/Modules/FindPCAP.cmake index 3be89420e..d91524ff4 100644 --- a/cmake/Modules/FindPCAP.cmake +++ b/cmake/Modules/FindPCAP.cmake @@ -37,16 +37,16 @@ # Find the PCAP includes and library # http://www.tcpdump.org/ # -# The environment variable PCAPDIR allows to specficy where to find +# The environment variable PCAPDIR allows to specficy where to find # libpcap in non standard location. -# +# # PCAP_INCLUDE_DIRS - where to find pcap.h, etc. # PCAP_LIBRARIES - List of libraries when using pcap. # PCAP_FOUND - True if pcap found. -IF(EXISTS $ENV{PCAPDIR}) - FIND_PATH(PCAP_INCLUDE_DIR +if(EXISTS $ENV{PCAPDIR}) + find_path(PCAP_INCLUDE_DIR NAMES pcap/pcap.h pcap.h @@ -54,68 +54,60 @@ IF(EXISTS $ENV{PCAPDIR}) $ENV{PCAPDIR} NO_DEFAULT_PATH ) - - FIND_LIBRARY(PCAP_LIBRARY - NAMES + find_library(PCAP_LIBRARY + NAMES pcap PATHS $ENV{PCAPDIR} NO_DEFAULT_PATH ) - - -ELSE(EXISTS $ENV{PCAPDIR}) - FIND_PATH(PCAP_INCLUDE_DIR +else() + find_path(PCAP_INCLUDE_DIR NAMES pcap/pcap.h pcap.h ) - - FIND_LIBRARY(PCAP_LIBRARY - NAMES + + find_library(PCAP_LIBRARY + NAMES pcap ) - -ENDIF(EXISTS $ENV{PCAPDIR}) +endif() -SET(PCAP_INCLUDE_DIRS ${PCAP_INCLUDE_DIR}) -SET(PCAP_LIBRARIES ${PCAP_LIBRARY}) +set(PCAP_INCLUDE_DIRS ${PCAP_INCLUDE_DIR}) +set(PCAP_LIBRARIES ${PCAP_LIBRARY}) -IF(PCAP_INCLUDE_DIRS) - MESSAGE(STATUS "Pcap include dirs set to ${PCAP_INCLUDE_DIRS}") -ELSE(PCAP_INCLUDE_DIRS) - MESSAGE(FATAL " Pcap include dirs cannot be found") -ENDIF(PCAP_INCLUDE_DIRS) +if(PCAP_INCLUDE_DIRS) + message(STATUS "Pcap include dirs set to ${PCAP_INCLUDE_DIRS}") +else() + message(FATAL " Pcap include dirs cannot be found") +endif() -IF(PCAP_LIBRARIES) - MESSAGE(STATUS "Pcap library set to ${PCAP_LIBRARIES}") -ELSE(PCAP_LIBRARIES) - MESSAGE(FATAL "Pcap library cannot be found") -ENDIF(PCAP_LIBRARIES) +if(PCAP_LIBRARIES) + message(STATUS "Pcap library set to ${PCAP_LIBRARIES}") +else() + message(FATAL "Pcap library cannot be found") +endif() #Functions -INCLUDE(CheckFunctionExists) -SET(CMAKE_REQUIRED_INCLUDES ${PCAP_INCLUDE_DIRS}) -SET(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARIES}) -CHECK_FUNCTION_EXISTS("pcap_breakloop" HAVE_PCAP_BREAKLOOP) -CHECK_FUNCTION_EXISTS("pcap_datalink_name_to_val" HAVE_PCAP_DATALINK_NAME_TO_VAL) -CHECK_FUNCTION_EXISTS("pcap_datalink_val_to_name" HAVE_PCAP_DATALINK_VAL_TO_NAME) -CHECK_FUNCTION_EXISTS("pcap_findalldevs" HAVE_PCAP_FINDALLDEVS) -CHECK_FUNCTION_EXISTS("pcap_freecode" HAVE_PCAP_FREECODE) -CHECK_FUNCTION_EXISTS("pcap_get_selectable_fd" HAVE_PCAP_GET_SELECTABLE_FD) -CHECK_FUNCTION_EXISTS("pcap_lib_version" HAVE_PCAP_LIB_VERSION) -CHECK_FUNCTION_EXISTS("pcap_list_datalinks" HAVE_PCAP_LIST_DATALINKS) -CHECK_FUNCTION_EXISTS("pcap_open_dead" HAVE_PCAP_OPEN_DEAD) -CHECK_FUNCTION_EXISTS("pcap_set_datalink" HAVE_PCAP_SET_DATALINK) +include(CheckFunctionExists) +set(CMAKE_REQUIRED_INCLUDES ${PCAP_INCLUDE_DIRS}) +set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARIES}) +check_function_exists("pcap_breakloop" HAVE_PCAP_BREAKLOOP) +check_function_exists("pcap_datalink_name_to_val" HAVE_PCAP_DATALINK_NAME_TO_VAL) +check_function_exists("pcap_datalink_val_to_name" HAVE_PCAP_DATALINK_VAL_TO_NAME) +check_function_exists("pcap_findalldevs" HAVE_PCAP_FINDALLDEVS) +check_function_exists("pcap_freecode" HAVE_PCAP_FREECODE) +check_function_exists("pcap_get_selectable_fd" HAVE_PCAP_GET_SELECTABLE_FD) +check_function_exists("pcap_lib_version" HAVE_PCAP_LIB_VERSION) +check_function_exists("pcap_list_datalinks" HAVE_PCAP_LIST_DATALINKS) +check_function_exists("pcap_open_dead" HAVE_PCAP_OPEN_DEAD) +check_function_exists("pcap_set_datalink" HAVE_PCAP_SET_DATALINK) - -#Is pcap found ? -IF(PCAP_INCLUDE_DIRS AND PCAP_LIBRARIES) - SET( PCAP_FOUND true ) -ENDIF(PCAP_INCLUDE_DIRS AND PCAP_LIBRARIES) - - -MARK_AS_ADVANCED( +mark_as_advanced( PCAP_LIBRARIES PCAP_INCLUDE_DIRS ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PCAP DEFAULT_MSG PCAP_INCLUDE_DIRS PCAP_LIBRARIES) diff --git a/cmake/Modules/FindPUGIXML.cmake b/cmake/Modules/FindPUGIXML.cmake new file mode 100644 index 000000000..da7de4188 --- /dev/null +++ b/cmake/Modules/FindPUGIXML.cmake @@ -0,0 +1,67 @@ +# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors) +# +# This file is part of GNSS-SDR. +# +# GNSS-SDR is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GNSS-SDR is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNSS-SDR. If not, see . + +# Find the pugixml XML parsing library. +# +# Sets the usual variables expected for find_package scripts: +# +# PUGIXML_INCLUDE_DIR - header location +# PUGIXML_LIBRARIES - library to link against +# PUGIXML_FOUND - true if pugixml was found. + +find_path(PUGIXML_INCLUDE_DIR + NAMES pugixml.hpp + PATHS ${PUGIXML_HOME}/include + /usr/include + /usr/local/include + /opt/local/include) + +find_library(PUGIXML_LIBRARY + NAMES pugixml + PATHS ${PUGIXML_HOME}/lib + /usr/lib/x86_64-linux-gnu + /usr/lib/aarch64-linux-gnu + /usr/lib/arm-linux-gnueabi + /usr/lib/arm-linux-gnueabihf + /usr/lib/i386-linux-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/mipsel-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/local/lib + /opt/local/lib + /usr/lib + /usr/lib64 + /usr/local/lib64) + +# Support the REQUIRED and QUIET arguments, and set PUGIXML_FOUND if found. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PUGIXML DEFAULT_MSG PUGIXML_LIBRARY + PUGIXML_INCLUDE_DIR) + +if(PUGIXML_FOUND) + set(PUGIXML_LIBRARIES ${PUGIXML_LIBRARY}) + if(NOT PUGIXML_FIND_QUIETLY) + message(STATUS "PugiXML include = ${PUGIXML_INCLUDE_DIR}") + message(STATUS "PugiXML library = ${PUGIXML_LIBRARY}") + endif() +else() + message(STATUS "PugiXML not found.") +endif() + +mark_as_advanced(PUGIXML_LIBRARY PUGIXML_INCLUDE_DIR) diff --git a/cmake/Modules/FindTeleorbit.cmake b/cmake/Modules/FindTELEORBIT.cmake similarity index 83% rename from cmake/Modules/FindTeleorbit.cmake rename to cmake/Modules/FindTELEORBIT.cmake index e7fdbf5fc..0f78ed339 100644 --- a/cmake/Modules/FindTeleorbit.cmake +++ b/cmake/Modules/FindTELEORBIT.cmake @@ -15,10 +15,10 @@ # You should have received a copy of the GNU General Public License # along with GNSS-SDR. If not, see . -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_TELEORBIT teleorbit) +include(FindPkgConfig) +pkg_check_modules(PC_TELEORBIT teleorbit) -FIND_PATH( +find_path( TELEORBIT_INCLUDE_DIRS NAMES teleorbit/api.h HINTS $ENV{TELEORBIT_DIR}/include @@ -28,7 +28,7 @@ FIND_PATH( /usr/include ) -FIND_LIBRARY( +find_library( TELEORBIT_LIBRARIES NAMES gnuradio-teleorbit HINTS $ENV{TELEORBIT_DIR}/lib @@ -41,6 +41,6 @@ FIND_LIBRARY( /usr/lib64 ) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(TELEORBIT DEFAULT_MSG TELEORBIT_LIBRARIES TELEORBIT_INCLUDE_DIRS) -MARK_AS_ADVANCED(TELEORBIT_LIBRARIES TELEORBIT_INCLUDE_DIRS) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(TELEORBIT DEFAULT_MSG TELEORBIT_LIBRARIES TELEORBIT_INCLUDE_DIRS) +mark_as_advanced(TELEORBIT_LIBRARIES TELEORBIT_INCLUDE_DIRS) diff --git a/cmake/Modules/FindUHD.cmake b/cmake/Modules/FindUHD.cmake index 3a245f8a2..fc12a9cdd 100644 --- a/cmake/Modules/FindUHD.cmake +++ b/cmake/Modules/FindUHD.cmake @@ -19,10 +19,10 @@ # Find the library for the USRP Hardware Driver ######################################################################## -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_UHD uhd) +include(FindPkgConfig) +pkg_check_modules(PC_UHD uhd) -FIND_PATH( +find_path( UHD_INCLUDE_DIRS NAMES uhd/config.hpp HINTS $ENV{UHD_DIR}/include @@ -32,7 +32,7 @@ FIND_PATH( ${GNURADIO_INSTALL_PREFIX}/include ) -FIND_LIBRARY( +find_library( UHD_LIBRARIES NAMES uhd HINTS $ENV{UHD_DIR}/lib @@ -66,6 +66,6 @@ FIND_LIBRARY( ${GNURADIO_INSTALL_PREFIX}/lib ) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(UHD DEFAULT_MSG UHD_LIBRARIES UHD_INCLUDE_DIRS) -MARK_AS_ADVANCED(UHD_LIBRARIES UHD_INCLUDE_DIRS) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(UHD DEFAULT_MSG UHD_LIBRARIES UHD_INCLUDE_DIRS) +mark_as_advanced(UHD_LIBRARIES UHD_INCLUDE_DIRS) diff --git a/cmake/Modules/FindVolk.cmake b/cmake/Modules/FindVOLK.cmake similarity index 89% rename from cmake/Modules/FindVolk.cmake rename to cmake/Modules/FindVOLK.cmake index 994ce6e7d..d491c08b0 100644 --- a/cmake/Modules/FindVolk.cmake +++ b/cmake/Modules/FindVOLK.cmake @@ -19,10 +19,10 @@ # Find VOLK (Vector-Optimized Library of Kernels) ######################################################################## -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_VOLK volk) +include(FindPkgConfig) +pkg_check_modules(PC_VOLK volk) -FIND_PATH( +find_path( VOLK_INCLUDE_DIRS NAMES volk/volk.h HINTS $ENV{VOLK_DIR}/include @@ -32,7 +32,7 @@ FIND_PATH( ${CMAKE_INSTALL_PREFIX}/include ) -FIND_LIBRARY( +find_library( VOLK_LIBRARIES NAMES volk HINTS $ENV{VOLK_DIR}/lib @@ -67,7 +67,6 @@ FIND_LIBRARY( ${CMAKE_INSTALL_PREFIX}/lib ) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(VOLK DEFAULT_MSG VOLK_LIBRARIES VOLK_INCLUDE_DIRS) -MARK_AS_ADVANCED(VOLK_LIBRARIES VOLK_INCLUDE_DIRS VOLK_VERSION) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(VOLK DEFAULT_MSG VOLK_LIBRARIES VOLK_INCLUDE_DIRS) +mark_as_advanced(VOLK_LIBRARIES VOLK_INCLUDE_DIRS VOLK_VERSION) diff --git a/cmake/Modules/FindVolkGnssSdr.cmake b/cmake/Modules/FindVOLKGNSSSDR.cmake similarity index 82% rename from cmake/Modules/FindVolkGnssSdr.cmake rename to cmake/Modules/FindVOLKGNSSSDR.cmake index 6225f38a0..cd5cac918 100644 --- a/cmake/Modules/FindVolkGnssSdr.cmake +++ b/cmake/Modules/FindVOLKGNSSSDR.cmake @@ -19,10 +19,10 @@ # Find VOLK (Vector-Optimized Library of Kernels) GNSS-SDR library ######################################################################## -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_VOLK_GNSSSDR volk_gnsssdr) +include(FindPkgConfig) +pkg_check_modules(PC_VOLK_GNSSSDR volk_gnsssdr) -FIND_PATH( +find_path( VOLK_GNSSSDR_INCLUDE_DIRS NAMES volk_gnsssdr/volk_gnsssdr.h HINTS $ENV{VOLK_GNSSSDR_DIR}/include @@ -32,7 +32,7 @@ FIND_PATH( ${GNURADIO_INSTALL_PREFIX}/include ) -FIND_LIBRARY( +find_library( VOLK_GNSSSDR_LIBRARIES NAMES volk_gnsssdr HINTS $ENV{VOLK_GNSSSDR_DIR}/lib @@ -44,6 +44,6 @@ FIND_LIBRARY( ${GNURADIO_INSTALL_PREFIX}/lib ) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(VOLK_GNSSSDR DEFAULT_MSG VOLK_GNSSSDR_LIBRARIES VOLK_GNSSSDR_INCLUDE_DIRS) -MARK_AS_ADVANCED(VOLK_GNSSSDR_LIBRARIES VOLK_GNSSSDR_INCLUDE_DIRS) \ No newline at end of file +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(VOLKGNSSSDR DEFAULT_MSG VOLK_GNSSSDR_LIBRARIES VOLK_GNSSSDR_INCLUDE_DIRS) +mark_as_advanced(VOLK_GNSSSDR_LIBRARIES VOLK_GNSSSDR_INCLUDE_DIRS) diff --git a/cmake/Modules/GnsssdrBuildTypes.cmake b/cmake/Modules/GnsssdrBuildTypes.cmake new file mode 100644 index 000000000..a80cd0c6b --- /dev/null +++ b/cmake/Modules/GnsssdrBuildTypes.cmake @@ -0,0 +1,219 @@ +# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors) +# +# This file is part of GNSS-SDR. +# +# GNSS-SDR is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GNSS-SDR is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNSS-SDR. If not, see . + +if(DEFINED __INCLUDED_GNSSSDR_BUILD_TYPES_CMAKE) + return() +endif() +set(__INCLUDED_GNSSSDR_BUILD_TYPES_CMAKE TRUE) + +# Standard CMake Build Types and their basic CFLAGS: +# - None: nothing set +# - Debug: -O2 -g +# - Release: -O3 +# - RelWithDebInfo: -O3 -g +# - MinSizeRel: -Os + +# Additional Build Types, defined below: +# - NoOptWithASM: -O0 -g -save-temps +# - O2WithASM: -O2 -g -save-temps +# - O3WithASM: -O3 -g -save-temps + +# Defines the list of acceptable cmake build types. When adding a new +# build type below, make sure to add it to this list. +list(APPEND AVAIL_BUILDTYPES + None Debug Release RelWithDebInfo MinSizeRel + Coverage NoOptWithASM O2WithASM O3WithASM ASAN +) + +######################################################################## +# GNSSSDR_CHECK_BUILD_TYPE(build type) +# +# Use this to check that the build type set in CMAKE_BUILD_TYPE on the +# commandline is one of the valid build types used by this project. It +# checks the value set in the cmake interface against the list of +# known build types in AVAIL_BUILDTYPES. If the build type is found, +# the function exits immediately. If nothing is found by the end of +# checking all available build types, we exit with an error and list +# the avialable build types. +######################################################################## +function(GNSSSDR_CHECK_BUILD_TYPE settype) + string(TOUPPER ${settype} _settype) + foreach(btype ${AVAIL_BUILDTYPES}) + string(TOUPPER ${btype} _btype) + if(${_settype} STREQUAL ${_btype}) + return() # found it; exit cleanly + endif() + endforeach() + # Build type not found; error out + message(FATAL_ERROR "Build type '${settype}' not valid, must be one of: ${AVAIL_BUILDTYPES}") +endfunction() + + +######################################################################## +# For GCC and Clang, we can set a build type: +# +# -DCMAKE_BUILD_TYPE=Coverage +# +# This type uses no optimization (-O0), outputs debug symbols (-g) and +# outputs all intermediary files the build system produces, including +# all assembly (.s) files. Look in the build directory for these +# files. +# NOTE: This is not defined on Windows systems. +######################################################################## +if(NOT WIN32) + set(CMAKE_CXX_FLAGS_COVERAGE "-Wall -pedantic -pthread -g -O0 -fprofile-arcs -ftest-coverage" CACHE STRING + "Flags used by the C++ compiler during Coverage builds." FORCE) + set(CMAKE_C_FLAGS_COVERAGE "-Wall -pedantic -pthread -g -O0 -fprofile-arcs -ftest-coverage" CACHE STRING + "Flags used by the C compiler during Coverage builds." FORCE) + set(CMAKE_EXE_LINKER_FLAGS_COVERAGE + "-W" CACHE STRING + "Flags used for linking binaries during Coverage builds." FORCE) + set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE + "-W" CACHE STRING + "Flags used by the shared lib linker during Coverage builds." FORCE) + + mark_as_advanced( + CMAKE_CXX_FLAGS_COVERAGE + CMAKE_C_FLAGS_COVERAGE + CMAKE_EXE_LINKER_FLAGS_COVERAGE + CMAKE_SHARED_LINKER_FLAGS_COVERAGE) +endif() + + +######################################################################## +# For GCC and Clang, we can set a build type: +# +# -DCMAKE_BUILD_TYPE=NoOptWithASM +# +# This type uses no optimization (-O0), outputs debug symbols (-g) and +# outputs all intermediary files the build system produces, including +# all assembly (.s) files. Look in the build directory for these +# files. +# NOTE: This is not defined on Windows systems. +######################################################################## +if(NOT WIN32) + set(CMAKE_CXX_FLAGS_NOOPTWITHASM "-Wall -save-temps -g -O0" CACHE STRING + "Flags used by the C++ compiler during NoOptWithASM builds." FORCE) + set(CMAKE_C_FLAGS_NOOPTWITHASM "-Wall -save-temps -g -O0" CACHE STRING + "Flags used by the C compiler during NoOptWithASM builds." FORCE) + set(CMAKE_EXE_LINKER_FLAGS_NOOPTWITHASM + "-W" CACHE STRING + "Flags used for linking binaries during NoOptWithASM builds." FORCE) + set(CMAKE_SHARED_LINKER_FLAGS_NOOPTWITHASM + "-W" CACHE STRING + "Flags used by the shared lib linker during NoOptWithASM builds." FORCE) + + mark_as_advanced( + CMAKE_CXX_FLAGS_NOOPTWITHASM + CMAKE_C_FLAGS_NOOPTWITHASM + CMAKE_EXE_LINKER_FLAGS_NOOPTWITHASM + CMAKE_SHARED_LINKER_FLAGS_NOOPTWITHASM) +endif() + + + +######################################################################## +# For GCC and Clang, we can set a build type: +# +# -DCMAKE_BUILD_TYPE=O2WithASM +# +# This type uses level 2 optimization (-O2), outputs debug symbols +# (-g) and outputs all intermediary files the build system produces, +# including all assembly (.s) files. Look in the build directory for +# these files. +# NOTE: This is not defined on Windows systems. +######################################################################## + +if(NOT WIN32) + set(CMAKE_CXX_FLAGS_O2WITHASM "-Wall -save-temps -g -O2" CACHE STRING + "Flags used by the C++ compiler during O2WithASM builds." FORCE) + set(CMAKE_C_FLAGS_O2WITHASM "-Wall -save-temps -g -O2" CACHE STRING + "Flags used by the C compiler during O2WithASM builds." FORCE) + set(CMAKE_EXE_LINKER_FLAGS_O2WITHASM + "-W" CACHE STRING + "Flags used for linking binaries during O2WithASM builds." FORCE) + set(CMAKE_SHARED_LINKER_FLAGS_O2WITHASM + "-W" CACHE STRING + "Flags used by the shared lib linker during O2WithASM builds." FORCE) + + mark_as_advanced( + CMAKE_CXX_FLAGS_O2WITHASM + CMAKE_C_FLAGS_O2WITHASM + CMAKE_EXE_LINKER_FLAGS_O2WITHASM + CMAKE_SHARED_LINKER_FLAGS_O2WITHASM) +endif() + + +######################################################################## +# For GCC and Clang, we can set a build type: +# +# -DCMAKE_BUILD_TYPE=O3WithASM +# +# This type uses level 3 optimization (-O3), outputs debug symbols +# (-g) and outputs all intermediary files the build system produces, +# including all assembly (.s) files. Look in the build directory for +# these files. +# NOTE: This is not defined on Windows systems. +######################################################################## + +if(NOT WIN32) + set(CMAKE_CXX_FLAGS_O3WITHASM "-Wall -save-temps -g -O3" CACHE STRING + "Flags used by the C++ compiler during O3WithASM builds." FORCE) + set(CMAKE_C_FLAGS_O3WITHASM "-Wall -save-temps -g -O3" CACHE STRING + "Flags used by the C compiler during O3WithASM builds." FORCE) + set(CMAKE_EXE_LINKER_FLAGS_O3WITHASM + "-W" CACHE STRING + "Flags used for linking binaries during O3WithASM builds." FORCE) + set(CMAKE_SHARED_LINKER_FLAGS_O3WITHASM + "-W" CACHE STRING + "Flags used by the shared lib linker during O3WithASM builds." FORCE) + + mark_as_advanced( + CMAKE_CXX_FLAGS_O3WITHASM + CMAKE_C_FLAGS_O3WITHASM + CMAKE_EXE_LINKER_FLAGS_O3WITHASM + CMAKE_SHARED_LINKER_FLAGS_O3WITHASM) +endif() + + +######################################################################## +# For GCC and Clang, we can set a build type: +# +# -DCMAKE_BUILD_TYPE=ASAN +# +# This type creates an address sanitized build (-fsanitize=address) +# and defaults to the DebugParanoid linker flags. +# NOTE: This is not defined on Windows systems. +######################################################################## +if(NOT WIN32) + set(CMAKE_CXX_FLAGS_ASAN "-Wall -Wextra -g -O2 -fsanitize=address -fno-omit-frame-pointer" CACHE STRING + "Flags used by the C++ compiler during Address Sanitized builds." FORCE) + set(CMAKE_C_FLAGS_ASAN "-Wall -Wextra -g -O2 -fsanitize=address -fno-omit-frame-pointer" CACHE STRING + "Flags used by the C compiler during Address Sanitized builds." FORCE) + set(CMAKE_EXE_LINKER_FLAGS_ASAN + "-W" CACHE STRING + "Flags used for linking binaries during Address Sanitized builds." FORCE) + set(CMAKE_SHARED_LINKER_FLAGS_ASAN + "-W" CACHE STRING + "Flags used by the shared lib linker during Address Sanitized builds." FORCE) + + mark_as_advanced( + CMAKE_CXX_FLAGS_ASAN + CMAKE_C_FLAGS_ASAN + CMAKE_EXE_LINKER_FLAGS_ASAN + CMAKE_SHARED_LINKER_ASAN) +endif() diff --git a/cmake/Modules/SetupPython.cmake b/cmake/Modules/SetupPython.cmake index eb4e7a55d..f3d59c900 100644 --- a/cmake/Modules/SetupPython.cmake +++ b/cmake/Modules/SetupPython.cmake @@ -15,54 +15,6 @@ # You should have received a copy of the GNU General Public License # along with GNSS-SDR. If not, see . -######################################################################## -# Setup the python interpreter: -# This allows the user to specify a specific interpreter, -# or finds the interpreter via the built-in cmake module. -######################################################################## -#this allows the user to override PYTHON_EXECUTABLE -if(PYTHON_EXECUTABLE) - - set(PYTHONINTERP_FOUND TRUE) - -#otherwise if not set, try to automatically find it -else(PYTHON_EXECUTABLE) - - #use the built-in find script - set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6) - find_package(PythonInterp 2) - - #and if that fails use the find program routine - if(NOT PYTHONINTERP_FOUND) - find_program(PYTHON_EXECUTABLE NAMES python python2 python2.7 python3) - if(PYTHON_EXECUTABLE) - set(PYTHONINTERP_FOUND TRUE) - endif(PYTHON_EXECUTABLE) - endif(NOT PYTHONINTERP_FOUND) - -endif(PYTHON_EXECUTABLE) - -if (CMAKE_CROSSCOMPILING) - set(QA_PYTHON_EXECUTABLE "/usr/bin/python") -else (CMAKE_CROSSCOMPILING) - set(QA_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE}) -endif(CMAKE_CROSSCOMPILING) - -#make the path to the executable appear in the cmake gui -set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter") -set(QA_PYTHON_EXECUTABLE ${QA_PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter for QA tests") - -#make sure we can use -B with python (introduced in 2.6) -if(PYTHON_EXECUTABLE) - execute_process( - COMMAND ${PYTHON_EXECUTABLE} -B -c "" - OUTPUT_QUIET ERROR_QUIET - RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT - ) - if(PYTHON_HAS_DASH_B_RESULT EQUAL 0) - set(PYTHON_DASH_B "-B") - endif() -endif(PYTHON_EXECUTABLE) ######################################################################## # Check for the existence of a python module: @@ -71,25 +23,97 @@ endif(PYTHON_EXECUTABLE) # - cmd an additional command to run # - have the result variable to set ######################################################################## -macro(GNSSSDR_PYTHON_CHECK_MODULE desc mod cmd have) - message(STATUS "Python checking for ${desc}") +macro(GNSSSDR_PYTHON_CHECK_MODULE_RAW desc python_code have) execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c " -######################################### -try: import ${mod} -except: - try: ${mod} - except: exit(-1) -try: assert ${cmd} -except: exit(-1) -#########################################" - RESULT_VARIABLE ${have} + COMMAND ${PYTHON_EXECUTABLE} -c "${python_code}" + OUTPUT_QUIET ERROR_QUIET + RESULT_VARIABLE return_code ) - if(${have} EQUAL 0) + if(return_code EQUAL 0) message(STATUS "Python checking for ${desc} - found") set(${have} TRUE) - else(${have} EQUAL 0) + else() message(STATUS "Python checking for ${desc} - not found") set(${have} FALSE) - endif(${have} EQUAL 0) -endmacro(GNSSSDR_PYTHON_CHECK_MODULE) + endif() +endmacro() + +macro(GNSSSDR_PYTHON_CHECK_MODULE desc mod cmd have) + gnsssdr_python_check_module_raw( + "${desc}" " +######################################### +try: + import ${mod} + assert ${cmd} +except (ImportError, AssertionError): exit(-1) +except: pass +#########################################" + "${have}") +endmacro() + + +######################################################################## +# Setup the python interpreter: +# This allows the user to specify a specific interpreter, +# or finds the interpreter via the built-in cmake module. +######################################################################## + +if(CMAKE_VERSION VERSION_LESS 3.12) + if(PYTHON_EXECUTABLE) + message(STATUS "User set python executable ${PYTHON_EXECUTABLE}") + string(FIND "${PYTHON_EXECUTABLE}" "python3" IS_PYTHON3) + if(IS_PYTHON3 EQUAL -1) + find_package(PythonInterp ${GNSSSDR_PYTHON_MIN_VERSION} REQUIRED) + else() + find_package(PythonInterp ${GNSSSDR_PYTHON3_MIN_VERSION} REQUIRED) + endif() + gnsssdr_python_check_module("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND) + gnsssdr_python_check_module("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND) + gnsssdr_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) + else() + message(STATUS "PYTHON_EXECUTABLE not set - trying by default python2") + message(STATUS "Use -DPYTHON_EXECUTABLE=/path/to/python3 to build for python3.") + find_package(PythonInterp ${GNSSSDR_PYTHON_MIN_VERSION}) + if(NOT PYTHONINTERP_FOUND) + message(STATUS "python2 not found - trying with python3") + find_package(PythonInterp ${GNSSSDR_PYTHON3_MIN_VERSION} REQUIRED) + endif() + gnsssdr_python_check_module("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND) + gnsssdr_python_check_module("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND) + gnsssdr_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) + endif() + find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT) +else() + find_package(Python3 COMPONENTS Interpreter) + if(Python3_FOUND) + set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) + set(PYTHON_VERSION_MAJOR ${Python3_VERSION_MAJOR}) + gnsssdr_python_check_module("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND) + gnsssdr_python_check_module("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND) + gnsssdr_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) + endif() + if(NOT Python3_FOUND OR NOT MAKO_FOUND OR NOT SIX_FOUND) + find_package(Python2 COMPONENTS Interpreter) + if(Python2_FOUND) + set(PYTHON_EXECUTABLE ${Python2_EXECUTABLE}) + set(PYTHON_VERSION_MAJOR ${Python2_VERSION_MAJOR}) + gnsssdr_python_check_module("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND) + gnsssdr_python_check_module("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND) + gnsssdr_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) + endif() + endif() +endif() + +if(${PYTHON_VERSION_MAJOR} VERSION_EQUAL 3) + set(PYTHON3 TRUE) +endif() + +if(CMAKE_CROSSCOMPILING) + set(QA_PYTHON_EXECUTABLE "/usr/bin/python") +else() + set(QA_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE}) +endif() + +# make the path to the executable appear in the cmake gui +set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter") +set(QA_PYTHON_EXECUTABLE ${QA_PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter for QA tests") diff --git a/cmake/Modules/TestForARM.cmake b/cmake/Modules/TestForARM.cmake index 26c0a1874..05a5c172e 100644 --- a/cmake/Modules/TestForARM.cmake +++ b/cmake/Modules/TestForARM.cmake @@ -16,14 +16,14 @@ # along with GNSS-SDR. If not, see . ############################################################################## -# check if the compiler defines the architecture as ARM and set the +# check if the compiler defines the architecture as ARM and set the # version, if found. # # - Anthony Arnold ############################################################################## -if (__TEST_FOR_ARM_INCLUDED) - return () +if(__TEST_FOR_ARM_INCLUDED) + return() endif() set(__TEST_FOR_ARM_INCLUDED TRUE) @@ -31,27 +31,27 @@ set(__TEST_FOR_ARM_INCLUDED TRUE) # output variable if found. function(check_arm_version ppdef input_string version output_var) string(REGEX MATCH "${ppdef}" _VERSION_MATCH "${input_string}") - if (NOT _VERSION_MATCH STREQUAL "") + if(NOT _VERSION_MATCH STREQUAL "") set(${output_var} "${version}" PARENT_SCOPE) - endif(NOT _VERSION_MATCH STREQUAL "") + endif() endfunction() message(STATUS "Checking for ARM") -set (IS_ARM NO) -set (ARM_VERSION "") +set(IS_ARM NO) +set(ARM_VERSION "") -if (CMAKE_COMPILER_IS_GNUCXX) +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") execute_process(COMMAND echo "int main(){}" COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -dM -E - OUTPUT_VARIABLE TEST_FOR_ARM_RESULTS) string(REGEX MATCH "__arm" ARM_FOUND "${TEST_FOR_ARM_RESULTS}") if(ARM_FOUND STREQUAL "") - string(REGEX MATCH "__aarch64" ARM_FOUND "${TEST_FOR_ARM_RESULTS}") - endif(ARM_FOUND STREQUAL "") + string(REGEX MATCH "__aarch64" ARM_FOUND "${TEST_FOR_ARM_RESULTS}") + endif() - if (NOT ARM_FOUND STREQUAL "") + if(NOT ARM_FOUND STREQUAL "") set(IS_ARM YES) message(STATUS "ARM system detected") @@ -83,22 +83,21 @@ if (CMAKE_COMPILER_IS_GNUCXX) check_arm_version("__ARM_ARCH_8A" ${TEST_FOR_ARM_RESULTS} "armv8-a" ARM_VERSION) # anything else just define as arm - if (ARM_VERSION STREQUAL "") + if(ARM_VERSION STREQUAL "") message(STATUS "Couldn't detect ARM version. Setting to 'arm'") set(ARM_VERSION "arm") - else (ARM_VERSION STREQUAL "") + else() message(STATUS "ARM version ${ARM_VERSION} detected") - endif (ARM_VERSION STREQUAL "") - - else (NOT ARM_FOUND STREQUAL "") - message(STATUS "System is not ARM") - endif(NOT ARM_FOUND STREQUAL "") + endif() + else() + message(STATUS "System is not ARM") + endif() -else (CMAKE_COMPILE_IS_GNUCXX) +else() # TODO: Other compilers message(STATUS "Not detecting ARM on non-GNUCXX compiler. Defaulting to false") message(STATUS "If you are compiling for ARM, set IS_ARM=ON manually") -endif(CMAKE_COMPILER_IS_GNUCXX) +endif() set(IS_ARM ${IS_ARM} CACHE BOOL "Compiling for ARM") set(ARM_VERSION ${ARM_VERSION} CACHE STRING "ARM version") diff --git a/cmake/Modules/TestForSSE.cmake b/cmake/Modules/TestForSSE.cmake index 135a434ef..23b2d16a8 100644 --- a/cmake/Modules/TestForSSE.cmake +++ b/cmake/Modules/TestForSSE.cmake @@ -22,21 +22,20 @@ # - Anthony Arnold ############################################################################### - -function (test_for_sse h_file result_var name) - if (NOT DEFINED ${result_var}) +function(test_for_sse h_file result_var name) + if(NOT DEFINED ${result_var}) execute_process(COMMAND echo "#include <${h_file}>" - COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -c -x c++ - - RESULT_VARIABLE COMPILE_RESULT - OUTPUT_QUIET ERROR_QUIET) + COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -c -x c++ - + RESULT_VARIABLE COMPILE_RESULT + OUTPUT_QUIET ERROR_QUIET) set(detected 0) - if (COMPILE_RESULT EQUAL 0) + if(COMPILE_RESULT EQUAL 0) message(STATUS "Detected ${name}") set(detected 1) - endif(COMPILE_RESULT EQUAL 0) + endif() set(${result_var} ${detected} CACHE INTERNAL "${name} Available") - endif (NOT DEFINED ${result_var}) -endfunction(test_for_sse) + endif() +endfunction() message(STATUS "Testing for SIMD extensions") diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in index 5d4ab76f7..9b3887185 100644 --- a/cmake/cmake_uninstall.cmake.in +++ b/cmake/cmake_uninstall.cmake.in @@ -24,10 +24,10 @@ string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - exec_program( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + execute_process( + COMMAND @CMAKE_COMMAND@ -E remove \"$ENV{DESTDIR}${file}\" OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval + RESULT_VARIABLE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") diff --git a/conf/front-end-cal.conf b/conf/front-end-cal.conf index 16bf70407..8a2b55cb5 100644 --- a/conf/front-end-cal.conf +++ b/conf/front-end-cal.conf @@ -39,7 +39,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=217 -GNSS-SDR.SUPL_MNS=7 +GNSS-SDR.SUPL_MNC=7 GNSS-SDR.SUPL_LAC=861 GNSS-SDR.SUPL_CI=40184 diff --git a/conf/gnss-sdr-kalman-bayes.conf b/conf/gnss-sdr-kalman-bayes.conf new file mode 100644 index 000000000..051d080de --- /dev/null +++ b/conf/gnss-sdr-kalman-bayes.conf @@ -0,0 +1,63 @@ +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second]. +GNSS-SDR.internal_fs_sps=2000000 +GNSS-SDR.internal_fs_hz=2000000 + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource.implementation=File_Signal_Source +SignalSource.filename=/home/glamountain/gnss-sdr/data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat +SignalSource.item_type=ishort +SignalSource.sampling_frequency=4000000 +SignalSource.freq=1575420000 +SignalSource.samples=0 + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner.implementation=Signal_Conditioner +DataTypeAdapter.implementation=Ishort_To_Complex +InputFilter.implementation=Pass_Through +InputFilter.item_type=gr_complex +Resampler.implementation=Direct_Resampler +Resampler.sample_freq_in=4000000 +Resampler.sample_freq_out=2000000 +Resampler.item_type=gr_complex + +;######### CHANNELS GLOBAL CONFIG ############ +Channels_1C.count=8 +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.threshold=0.008 +Acquisition_1C.doppler_max=10000 +Acquisition_1C.doppler_step=250 +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=../data/kalman/acq_dump + +;######### TRACKING GLOBAL CONFIG ############ +Tracking_1C.implementation=GPS_L1_CA_KF_Tracking +Tracking_1C.item_type=gr_complex +Tracking_1C.pll_bw_hz=40.0; +Tracking_1C.dll_bw_hz=4.0; +Tracking_1C.order=3; +Tracking_1C.dump=true +Tracking_1C.dump_filename=../data/kalman/epl_tracking_ch_ +Tracking_1C.bce_run = true; +Tracking_1C.p_transient = 0; +Tracking_1C.s_transient = 100; + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=GPS_L1_CA_Observables + +;######### PVT CONFIG ############ +PVT.implementation=GPS_L1_CA_PVT +PVT.averaging_depth=100 +PVT.flag_averaging=true +PVT.output_rate_ms=10 +PVT.display_rate_ms=500 diff --git a/conf/gnss-sdr.conf b/conf/gnss-sdr.conf index 4c9ae11a4..353bdb2fd 100644 --- a/conf/gnss-sdr.conf +++ b/conf/gnss-sdr.conf @@ -23,7 +23,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf b/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf index ba96a533e..f437366bf 100644 --- a/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf @@ -24,7 +24,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_USRP_realtime.conf b/conf/gnss-sdr_GPS_L1_USRP_realtime.conf index b432eb6b2..323feec08 100644 --- a/conf/gnss-sdr_GPS_L1_USRP_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_USRP_realtime.conf @@ -23,7 +23,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf index 3de8486d8..b2d0604bb 100644 --- a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf @@ -21,7 +21,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_nsr.conf b/conf/gnss-sdr_GPS_L1_nsr.conf index 49ae18b56..4b0b05ae2 100644 --- a/conf/gnss-sdr_GPS_L1_nsr.conf +++ b/conf/gnss-sdr_GPS_L1_nsr.conf @@ -25,7 +25,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_nsr_kf.conf b/conf/gnss-sdr_GPS_L1_nsr_kf.conf new file mode 100644 index 000000000..d2a84cd9f --- /dev/null +++ b/conf/gnss-sdr_GPS_L1_nsr_kf.conf @@ -0,0 +1,211 @@ +; Default configuration file +; 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=6826700 +GNSS-SDR.internal_fs_sps=2560000 +;GNSS-SDR.internal_fs_sps=4096000 +;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) +SignalSource.implementation=Nsr_File_Signal_Source + +;#filename: path to file with the captured GNSS signal samples to be processed +SignalSource.filename=/home/javier/signals/ifen/E1L1_FE0_Band0.stream ; <- PUT YOUR FILE HERE + +;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. +SignalSource.item_type=byte + +;#sampling_frequency: Original Signal sampling frequency in [Hz] +SignalSource.sampling_frequency=20480000 + +;#freq: RF front-end center frequency in [Hz] +SignalSource.freq=1575420000 + +;#samples: Number of samples to be processed. Notice that 0 indicates the entire file. +SignalSource.samples=0 + +;#repeat: Repeat the processing file. Disable this option in this version +SignalSource.repeat=false + +;#dump: Dump the Signal source data to a file. Disable this option in this version +SignalSource.dump=false + +SignalSource.dump_filename=../data/signal_source.dat + + +;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. +; it helps to not overload the CPU, but the processing time will be longer. +SignalSource.enable_throttle_control=false + + +;######### SIGNAL_CONDITIONER CONFIG ############ +;## It holds blocks to change data type, filter and resample input data. + +;#implementation: Use [Pass_Through] or [Signal_Conditioner] +;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks +;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks +SignalConditioner.implementation=Signal_Conditioner + +;######### DATA_TYPE_ADAPTER CONFIG ############ +;## Changes the type of input data. +;#implementation: [Pass_Through] disables this block +DataTypeAdapter.implementation=Pass_Through +DataTypeAdapter.item_type=float + +;######### INPUT_FILTER CONFIG ############ +;## Filter the input data. Can be combined with frequency translation for IF signals + +;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter] +;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation +;# that shifts IF down to zero Hz. + +InputFilter.implementation=Freq_Xlating_Fir_Filter + +;#dump: Dump the filtered data to a file. +InputFilter.dump=false + +;#dump_filename: Log path and filename. +InputFilter.dump_filename=../data/input_filter.dat + +;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. +;#These options are based on parameters of gnuradio's function: gr_remez. +;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse +;#reponse given a set of band edges, the desired reponse on those bands, +;#and the weight given to the error in those bands. + +;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. +InputFilter.input_item_type=float + +;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version. +InputFilter.output_item_type=gr_complex + +;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version. +InputFilter.taps_item_type=float + +;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time +InputFilter.number_of_taps=5 + +;#number_of _bands: Number of frequency bands in the filter. +InputFilter.number_of_bands=2 + +;#bands: frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...]. +;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2) +;#The number of band_begin and band_end elements must match the number of bands + +InputFilter.band1_begin=0.0 +InputFilter.band1_end=0.45 +InputFilter.band2_begin=0.55 +InputFilter.band2_end=1.0 + +;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...]. +;#The number of ampl_begin and ampl_end elements must match the number of bands + +InputFilter.ampl1_begin=1.0 +InputFilter.ampl1_end=1.0 +InputFilter.ampl2_begin=0.0 +InputFilter.ampl2_end=0.0 + +;#band_error: weighting applied to each band (usually 1). +;#The number of band_error elements must match the number of bands +InputFilter.band1_error=1.0 +InputFilter.band2_error=1.0 + +;#filter_type: one of "bandpass", "hilbert" or "differentiator" +InputFilter.filter_type=bandpass + +;#grid_density: determines how accurately the filter will be constructed. +;The minimum value is 16; higher values are slower to compute the filter. +InputFilter.grid_density=16 + +;# Original sampling frequency stored in the signal file +InputFilter.sampling_frequency=20480000 + +;#The following options are used only in Freq_Xlating_Fir_Filter implementation. +;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz + +InputFilter.IF=5499998.47412109 + +;# Decimation factor after the frequency tranaslating block +InputFilter.decimation_factor=8 + + +;######### RESAMPLER CONFIG ############ +;## Resamples the input data. + +;#implementation: Use [Pass_Through] or [Direct_Resampler] +;#[Pass_Through] disables this block +;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation +Resampler.implementation=Pass_Through + +;######### CHANNELS GLOBAL CONFIG ############ +;#count: Number of available GPS satellite channels. +Channels_1C.count=8 +Channels.in_acquisition=1 +#Channel.signal=1C + + +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat +Acquisition_1C.item_type=gr_complex +Acquisition_1C.if=0 +Acquisition_1C.sampled_ms=1 +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +;#use_CFAR_algorithm: If enabled, acquisition estimates the input signal power to implement CFAR detection algorithms +;#notice that this affects the Acquisition threshold range! +Acquisition_1C.use_CFAR_algorithm=false; +;#threshold: Acquisition threshold +Acquisition_1C.threshold=10 +;Acquisition_1C.pfa=0.01 +Acquisition_1C.doppler_max=5000 +Acquisition_1C.doppler_step=100 + + +;######### TRACKING GPS CONFIG ############ +Tracking_1C.implementation=GPS_L1_CA_KF_Tracking +Tracking_1C.item_type=gr_complex +Tracking_1C.if=0 +Tracking_1C.dump=true +Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.pll_bw_hz=15.0; +Tracking_1C.dll_bw_hz=2.0; +Tracking_1C.order=3; + + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder +TelemetryDecoder_1C.dump=false +TelemetryDecoder_1C.decimation_factor=1; + +;######### OBSERVABLES CONFIG ############ +;#implementation: +Observables.implementation=Hybrid_Observables + +;#dump: Enable or disable the Observables internal binary data file logging [true] or [false] +Observables.dump=false + +;#dump_filename: Log path and filename. +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=100 +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.flag_rtcm_server=false +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.dump=true diff --git a/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf b/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf index 82d382a27..dfe6e331a 100644 --- a/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf +++ b/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf @@ -25,7 +25,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf index fa8996dc7..872f56bf4 100644 --- a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf @@ -24,7 +24,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf b/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf index e186f1da7..618341f48 100644 --- a/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf +++ b/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf b/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf index 91b952ad0..4b91a9344 100644 --- a/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf @@ -24,7 +24,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5_1C +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf b/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf index f3252578b..2cec70e8c 100644 --- a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf @@ -24,7 +24,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf b/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf index 84753bee7..b58fc57ba 100644 --- a/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf +++ b/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf b/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf index 6d61e063b..cce644be9 100644 --- a/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf +++ b/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf @@ -23,7 +23,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf b/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf index 55a84a13e..49868f37a 100644 --- a/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf +++ b/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf @@ -23,7 +23,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_Galileo_E5a.conf b/conf/gnss-sdr_Galileo_E5a.conf index c4df4139f..81dddd613 100644 --- a/conf/gnss-sdr_Galileo_E5a.conf +++ b/conf/gnss-sdr_Galileo_E5a.conf @@ -22,7 +22,7 @@ GNSS-SDR.internal_fs_sps=32000000 ;GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com ;GNSS-SDR.SUPL_gps_acquisition_port=7275 ;GNSS-SDR.SUPL_MCC=244 -;GNSS-SDR.SUPL_MNS=5 +;GNSS-SDR.SUPL_MNC=5 ;GNSS-SDR.SUPL_LAC=0x59e2 ;GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf b/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf index f66079cb4..26d01617d 100644 --- a/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf +++ b/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf @@ -21,7 +21,7 @@ GNSS-SDR.internal_fs_sps=50000000 ;GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com ;GNSS-SDR.SUPL_gps_acquisition_port=7275 ;GNSS-SDR.SUPL_MCC=244 -;GNSS-SDR.SUPL_MNS=5 +;GNSS-SDR.SUPL_MNC=5 ;GNSS-SDR.SUPL_LAC=0x59e2 ;GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_Hybrid_ishort.conf b/conf/gnss-sdr_Hybrid_ishort.conf index 55a70b7a2..c634009f3 100644 --- a/conf/gnss-sdr_Hybrid_ishort.conf +++ b/conf/gnss-sdr_Hybrid_ishort.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf index 7b978be5b..c395a5f3c 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf @@ -21,7 +21,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf index bb5d4327e..134bfa457 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf index 2ef22b956..9552ebabe 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf index 1d7fa6097..f1e5d264b 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf index 2072f8c7d..201fff1ab 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf index 3094d8c97..48eabee34 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf index d27d98d62..7c19ebc2c 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf b/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf index 411a712ab..63746aea4 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf +++ b/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_1C_ephemeris_port=7275 GNSS-SDR.SUPL_1C_acquisition_server=supl.google.com GNSS-SDR.SUPL_1C_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf index fb6fae1c2..9c2a86def 100644 --- a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf +++ b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf index 6d62e65b3..a52349af1 100644 --- a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf +++ b/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf b/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf index 50e49f2e9..a3e23b001 100644 --- a/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf +++ b/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf @@ -22,7 +22,7 @@ GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 GNSS-SDR.SUPL_MCC=244 -GNSS-SDR.SUPL_MNS=5 +GNSS-SDR.SUPL_MNC=5 GNSS-SDR.SUPL_LAC=0x59e2 GNSS-SDR.SUPL_CI=0x31b0 diff --git a/docs/changelog b/docs/changelog index 47ba133b8..2c5d26ce0 100644 --- a/docs/changelog +++ b/docs/changelog @@ -16,6 +16,7 @@ This release has several improvements in different dimensions, addition of new f - Redesign of the time counter for enhanced continuity. - Improved flow graph in multisystem configurations: the receiver does not get stalled anymore if no signal is found from the first system. - Improved acquisition and tracking sensitivity. +- Added mechanisms for Assisted GNSS, thus shortening the Time-To-First-Fix. Provision of data via XML files or via SUPL v1.0. Documented at https://gnss-sdr.org/docs/sp-blocks/global-parameters/ - Other minor bug fixes. @@ -27,6 +28,7 @@ This release has several improvements in different dimensions, addition of new f - 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. - 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. +- Output printers can be shut down, with some savings in memory and storage requirements. - A number of code optimizations here and there. @@ -34,7 +36,8 @@ This release has several improvements in different dimensions, addition of new f - A number of new parameters have been exposed to the configuration system. - Possibility to choose Pilot or Data component for tracking of GPS L5 and Galileo E5a signals. -- Enabled extended coherent integration times. +- Enabled extended coherent integration times for signal tracking. +- Configurable coherent and/or non-coherent signal acquisition. - Some configuration parameters can now be overridden by commandline flags for easier use in scripts. @@ -48,11 +51,15 @@ This release has several improvements in different dimensions, addition of new f - 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 binary format, readable from Matlab/Octave and from Python via h5py. +- Intermediate results are now saved in MAT-file format (.mat), readable from Matlab/Octave and from Python via h5py. - Added the GPX output format. -- Fixed a bug in the format of NMEA sentences when latitude or longitude minutes were >10. +- Improvements in the generation of KML files. +- Improvements in the NMEA output. The receiver can produce GPGGA, GPRMC, GPGSA, GPGSV, GAGSA and GAGSV sentences. - Improvements in the RTCM server stability. - Improvements in the correctness of generated RINEX files. +- The receiver can read and make use of Galileo almanac XML files published by the European GNSS Service Centre at 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 usable for Assisted GNSS. Only available building from source. See https://github.com/gnss-sdr/gnss-sdr/tree/next/src/utils/rinex2assist ### Improvements in Maintainability: @@ -64,6 +71,8 @@ This release has several improvements in different dimensions, addition of new f - Improvement in C++ usage: The override special identifier is now used when overriding a virtual function. This helps the compiler to check for type changes in the base class, making the detection of errors easier. - Improvement in C++ usage: A number of unused includes have been removed. Order of includes set to: local (in-source) headers, then library headers, then system headers. This helps to detect missing includes. - Improvement in C++ usage: Enhanced const correctness. Misuses of those variables are detected by the compiler. +- Applied some style rules to CMake scripts. +- Minimal versions of dependencies identified and detected. ### Improvements in Portability: @@ -76,15 +85,16 @@ This release has several improvements in different dimensions, addition of new f - 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. -- Ready for GNU Radio 3.8 C++ API (as per current next branch of GNU Radio upstream repository). +- Ready for GNU Radio 3.8 C++ API (as per current master branch of GNU Radio upstream repository). - Improved detection of required and optional dependencies in many GNU/Linux distributions and processor architectures. -- Improvement in C++ usage: The library has been replaced by the more modern and portable . +- Improvement in C++ usage: The library has been replaced by the more modern and portable (except for the interaction with RTKLIB). - Improvement in C++ usage: The library has been replaced by the more modern and portable for file handling. - Improvement in C++ usage: C++ libraries preferred over C libraries (e.g., instead of , instead of ). - Fixes required by Debian packaging. - Fixes required by Macports packaging. - A downside in portability: BLAS and LAPACK libraries are now required even in ARM devices. - A downside in portability: the matio library >= 1.5.3 is a new required dependency. If not found, it is downloaded and built automatically at building time, but this requires libtool, automake and hdf5 already installed in the system. +- A downside in portability: the PugiXML library is a new required dependency. If not found, it is downloaded and built automatically at building time. ### Improvements in Reliability: @@ -93,6 +103,7 @@ This release has several improvements in different dimensions, addition of new f - Improved flow graph stabiliy. - Introduction of high-integrity C++ practices into the source code and included in the coding style guide. See https://gnss-sdr.org/coding-style/ - 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 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. @@ -122,9 +133,10 @@ This release has several improvements in different dimensions, addition of new f - All Observables block implementations have been merged into a single 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 warning is provided to the user. -- Updated and improved documentation of processing blocks at https://gnss-sdr.org/docs/sp-blocks/ +- 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 https://gnss-sdr.org/docs/sp-blocks/ - Improved documentation of required dependency packages in several GNU/Linux distributions. +- Dump and output files can now be stored anywhere. - Parameter names with the same role have been harmonized within different block implementations. - Added a changelog, a code of conduct, a contributing guide and a pull-request template in the source tree. - Added colors to the commandline user interface. diff --git a/docs/xml-schemas/README.md b/docs/xml-schemas/README.md new file mode 100644 index 000000000..007d520c0 --- /dev/null +++ b/docs/xml-schemas/README.md @@ -0,0 +1,35 @@ +# XML Schemas for Assisted GNSS-SDR + +GNSS-SDR can read assistance data from [Extensible Markup Language (XML)](https://www.w3.org/XML/) files for faster [Time-To-First-Fix](https://gnss-sdr.org/design-forces/availability/#time-to-first-fix-ttff), and can store navigation data decoded from GNSS signals in the same format. This folder provides XML Schemas which describe those XML files structure. + +[XSD (XML Schema Definition)](https://www.w3.org/XML/Schema) is a World Wide Web Consortium (W3C) recommendation that specifies how to formally describe the elements in an XML document. + + +GPS L1 C/A +---------- + + - [ephemeris_map.xsd](./ephemeris_map.xsd) - GPS NAV message ephemeris parameters. + - [iono_model.xsd](./iono_model.xsd) - GPS NAV message ionospheric model parameters. + - [utc_model.xsd](./utc_model.xsd) - GPS NAV message UTC model parameters. + - [gps_almanac_map.xsd](./gps_almanac_map.xsd) - GPS NAV message almanac. + + +GPS L2C and L5 +-------------- + + - [cnav_ephemeris_map.xsd](./cnav_ephemeris_map.xsd) - GPS CNAV message ephemeris parameters. + + +Galileo +------- + + - [gal_ephemeris_map.xsd](./gal_ephemeris_map.xsd) - Galileo ephemeris parameters. + - [gal_iono_model.xsd](./gal_iono_model.xsd) - Galileo ionospheric model parameters. + - [gal_utc_model.xsd](./gal_utc_model.xsd) - Galileo UTC model parameters. + - [gal_almanac_map.xsd](./gal_almanac_map.xsd) - Galileo almanac. + +------- + +Please check https://gnss-sdr.org/docs/sp-blocks/global-parameters/ for more information about the usage of XML files in GNSS-SDR. + +You could find useful the utility program [rinex2assist](https://github.com/gnss-sdr/gnss-sdr/tree/next/src/utils/rinex2assist) for the generation of compatible XML files from recent, publicly available RINEX navigation data files. diff --git a/docs/xml-schemas/cnav_ephemeris_map.xsd b/docs/xml-schemas/cnav_ephemeris_map.xsd new file mode 100644 index 000000000..139756f36 --- /dev/null +++ b/docs/xml-schemas/cnav_ephemeris_map.xsd @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/ephemeris_map.xsd b/docs/xml-schemas/ephemeris_map.xsd new file mode 100644 index 000000000..f76c5e900 --- /dev/null +++ b/docs/xml-schemas/ephemeris_map.xsd @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/gal_almanac_map.xsd b/docs/xml-schemas/gal_almanac_map.xsd new file mode 100644 index 000000000..390609c58 --- /dev/null +++ b/docs/xml-schemas/gal_almanac_map.xsd @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/gal_ephemeris_map.xsd b/docs/xml-schemas/gal_ephemeris_map.xsd new file mode 100644 index 000000000..bf6c5ea20 --- /dev/null +++ b/docs/xml-schemas/gal_ephemeris_map.xsd @@ -0,0 +1,77 @@ +< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/gal_iono_model.xsd b/docs/xml-schemas/gal_iono_model.xsd new file mode 100644 index 000000000..dc0219273 --- /dev/null +++ b/docs/xml-schemas/gal_iono_model.xsd @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/gal_utc_model.xsd b/docs/xml-schemas/gal_utc_model.xsd new file mode 100644 index 000000000..a589f94fb --- /dev/null +++ b/docs/xml-schemas/gal_utc_model.xsd @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/gps_almanac_map.xsd b/docs/xml-schemas/gps_almanac_map.xsd new file mode 100644 index 000000000..86b9d2a2d --- /dev/null +++ b/docs/xml-schemas/gps_almanac_map.xsd @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/iono_model.xsd b/docs/xml-schemas/iono_model.xsd new file mode 100644 index 000000000..26cda74bd --- /dev/null +++ b/docs/xml-schemas/iono_model.xsd @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/xml-schemas/utc_model.xsd b/docs/xml-schemas/utc_model.xsd new file mode 100644 index 000000000..44005a628 --- /dev/null +++ b/docs/xml-schemas/utc_model.xsd @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 84e918b73..83c519fd5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,5 +21,5 @@ add_subdirectory(core) add_subdirectory(main) if(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING) add_subdirectory(tests) -endif(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING) +endif() add_subdirectory(utils) diff --git a/src/algorithms/PVT/adapters/CMakeLists.txt b/src/algorithms/PVT/adapters/CMakeLists.txt index 73c996521..d8c055506 100644 --- a/src/algorithms/PVT/adapters/CMakeLists.txt +++ b/src/algorithms/PVT/adapters/CMakeLists.txt @@ -16,28 +16,41 @@ # along with GNSS-SDR. If not, see . # + +if(Boost_VERSION LESS 105800) + add_definitions(-DOLD_BOOST=1) +endif() + set(PVT_ADAPTER_SOURCES - rtklib_pvt.cc + rtklib_pvt.cc +) + +set(PVT_ADAPTER_HEADERS + rtklib_pvt.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${ARMADILLO_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${ARMADILLO_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} ) -file(GLOB PVT_ADAPTER_HEADERS "*.h") -list(SORT PVT_ADAPTER_HEADERS) add_library(pvt_adapters ${PVT_ADAPTER_SOURCES} ${PVT_ADAPTER_HEADERS}) + source_group(Headers FILES ${PVT_ADAPTER_HEADERS}) -target_link_libraries(pvt_adapters pvt_gr_blocks ${ARMADILLO_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES}) + +target_link_libraries(pvt_adapters + pvt_gr_blocks + ${ARMADILLO_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} +) diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.cc b/src/algorithms/PVT/adapters/rtklib_pvt.cc index 24f4c9150..05ea52e5f 100644 --- a/src/algorithms/PVT/adapters/rtklib_pvt.cc +++ b/src/algorithms/PVT/adapters/rtklib_pvt.cc @@ -30,17 +30,45 @@ #include "rtklib_pvt.h" +#include "pvt_conf.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" #include #include -#include #include #include +#if OLD_BOOST +#include +namespace bc = boost::math; +#else +#include +namespace bc = boost::integer; +#endif using google::LogMessage; + +bool RtklibPvt::get_latest_PVT(double* longitude_deg, + double* latitude_deg, + double* height_m, + double* ground_speed_kmh, + double* course_over_ground_deg, + time_t* UTC_time) +{ + return pvt_->get_latest_PVT(longitude_deg, + latitude_deg, + height_m, + ground_speed_kmh, + course_over_ground_deg, + UTC_time); +} + +void RtklibPvt::clear_ephemeris() +{ + pvt_->clear_ephemeris(); +} + RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, @@ -48,97 +76,87 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, in_streams_(in_streams), out_streams_(out_streams) { + Pvt_Conf pvt_output_parameters = Pvt_Conf(); // dump parameters std::string default_dump_filename = "./pvt.dat"; std::string default_nmea_dump_filename = "./nmea_pvt.nmea"; std::string default_nmea_dump_devname = "/dev/tty1"; std::string default_rtcm_dump_devname = "/dev/pts/1"; DLOG(INFO) << "role " << role; - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); + pvt_output_parameters.dump = configuration->property(role + ".dump", false); + pvt_output_parameters.dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + pvt_output_parameters.dump_mat = configuration->property(role + ".dump_mat", true); // output rate - int output_rate_ms = configuration->property(role + ".output_rate_ms", 500); + pvt_output_parameters.output_rate_ms = configuration->property(role + ".output_rate_ms", 500); // display rate - int display_rate_ms = configuration->property(role + ".display_rate_ms", 500); + pvt_output_parameters.display_rate_ms = configuration->property(role + ".display_rate_ms", 500); // NMEA Printer settings - bool flag_nmea_tty_port = configuration->property(role + ".flag_nmea_tty_port", false); - std::string nmea_dump_filename = configuration->property(role + ".nmea_dump_filename", default_nmea_dump_filename); + pvt_output_parameters.flag_nmea_tty_port = configuration->property(role + ".flag_nmea_tty_port", false); + pvt_output_parameters.nmea_dump_filename = configuration->property(role + ".nmea_dump_filename", default_nmea_dump_filename); std::string nmea_dump_devname = configuration->property(role + ".nmea_dump_devname", default_nmea_dump_devname); // RINEX version - int rinex_version = configuration->property(role + ".rinex_version", 3); + pvt_output_parameters.rinex_version = configuration->property(role + ".rinex_version", 3); if (FLAGS_RINEX_version.compare("3.01") == 0) { - rinex_version = 3; + pvt_output_parameters.rinex_version = 3; } else if (FLAGS_RINEX_version.compare("3.02") == 0) { - rinex_version = 3; + pvt_output_parameters.rinex_version = 3; } else if (FLAGS_RINEX_version.compare("3") == 0) { - rinex_version = 3; + pvt_output_parameters.rinex_version = 3; } else if (FLAGS_RINEX_version.compare("2.11") == 0) { - rinex_version = 2; + pvt_output_parameters.rinex_version = 2; } else if (FLAGS_RINEX_version.compare("2.10") == 0) { - rinex_version = 2; + pvt_output_parameters.rinex_version = 2; } else if (FLAGS_RINEX_version.compare("2") == 0) { - rinex_version = 2; + pvt_output_parameters.rinex_version = 2; } - int rinexobs_rate_ms = boost::math::lcm(configuration->property(role + ".rinexobs_rate_ms", 1000), output_rate_ms); - int rinexnav_rate_ms = boost::math::lcm(configuration->property(role + ".rinexnav_rate_ms", 6000), output_rate_ms); + pvt_output_parameters.rinexobs_rate_ms = bc::lcm(configuration->property(role + ".rinexobs_rate_ms", 1000), pvt_output_parameters.output_rate_ms); + pvt_output_parameters.rinexnav_rate_ms = bc::lcm(configuration->property(role + ".rinexnav_rate_ms", 6000), pvt_output_parameters.output_rate_ms); // RTCM Printer settings - bool flag_rtcm_tty_port = configuration->property(role + ".flag_rtcm_tty_port", false); - std::string rtcm_dump_devname = configuration->property(role + ".rtcm_dump_devname", default_rtcm_dump_devname); - bool flag_rtcm_server = configuration->property(role + ".flag_rtcm_server", false); - unsigned short rtcm_tcp_port = configuration->property(role + ".rtcm_tcp_port", 2101); - unsigned short rtcm_station_id = configuration->property(role + ".rtcm_station_id", 1234); + pvt_output_parameters.flag_rtcm_tty_port = configuration->property(role + ".flag_rtcm_tty_port", false); + pvt_output_parameters.rtcm_dump_devname = configuration->property(role + ".rtcm_dump_devname", default_rtcm_dump_devname); + pvt_output_parameters.flag_rtcm_server = configuration->property(role + ".flag_rtcm_server", false); + pvt_output_parameters.rtcm_tcp_port = configuration->property(role + ".rtcm_tcp_port", 2101); + pvt_output_parameters.rtcm_station_id = configuration->property(role + ".rtcm_station_id", 1234); // RTCM message rates: least common multiple with output_rate_ms - int rtcm_MT1019_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1019_rate_ms", 5000), output_rate_ms); - int rtcm_MT1020_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1020_rate_ms", 5000), output_rate_ms); - int rtcm_MT1045_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1045_rate_ms", 5000), output_rate_ms); - int rtcm_MSM_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MSM_rate_ms", 1000), output_rate_ms); - int rtcm_MT1077_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1077_rate_ms", rtcm_MSM_rate_ms), output_rate_ms); - int rtcm_MT1087_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1087_rate_ms", rtcm_MSM_rate_ms), output_rate_ms); - int rtcm_MT1097_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1097_rate_ms", rtcm_MSM_rate_ms), output_rate_ms); - std::map rtcm_msg_rate_ms; - rtcm_msg_rate_ms[1019] = rtcm_MT1019_rate_ms; - rtcm_msg_rate_ms[1020] = rtcm_MT1020_rate_ms; - rtcm_msg_rate_ms[1045] = rtcm_MT1045_rate_ms; + int rtcm_MT1019_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1019_rate_ms", 5000), pvt_output_parameters.output_rate_ms); + int rtcm_MT1020_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1020_rate_ms", 5000), pvt_output_parameters.output_rate_ms); + int rtcm_MT1045_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1045_rate_ms", 5000), pvt_output_parameters.output_rate_ms); + int rtcm_MSM_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MSM_rate_ms", 1000), pvt_output_parameters.output_rate_ms); + int rtcm_MT1077_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1077_rate_ms", rtcm_MSM_rate_ms), pvt_output_parameters.output_rate_ms); + int rtcm_MT1087_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1087_rate_ms", rtcm_MSM_rate_ms), pvt_output_parameters.output_rate_ms); + int rtcm_MT1097_rate_ms = bc::lcm(configuration->property(role + ".rtcm_MT1097_rate_ms", rtcm_MSM_rate_ms), pvt_output_parameters.output_rate_ms); + //std::map rtcm_msg_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[1019] = rtcm_MT1019_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[1020] = rtcm_MT1020_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[1045] = rtcm_MT1045_rate_ms; for (int k = 1071; k < 1078; k++) // All GPS MSM { - rtcm_msg_rate_ms[k] = rtcm_MT1077_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[k] = rtcm_MT1077_rate_ms; } for (int k = 1081; k < 1088; k++) // All GLONASS MSM { - rtcm_msg_rate_ms[k] = rtcm_MT1087_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[k] = rtcm_MT1087_rate_ms; } for (int k = 1091; k < 1098; k++) // All Galileo MSM { - rtcm_msg_rate_ms[k] = rtcm_MT1097_rate_ms; + pvt_output_parameters.rtcm_msg_rate_ms[k] = rtcm_MT1097_rate_ms; } - // getting names from the config file, if available - // default filename for assistance data - const std::string eph_default_xml_filename = "./gps_ephemeris.xml"; - const std::string utc_default_xml_filename = "./gps_utc_model.xml"; - const std::string iono_default_xml_filename = "./gps_iono.xml"; - const std::string ref_time_default_xml_filename = "./gps_ref_time.xml"; - const std::string ref_location_default_xml_filename = "./gps_ref_location.xml"; - eph_xml_filename_ = configuration->property("GNSS-SDR.SUPL_gps_ephemeris_xml", eph_default_xml_filename); - //std::string utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_utc_model.xml", utc_default_xml_filename); - //std::string iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_iono_xml", iono_default_xml_filename); - //std::string ref_time_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_time_xml", ref_time_default_xml_filename); - //std::string ref_location_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_location_xml", ref_location_default_xml_filename); // Infer the type of receiver /* @@ -182,47 +200,46 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, int glo_1G_count = configuration->property("Channels_1G.count", 0); int glo_2G_count = configuration->property("Channels_2G.count", 0); - unsigned int type_of_receiver = 0; + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 1; // L1 + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 2; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 3; // L5 + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 4; // E1 + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 5; // E5a + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 6; - // *******************WARNING!!!!!!!*********** - // GPS L5 only configurable for single frequency, single system at the moment!!!!!! - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 1; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 2; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 3; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 4; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 5; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 6; + if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 7; + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 8; // L1+L5 + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 9; // L1+E1 + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 10; + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 11; + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 12; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 13; // L5+E5a + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 14; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 15; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) pvt_output_parameters.type_of_receiver = 16; + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 17; + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 18; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) pvt_output_parameters.type_of_receiver = 19; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) pvt_output_parameters.type_of_receiver = 20; + if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 21; + //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count = 0)) pvt_output_parameters.type_of_receiver = 22; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) pvt_output_parameters.type_of_receiver = 23; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) pvt_output_parameters.type_of_receiver = 24; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count != 0)) pvt_output_parameters.type_of_receiver = 25; + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 26; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 27; + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 28; + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) pvt_output_parameters.type_of_receiver = 29; + if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) pvt_output_parameters.type_of_receiver = 30; + if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) pvt_output_parameters.type_of_receiver = 31; - if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 7; - //if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 8; - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 9; - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 10; - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 11; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 12; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 13; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 14; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 15; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 16; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 17; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 18; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 19; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 20; - if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 21; - //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count = 0)) type_of_receiver = 22; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 23; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 24; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count != 0)) type_of_receiver = 25; - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 26; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 27; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 28; - if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 29; - if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 30; - if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 31; - //RTKLIB PVT solver options + if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) pvt_output_parameters.type_of_receiver = 32; // L1+E1+L5+E5a + + // RTKLIB PVT solver options // Settings 1 int positioning_mode = -1; std::string default_pos_mode("Single"); - std::string positioning_mode_str = configuration->property(role + ".positioning_mode", default_pos_mode); /* (PMODE_XXX) see src/algorithms/libs/rtklib/rtklib.h */ + std::string positioning_mode_str = configuration->property(role + ".positioning_mode", default_pos_mode); // (PMODE_XXX) see src/algorithms/libs/rtklib/rtklib.h if (positioning_mode_str.compare("Single") == 0) positioning_mode = PMODE_SINGLE; if (positioning_mode_str.compare("Static") == 0) positioning_mode = PMODE_STATIC; if (positioning_mode_str.compare("Kinematic") == 0) positioning_mode = PMODE_KINEMA; @@ -483,8 +500,29 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, rtkinit(&rtk, &rtklib_configuration_options); + // Outputs + bool default_output_enabled = configuration->property(role + ".output_enabled", true); + pvt_output_parameters.output_enabled = default_output_enabled; + pvt_output_parameters.rinex_output_enabled = configuration->property(role + ".rinex_output_enabled", default_output_enabled); + pvt_output_parameters.gpx_output_enabled = configuration->property(role + ".gpx_output_enabled", default_output_enabled); + pvt_output_parameters.geojson_output_enabled = configuration->property(role + ".geojson_output_enabled", default_output_enabled); + pvt_output_parameters.kml_output_enabled = configuration->property(role + ".kml_output_enabled", default_output_enabled); + pvt_output_parameters.xml_output_enabled = configuration->property(role + ".xml_output_enabled", default_output_enabled); + pvt_output_parameters.nmea_output_file_enabled = configuration->property(role + ".nmea_output_file_enabled", default_output_enabled); + pvt_output_parameters.rtcm_output_file_enabled = configuration->property(role + ".rtcm_output_file_enabled", default_output_enabled); + + std::string default_output_path = configuration->property(role + ".output_path", std::string(".")); + pvt_output_parameters.output_path = default_output_path; + pvt_output_parameters.rinex_output_path = configuration->property(role + ".rinex_output_path", default_output_path); + pvt_output_parameters.gpx_output_path = configuration->property(role + ".gpx_output_path", default_output_path); + pvt_output_parameters.geojson_output_path = configuration->property(role + ".geojson_output_path", default_output_path); + pvt_output_parameters.kml_output_path = configuration->property(role + ".kml_output_path", default_output_path); + pvt_output_parameters.xml_output_path = configuration->property(role + ".xml_output_path", default_output_path); + pvt_output_parameters.nmea_output_file_path = configuration->property(role + ".nmea_output_file_path", default_output_path); + pvt_output_parameters.rtcm_output_file_path = configuration->property(role + ".rtcm_output_file_path", default_output_path); + // make PVT object - pvt_ = rtklib_make_pvt_cc(in_streams_, dump_, dump_filename_, output_rate_ms, display_rate_ms, flag_nmea_tty_port, nmea_dump_filename, nmea_dump_devname, rinex_version, rinexobs_rate_ms, rinexnav_rate_ms, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_msg_rate_ms, rtcm_dump_devname, type_of_receiver, rtk); + pvt_ = rtklib_make_pvt_cc(in_streams_, pvt_output_parameters, rtk); DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")"; if (out_streams_ > 0) { @@ -493,40 +531,33 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, } -bool RtklibPvt::save_assistance_to_XML() -{ - LOG(INFO) << "SUPL: Try to save GPS ephemeris to XML file " << eph_xml_filename_; - std::map eph_map = pvt_->get_GPS_L1_ephemeris_map(); - - if (eph_map.size() > 0) - { - try - { - std::ofstream ofs(eph_xml_filename_.c_str(), std::ofstream::trunc | std::ofstream::out); - boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", eph_map); - ofs.close(); - LOG(INFO) << "Saved GPS L1 Ephemeris map data"; - } - catch (const std::exception& e) - { - LOG(WARNING) << e.what(); - return false; - } - return true; // return variable (true == succeeded) - } - else - { - LOG(WARNING) << "Failed to save Ephemeris, map is empty"; - return false; - } -} - - RtklibPvt::~RtklibPvt() { rtkfree(&rtk); - save_assistance_to_XML(); +} + + +std::map RtklibPvt::get_gps_ephemeris() const +{ + return pvt_->get_gps_ephemeris_map(); +} + + +std::map RtklibPvt::get_galileo_ephemeris() const +{ + return pvt_->get_galileo_ephemeris_map(); +} + + +std::map RtklibPvt::get_gps_almanac() const +{ + return pvt_->get_gps_almanac_map(); +} + + +std::map RtklibPvt::get_galileo_almanac() const +{ + return pvt_->get_galileo_almanac_map(); } diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.h b/src/algorithms/PVT/adapters/rtklib_pvt.h index 936fd1632..ed2bf7da4 100644 --- a/src/algorithms/PVT/adapters/rtklib_pvt.h +++ b/src/algorithms/PVT/adapters/rtklib_pvt.h @@ -40,7 +40,7 @@ class ConfigurationInterface; /*! - * \brief This class implements a PvtInterface for Galileo E1 + * \brief This class implements a PvtInterface for the RTKLIB PVT block */ class RtklibPvt : public PvtInterface { @@ -57,12 +57,18 @@ public: return role_; } - //! Returns "RTKLIB_Pvt" + //! Returns "RTKLIB_PVT" inline std::string implementation() override { return "RTKLIB_PVT"; } + void clear_ephemeris() override; + std::map get_gps_ephemeris() const override; + std::map get_galileo_ephemeris() const override; + std::map get_gps_almanac() const override; + std::map get_galileo_almanac() const override; + 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; @@ -79,16 +85,19 @@ public: return sizeof(gr_complex); } + bool get_latest_PVT(double* longitude_deg, + double* latitude_deg, + double* height_m, + double* ground_speed_kmh, + double* course_over_ground_deg, + time_t* UTC_time) override; + private: rtklib_pvt_cc_sptr pvt_; rtk_t rtk; - bool dump_; - std::string dump_filename_; std::string role_; unsigned int in_streams_; unsigned int out_streams_; - std::string eph_xml_filename_; - bool save_assistance_to_XML(); }; #endif diff --git a/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt b/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt index 34013b2ad..eb58c0894 100644 --- a/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt @@ -16,26 +16,34 @@ # along with GNSS-SDR. If not, see . # + +if(Boost_VERSION LESS 105800) + add_definitions(-DOLD_BOOST=1) +endif() + set(PVT_GR_BLOCKS_SOURCES - rtklib_pvt_cc.cc + rtklib_pvt_cc.cc +) + +set(PVT_GR_BLOCKS_HEADERS + rtklib_pvt_cc.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib - ${ARMADILLO_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${ARMADILLO_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} ) -file(GLOB PVT_GR_BLOCKS_HEADERS "*.h") -list(SORT PVT_GR_BLOCKS_HEADERS) add_library(pvt_gr_blocks ${PVT_GR_BLOCKS_SOURCES} ${PVT_GR_BLOCKS_HEADERS}) source_group(Headers FILES ${PVT_GR_BLOCKS_HEADERS}) target_link_libraries(pvt_gr_blocks pvt_lib ${ARMADILLO_LIBRARIES}) diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc index 1fc243cb3..7e6753b48 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc @@ -29,63 +29,40 @@ */ #include "rtklib_pvt_cc.h" -#include -#include +#include "galileo_almanac.h" +#include "galileo_almanac_helper.h" +#include "pvt_conf.h" +#include "display.h" +#include "gnss_sdr_create_directory.h" #include #include -#include #include +#include +#include #include #include #include -#include "display.h" #include #include #include #include - +#if OLD_BOOST +#include +namespace bc = boost::math; +#else +#include +namespace bc = boost::integer; +#endif using google::LogMessage; -rtklib_pvt_cc_sptr rtklib_make_pvt_cc(unsigned int nchannels, - bool dump, - std::string dump_filename, - int output_rate_ms, - int display_rate_ms, - bool flag_nmea_tty_port, - std::string nmea_dump_filename, - std::string nmea_dump_devname, - int rinex_version, - int rinexobs_rate_ms, - int rinexnav_rate_ms, - bool flag_rtcm_server, - bool flag_rtcm_tty_port, - unsigned short rtcm_tcp_port, - unsigned short rtcm_station_id, - std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname, - const unsigned int type_of_receiver, +rtklib_pvt_cc_sptr rtklib_make_pvt_cc(uint32_t nchannels, + const Pvt_Conf& conf_, rtk_t& rtk) { return rtklib_pvt_cc_sptr(new rtklib_pvt_cc(nchannels, - dump, - dump_filename, - output_rate_ms, - display_rate_ms, - flag_nmea_tty_port, - nmea_dump_filename, - nmea_dump_devname, - rinex_version, - rinexobs_rate_ms, - rinexnav_rate_ms, - flag_rtcm_server, - flag_rtcm_tty_port, - rtcm_tcp_port, - rtcm_station_id, - rtcm_msg_rate_ms, - rtcm_dump_devname, - type_of_receiver, + conf_, rtk)); } @@ -106,14 +83,14 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) << "inserted with Toe=" << gps_eph->d_Toe << " and GPS Week=" << gps_eph->i_GPS_week; // update/insert new ephemeris record to the global ephemeris map - d_ls_pvt->gps_ephemeris_map[gps_eph->i_satellite_PRN] = *gps_eph; + d_pvt_solver->gps_ephemeris_map[gps_eph->i_satellite_PRN] = *gps_eph; } else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) { // ### GPS IONO ### std::shared_ptr gps_iono; gps_iono = boost::any_cast>(pmt::any_ref(msg)); - d_ls_pvt->gps_iono = *gps_iono; + d_pvt_solver->gps_iono = *gps_iono; DLOG(INFO) << "New IONO record has arrived "; } else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) @@ -121,7 +98,7 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) // ### GPS UTC MODEL ### std::shared_ptr gps_utc_model; gps_utc_model = boost::any_cast>(pmt::any_ref(msg)); - d_ls_pvt->gps_utc_model = *gps_utc_model; + d_pvt_solver->gps_utc_model = *gps_utc_model; DLOG(INFO) << "New UTC record has arrived "; } else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) @@ -130,7 +107,7 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) std::shared_ptr gps_cnav_ephemeris; gps_cnav_ephemeris = boost::any_cast>(pmt::any_ref(msg)); // update/insert new ephemeris record to the global ephemeris map - d_ls_pvt->gps_cnav_ephemeris_map[gps_cnav_ephemeris->i_satellite_PRN] = *gps_cnav_ephemeris; + d_pvt_solver->gps_cnav_ephemeris_map[gps_cnav_ephemeris->i_satellite_PRN] = *gps_cnav_ephemeris; DLOG(INFO) << "New GPS CNAV ephemeris record has arrived "; } else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) @@ -138,7 +115,7 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) // ### GPS CNAV IONO ### std::shared_ptr gps_cnav_iono; gps_cnav_iono = boost::any_cast>(pmt::any_ref(msg)); - d_ls_pvt->gps_cnav_iono = *gps_cnav_iono; + d_pvt_solver->gps_cnav_iono = *gps_cnav_iono; DLOG(INFO) << "New CNAV IONO record has arrived "; } else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) @@ -146,10 +123,19 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) // ### GPS CNAV UTC MODEL ### std::shared_ptr gps_cnav_utc_model; gps_cnav_utc_model = boost::any_cast>(pmt::any_ref(msg)); - d_ls_pvt->gps_cnav_utc_model = *gps_cnav_utc_model; + d_pvt_solver->gps_cnav_utc_model = *gps_cnav_utc_model; DLOG(INFO) << "New CNAV UTC record has arrived "; } + else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) + { + // ### GPS ALMANAC ### + std::shared_ptr gps_almanac; + gps_almanac = boost::any_cast>(pmt::any_ref(msg)); + d_pvt_solver->gps_almanac_map[gps_almanac->i_satellite_PRN] = *gps_almanac; + DLOG(INFO) << "New GPS almanac record has arrived "; + } + // **************** Galileo telemetry ******************** else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) { @@ -161,14 +147,14 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) << ", GALILEO Week Number =" << galileo_eph->WN_5 << " and Ephemeris IOD = " << galileo_eph->IOD_ephemeris; // update/insert new ephemeris record to the global ephemeris map - d_ls_pvt->galileo_ephemeris_map[galileo_eph->i_satellite_PRN] = *galileo_eph; + d_pvt_solver->galileo_ephemeris_map[galileo_eph->i_satellite_PRN] = *galileo_eph; } else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) { // ### Galileo IONO ### std::shared_ptr galileo_iono; galileo_iono = boost::any_cast>(pmt::any_ref(msg)); - d_ls_pvt->galileo_iono = *galileo_iono; + d_pvt_solver->galileo_iono = *galileo_iono; DLOG(INFO) << "New IONO record has arrived "; } else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) @@ -176,17 +162,31 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) // ### Galileo UTC MODEL ### std::shared_ptr galileo_utc_model; galileo_utc_model = boost::any_cast>(pmt::any_ref(msg)); - d_ls_pvt->galileo_utc_model = *galileo_utc_model; + d_pvt_solver->galileo_utc_model = *galileo_utc_model; DLOG(INFO) << "New UTC record has arrived "; } + else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) + { + // ### Galileo Almanac ### + std::shared_ptr galileo_almanac_helper; + galileo_almanac_helper = boost::any_cast>(pmt::any_ref(msg)); + + Galileo_Almanac sv1 = galileo_almanac_helper->get_almanac(1); + Galileo_Almanac sv2 = galileo_almanac_helper->get_almanac(2); + Galileo_Almanac sv3 = galileo_almanac_helper->get_almanac(3); + + if (sv1.i_satellite_PRN != 0) d_pvt_solver->galileo_almanac_map[sv1.i_satellite_PRN] = sv1; + if (sv2.i_satellite_PRN != 0) d_pvt_solver->galileo_almanac_map[sv2.i_satellite_PRN] = sv2; + if (sv3.i_satellite_PRN != 0) d_pvt_solver->galileo_almanac_map[sv3.i_satellite_PRN] = sv3; + DLOG(INFO) << "New Galileo Almanac data have arrived "; + } else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) { // ### Galileo Almanac ### - std::shared_ptr galileo_almanac; - galileo_almanac = boost::any_cast>(pmt::any_ref(msg)); - // update/insert new ephemeris record to the global ephemeris map - d_ls_pvt->galileo_almanac = *galileo_almanac; - DLOG(INFO) << "New Galileo Almanac has arrived "; + std::shared_ptr galileo_alm; + galileo_alm = boost::any_cast>(pmt::any_ref(msg)); + // update/insert new almanac record to the global almanac map + d_pvt_solver->galileo_almanac_map[galileo_alm->i_satellite_PRN] = *galileo_alm; } // **************** GLONASS GNAV Telemetry ************************** @@ -202,14 +202,14 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) << " and Ephemeris IOD in UTC = " << glonass_gnav_eph->compute_GLONASS_time(glonass_gnav_eph->d_t_b) << " from SV = " << glonass_gnav_eph->i_satellite_slot_number; // update/insert new ephemeris record to the global ephemeris map - d_ls_pvt->glonass_gnav_ephemeris_map[glonass_gnav_eph->i_satellite_PRN] = *glonass_gnav_eph; + d_pvt_solver->glonass_gnav_ephemeris_map[glonass_gnav_eph->i_satellite_PRN] = *glonass_gnav_eph; } else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) { // ### GLONASS GNAV UTC MODEL ### std::shared_ptr glonass_gnav_utc_model; glonass_gnav_utc_model = boost::any_cast>(pmt::any_ref(msg)); - d_ls_pvt->glonass_gnav_utc_model = *glonass_gnav_utc_model; + d_pvt_solver->glonass_gnav_utc_model = *glonass_gnav_utc_model; DLOG(INFO) << "New GLONASS GNAV UTC record has arrived "; } else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr)) @@ -217,7 +217,7 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) // ### GLONASS GNAV Almanac ### std::shared_ptr glonass_gnav_almanac; glonass_gnav_almanac = boost::any_cast>(pmt::any_ref(msg)); - d_ls_pvt->glonass_gnav_almanac = *glonass_gnav_almanac; + d_pvt_solver->glonass_gnav_almanac = *glonass_gnav_almanac; DLOG(INFO) << "New GLONASS GNAV Almanac has arrived " << ", GLONASS GNAV Slot Number =" << glonass_gnav_almanac->d_n_A; } @@ -233,41 +233,87 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) } -std::map rtklib_pvt_cc::get_GPS_L1_ephemeris_map() +std::map rtklib_pvt_cc::get_gps_ephemeris_map() const { - return d_ls_pvt->gps_ephemeris_map; + return d_pvt_solver->gps_ephemeris_map; } -rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels, - bool dump, - std::string dump_filename, - int output_rate_ms, - int display_rate_ms, - bool flag_nmea_tty_port, - std::string nmea_dump_filename, - std::string nmea_dump_devname, - int rinex_version, - int rinexobs_rate_ms, - int rinexnav_rate_ms, - bool flag_rtcm_server, - bool flag_rtcm_tty_port, - unsigned short rtcm_tcp_port, - unsigned short rtcm_station_id, - std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname, - const unsigned int type_of_receiver, +std::map rtklib_pvt_cc::get_gps_almanac_map() const +{ + return d_pvt_solver->gps_almanac_map; +} + + +std::map rtklib_pvt_cc::get_galileo_ephemeris_map() const +{ + return d_pvt_solver->galileo_ephemeris_map; +} + + +std::map rtklib_pvt_cc::get_galileo_almanac_map() const +{ + return d_pvt_solver->galileo_almanac_map; +} + + +void rtklib_pvt_cc::clear_ephemeris() +{ + d_pvt_solver->gps_ephemeris_map.clear(); + d_pvt_solver->gps_almanac_map.clear(); + d_pvt_solver->galileo_ephemeris_map.clear(); + d_pvt_solver->galileo_almanac_map.clear(); +} + + +rtklib_pvt_cc::rtklib_pvt_cc(uint32_t nchannels, + const Pvt_Conf& conf_, rtk_t& rtk) : gr::sync_block("rtklib_pvt_cc", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)), gr::io_signature::make(0, 0, 0)) { - d_output_rate_ms = output_rate_ms; - d_display_rate_ms = display_rate_ms; - d_dump = dump; + d_output_rate_ms = conf_.output_rate_ms; + d_display_rate_ms = conf_.display_rate_ms; + d_dump = conf_.dump; + d_dump_mat = conf_.dump_mat and d_dump; + d_dump_filename = conf_.dump_filename; + std::string dump_ls_pvt_filename = conf_.dump_filename; + if (d_dump) + { + std::string dump_path; + // Get path + if (d_dump_filename.find_last_of("/") != std::string::npos) + { + std::string dump_filename_ = d_dump_filename.substr(d_dump_filename.find_last_of("/") + 1); + dump_path = d_dump_filename.substr(0, d_dump_filename.find_last_of("/")); + d_dump_filename = dump_filename_; + } + else + { + dump_path = std::string("."); + } + if (d_dump_filename.empty()) + { + d_dump_filename = "pvt"; + } + // remove extension if any + if (d_dump_filename.substr(1).find_last_of(".") != std::string::npos) + { + d_dump_filename = d_dump_filename.substr(0, d_dump_filename.find_last_of(".")); + } + dump_ls_pvt_filename = dump_path + boost::filesystem::path::preferred_separator + d_dump_filename; + dump_ls_pvt_filename.append(".dat"); + // create directory + if (!gnss_sdr_create_directory(dump_path)) + { + std::cerr << "GNSS-SDR cannot create dump file for the PVT block. Wrong permissions?" << std::endl; + d_dump = false; + } + } + d_nchannels = nchannels; - d_dump_filename = dump_filename; - std::string dump_ls_pvt_filename = dump_filename; - type_of_rx = type_of_receiver; + + type_of_rx = conf_.type_of_receiver; // GPS Ephemeris data message port in this->message_port_register_in(pmt::mp("telemetry")); @@ -276,116 +322,191 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels, // initialize kml_printer std::string kml_dump_filename; kml_dump_filename = d_dump_filename; - d_kml_dump = std::make_shared(); - d_kml_dump->set_headers(kml_dump_filename); + d_kml_output_enabled = conf_.kml_output_enabled; + if (d_kml_output_enabled) + { + d_kml_dump = std::make_shared(conf_.kml_output_path); + d_kml_dump->set_headers(kml_dump_filename); + } + else + { + d_kml_dump = nullptr; + } // initialize gpx_printer std::string gpx_dump_filename; gpx_dump_filename = d_dump_filename; - d_gpx_dump = std::make_shared(); - d_gpx_dump->set_headers(gpx_dump_filename); + d_gpx_output_enabled = conf_.gpx_output_enabled; + if (d_gpx_output_enabled) + { + d_gpx_dump = std::make_shared(conf_.gpx_output_path); + d_gpx_dump->set_headers(gpx_dump_filename); + } + else + { + d_gpx_dump = nullptr; + } // initialize geojson_printer std::string geojson_dump_filename; geojson_dump_filename = d_dump_filename; - d_geojson_printer = std::make_shared(); - d_geojson_printer->set_headers(geojson_dump_filename); + + d_geojson_output_enabled = conf_.geojson_output_enabled; + if (d_geojson_output_enabled) + { + d_geojson_printer = std::make_shared(conf_.geojson_output_path); + d_geojson_printer->set_headers(geojson_dump_filename); + } + else + { + d_geojson_printer = nullptr; + } // initialize nmea_printer - d_nmea_printer = std::make_shared(nmea_dump_filename, flag_nmea_tty_port, nmea_dump_devname); + d_nmea_output_file_enabled = (conf_.nmea_output_file_enabled or conf_.flag_nmea_tty_port); + if (d_nmea_output_file_enabled) + { + d_nmea_printer = std::make_shared(conf_.nmea_dump_filename, conf_.nmea_output_file_enabled, conf_.flag_nmea_tty_port, conf_.nmea_dump_devname, conf_.nmea_output_file_path); + } + else + { + d_nmea_printer = nullptr; + } // initialize rtcm_printer std::string rtcm_dump_filename; rtcm_dump_filename = d_dump_filename; - d_rtcm_printer = std::make_shared(rtcm_dump_filename, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname); - if (rtcm_msg_rate_ms.find(1019) != rtcm_msg_rate_ms.end()) + if (conf_.flag_rtcm_server or conf_.flag_rtcm_tty_port or conf_.rtcm_output_file_enabled) { - d_rtcm_MT1019_rate_ms = rtcm_msg_rate_ms[1019]; + d_rtcm_printer = std::make_shared(rtcm_dump_filename, conf_.rtcm_output_file_enabled, conf_.flag_rtcm_server, conf_.flag_rtcm_tty_port, conf_.rtcm_tcp_port, conf_.rtcm_station_id, conf_.rtcm_dump_devname, true, conf_.rtcm_output_file_path); + std::map rtcm_msg_rate_ms = conf_.rtcm_msg_rate_ms; + if (rtcm_msg_rate_ms.find(1019) != rtcm_msg_rate_ms.end()) + { + d_rtcm_MT1019_rate_ms = rtcm_msg_rate_ms[1019]; + } + else + { + d_rtcm_MT1019_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set + } + if (rtcm_msg_rate_ms.find(1020) != rtcm_msg_rate_ms.end()) + { + d_rtcm_MT1020_rate_ms = rtcm_msg_rate_ms[1020]; + } + else + { + d_rtcm_MT1020_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set + } + if (rtcm_msg_rate_ms.find(1045) != rtcm_msg_rate_ms.end()) + { + d_rtcm_MT1045_rate_ms = rtcm_msg_rate_ms[1045]; + } + else + { + d_rtcm_MT1045_rate_ms = bc::lcm(5000, d_output_rate_ms); // default value if not set + } + if (rtcm_msg_rate_ms.find(1077) != rtcm_msg_rate_ms.end()) // whatever between 1071 and 1077 + { + d_rtcm_MT1077_rate_ms = rtcm_msg_rate_ms[1077]; + } + else + { + d_rtcm_MT1077_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set + } + if (rtcm_msg_rate_ms.find(1087) != rtcm_msg_rate_ms.end()) // whatever between 1081 and 1087 + { + d_rtcm_MT1087_rate_ms = rtcm_msg_rate_ms[1087]; + } + else + { + d_rtcm_MT1087_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set + } + if (rtcm_msg_rate_ms.find(1097) != rtcm_msg_rate_ms.end()) // whatever between 1091 and 1097 + { + d_rtcm_MT1097_rate_ms = rtcm_msg_rate_ms[1097]; + d_rtcm_MSM_rate_ms = rtcm_msg_rate_ms[1097]; + } + else + { + d_rtcm_MT1097_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set + d_rtcm_MSM_rate_ms = bc::lcm(1000, d_output_rate_ms); // default value if not set + } + b_rtcm_writing_started = false; + b_rtcm_enabled = true; } else { - d_rtcm_MT1019_rate_ms = boost::math::lcm(5000, d_output_rate_ms); // default value if not set + d_rtcm_MT1019_rate_ms = 0; + d_rtcm_MT1045_rate_ms = 0; + d_rtcm_MT1020_rate_ms = 0; + d_rtcm_MT1077_rate_ms = 0; + d_rtcm_MT1087_rate_ms = 0; + d_rtcm_MT1097_rate_ms = 0; + d_rtcm_MSM_rate_ms = 0; + b_rtcm_enabled = false; + b_rtcm_writing_started = false; + d_rtcm_printer = nullptr; } - if (rtcm_msg_rate_ms.find(1020) != rtcm_msg_rate_ms.end()) - { - d_rtcm_MT1020_rate_ms = rtcm_msg_rate_ms[1020]; - } - else - { - d_rtcm_MT1020_rate_ms = boost::math::lcm(5000, d_output_rate_ms); // default value if not set - } - if (rtcm_msg_rate_ms.find(1045) != rtcm_msg_rate_ms.end()) - { - d_rtcm_MT1045_rate_ms = rtcm_msg_rate_ms[1045]; - } - else - { - d_rtcm_MT1045_rate_ms = boost::math::lcm(5000, d_output_rate_ms); // default value if not set - } - if (rtcm_msg_rate_ms.find(1077) != rtcm_msg_rate_ms.end()) // whatever between 1071 and 1077 - { - d_rtcm_MT1077_rate_ms = rtcm_msg_rate_ms[1077]; - } - else - { - d_rtcm_MT1077_rate_ms = boost::math::lcm(1000, d_output_rate_ms); // default value if not set - } - if (rtcm_msg_rate_ms.find(1087) != rtcm_msg_rate_ms.end()) // whatever between 1081 and 1087 - { - d_rtcm_MT1087_rate_ms = rtcm_msg_rate_ms[1087]; - } - else - { - d_rtcm_MT1087_rate_ms = boost::math::lcm(1000, d_output_rate_ms); // default value if not set - } - if (rtcm_msg_rate_ms.find(1097) != rtcm_msg_rate_ms.end()) // whatever between 1091 and 1097 - { - d_rtcm_MT1097_rate_ms = rtcm_msg_rate_ms[1097]; - d_rtcm_MSM_rate_ms = rtcm_msg_rate_ms[1097]; - } - else - { - d_rtcm_MT1097_rate_ms = boost::math::lcm(1000, d_output_rate_ms); // default value if not set - d_rtcm_MSM_rate_ms = boost::math::lcm(1000, d_output_rate_ms); // default value if not set - } - b_rtcm_writing_started = false; // initialize RINEX printer b_rinex_header_written = false; b_rinex_header_updated = false; - d_rinex_version = rinex_version; - rp = std::make_shared(d_rinex_version); - d_rinexobs_rate_ms = rinexobs_rate_ms; - d_rinexnav_rate_ms = rinexnav_rate_ms; + b_rinex_output_enabled = conf_.rinex_output_enabled; + d_rinex_version = conf_.rinex_version; + if (b_rinex_output_enabled) + { + rp = std::make_shared(d_rinex_version, conf_.rinex_output_path); + } + else + { + rp = nullptr; + } + d_rinexobs_rate_ms = conf_.rinexobs_rate_ms; + d_rinexnav_rate_ms = conf_.rinexnav_rate_ms; - d_dump_filename.append("_raw.dat"); - dump_ls_pvt_filename.append("_ls_pvt.dat"); + // XML printer + d_xml_storage = conf_.xml_output_enabled; + if (d_xml_storage) + { + xml_base_path = conf_.xml_output_path; + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(xml_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(xml_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + xml_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + xml_base_path = p.string(); + } + if (xml_base_path.compare(".") != 0) + { + std::cout << "XML files will be stored at " << xml_base_path << std::endl; + } - d_ls_pvt = std::make_shared(static_cast(nchannels), dump_ls_pvt_filename, d_dump, rtk); - d_ls_pvt->set_averaging_depth(1); + xml_base_path = xml_base_path + boost::filesystem::path::preferred_separator; + } + + d_pvt_solver = std::make_shared(static_cast(nchannels), dump_ls_pvt_filename, d_dump, d_dump_mat, rtk); + d_pvt_solver->set_averaging_depth(1); d_rx_time = 0.0; d_last_status_print_seg = 0; - // ############# ENABLE DATA FILE LOG ################# - if (d_dump == true) - { - if (d_dump_file.is_open() == false) - { - try - { - d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "PVT dump enabled Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure& e) - { - LOG(WARNING) << "Exception opening PVT dump file " << e.what(); - } - } - } - // Create Sys V message queue first_fix = true; sysv_msg_key = 1101; @@ -402,108 +523,314 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels, rtklib_pvt_cc::~rtklib_pvt_cc() { msgctl(sysv_msqid, IPC_RMID, NULL); - - // save GPS L2CM ephemeris to XML file - std::string file_name = "eph_GPS_CNAV.xml"; - - if (d_ls_pvt->gps_cnav_ephemeris_map.size() > 0) + if (d_xml_storage) { - try + // save GPS L2CM ephemeris to XML file + std::string file_name = xml_base_path + "gps_cnav_ephemeris.xml"; + if (d_pvt_solver->gps_cnav_ephemeris_map.empty() == false) { - std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); - boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->gps_cnav_ephemeris_map); - ofs.close(); - LOG(INFO) << "Saved GPS L2CM or L5 Ephemeris map data"; + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_cnav_ephemeris_map", d_pvt_solver->gps_cnav_ephemeris_map); + LOG(INFO) << "Saved GPS L2CM or L5 Ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } } - catch (std::exception& e) + else { - LOG(WARNING) << e.what(); + LOG(INFO) << "Failed to save GPS L2CM or L5 Ephemeris, map is empty"; } - } - else - { - LOG(WARNING) << "Failed to save GPS L2CM or L5 Ephemeris, map is empty"; - } - // save GPS L1 CA ephemeris to XML file - file_name = "eph_GPS_L1CA.xml"; + // save GPS L1 CA ephemeris to XML file + file_name = xml_base_path + "gps_ephemeris.xml"; + if (d_pvt_solver->gps_ephemeris_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_pvt_solver->gps_ephemeris_map); + LOG(INFO) << "Saved GPS L1 CA Ephemeris map data"; + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GPS L1 CA Ephemeris, map is empty"; + } - if (d_ls_pvt->gps_ephemeris_map.size() > 0) - { - try + // save Galileo E1 ephemeris to XML file + file_name = xml_base_path + "gal_ephemeris.xml"; + if (d_pvt_solver->galileo_ephemeris_map.empty() == false) { - std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); - boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->gps_ephemeris_map); - ofs.close(); - LOG(INFO) << "Saved GPS L1 CA Ephemeris map data"; + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", d_pvt_solver->galileo_ephemeris_map); + LOG(INFO) << "Saved Galileo E1 Ephemeris map data"; + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } } - catch (const std::exception& e) + else { - LOG(WARNING) << e.what(); + LOG(INFO) << "Failed to save Galileo E1 Ephemeris, map is empty"; } - } - else - { - LOG(WARNING) << "Failed to save GPS L1 CA Ephemeris, map is empty"; - } - // save Galileo E1 ephemeris to XML file - file_name = "eph_Galileo_E1.xml"; + // save GLONASS GNAV ephemeris to XML file + file_name = xml_base_path + "eph_GLONASS_GNAV.xml"; + if (d_pvt_solver->glonass_gnav_ephemeris_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gnav_ephemeris_map", d_pvt_solver->glonass_gnav_ephemeris_map); + LOG(INFO) << "Saved GLONASS GNAV Ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GLONASS GNAV Ephemeris, map is empty"; + } - if (d_ls_pvt->galileo_ephemeris_map.size() > 0) - { - try + // Save GPS UTC model parameters + file_name = xml_base_path + "gps_utc_model.xml"; + if (d_pvt_solver->gps_utc_model.valid) { - std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); - boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->galileo_ephemeris_map); - ofs.close(); - LOG(INFO) << "Saved Galileo E1 Ephemeris map data"; + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_utc_model", d_pvt_solver->gps_utc_model); + LOG(INFO) << "Saved GPS UTC model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } } - catch (const std::exception& e) + else { - LOG(WARNING) << e.what(); + LOG(INFO) << "Failed to save GPS UTC model parameters, not valid data"; } - } - else - { - LOG(WARNING) << "Failed to save Galileo E1 Ephemeris, map is empty"; - } - // save GLONASS GNAV ephemeris to XML file - file_name = "eph_GLONASS_GNAV.xml"; + // Save Galileo UTC model parameters + file_name = xml_base_path + "gal_utc_model.xml"; + if (d_pvt_solver->galileo_utc_model.Delta_tLS_6 != 0.0) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", d_pvt_solver->galileo_utc_model); + LOG(INFO) << "Saved Galileo UTC model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save Galileo UTC model parameters, not valid data"; + } - if (d_ls_pvt->glonass_gnav_ephemeris_map.size() > 0) - { - try + // Save GPS iono parameters + file_name = xml_base_path + "gps_iono.xml"; + if (d_pvt_solver->gps_iono.valid == true) { - std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); - boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->glonass_gnav_ephemeris_map); - ofs.close(); - LOG(INFO) << "Saved GLONASS GNAV Ephemeris map data"; + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_iono_model", d_pvt_solver->gps_iono); + LOG(INFO) << "Saved GPS ionospheric model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } } - catch (std::exception& e) + else { - LOG(WARNING) << e.what(); + LOG(INFO) << "Failed to save GPS ionospheric model parameters, not valid data"; } - } - else - { - LOG(WARNING) << "Failed to save GLONASS GNAV Ephemeris, map is empty"; - } - if (d_dump_file.is_open() == true) - { - try + // Save GPS CNAV iono parameters + file_name = xml_base_path + "gps_cnav_iono.xml"; + if (d_pvt_solver->gps_cnav_iono.valid == true) { - d_dump_file.close(); + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_cnav_iono_model", d_pvt_solver->gps_cnav_iono); + LOG(INFO) << "Saved GPS CNAV ionospheric model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } } - catch (const std::exception& ex) + else { - LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); + LOG(INFO) << "Failed to save GPS CNAV ionospheric model parameters, not valid data"; + } + + // Save Galileo iono parameters + file_name = xml_base_path + "gal_iono.xml"; + if (d_pvt_solver->galileo_iono.ai0_5 != 0.0) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_iono_model", d_pvt_solver->galileo_iono); + LOG(INFO) << "Saved Galileo ionospheric model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save Galileo ionospheric model parameters, not valid data"; + } + + // save GPS almanac to XML file + file_name = xml_base_path + "gps_almanac.xml"; + if (d_pvt_solver->gps_almanac_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gps_almanac_map", d_pvt_solver->gps_almanac_map); + LOG(INFO) << "Saved GPS almanac map data"; + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GPS almanac, map is empty"; + } + + // Save Galileo almanac + file_name = xml_base_path + "gal_almanac.xml"; + if (d_pvt_solver->galileo_almanac_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_almanac_map", d_pvt_solver->galileo_almanac_map); + LOG(INFO) << "Saved Galileo almanac data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save Galileo almanac, not valid data"; + } + + // Save GPS CNAV UTC model parameters + file_name = xml_base_path + "gps_cnav_utc_model.xml"; + if (d_pvt_solver->gps_cnav_utc_model.valid) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_cnav_utc_model", d_pvt_solver->gps_cnav_utc_model); + LOG(INFO) << "Saved GPS CNAV UTC model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GPS CNAV UTC model parameters, not valid data"; + } + + // save GLONASS GNAV ephemeris to XML file + file_name = xml_base_path + "glo_gnav_ephemeris.xml"; + if (d_pvt_solver->glonass_gnav_ephemeris_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gnav_ephemeris_map", d_pvt_solver->glonass_gnav_ephemeris_map); + LOG(INFO) << "Saved GLONASS GNAV ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GLONASS GNAV ephemeris, map is empty"; + } + + // save GLONASS UTC model parameters to XML file + file_name = xml_base_path + "glo_utc_model.xml"; + if (d_pvt_solver->glonass_gnav_utc_model.valid) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gnav_utc_model", d_pvt_solver->glonass_gnav_utc_model); + LOG(INFO) << "Saved GLONASS UTC model parameters"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + } + } + else + { + LOG(INFO) << "Failed to save GLONASS GNAV ephemeris, not valid data"; } } } @@ -531,10 +858,86 @@ bool rtklib_pvt_cc::send_sys_v_ttff_msg(ttff_msgbuf ttff) } +bool rtklib_pvt_cc::save_gnss_synchro_map_xml(const std::string file_name) +{ + if (gnss_observables_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gnss_synchro_map", gnss_observables_map); + LOG(INFO) << "Saved gnss_sychro map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + return true; + } + else + { + LOG(WARNING) << "Failed to save gnss_synchro, map is empty"; + return false; + } +} + + +bool rtklib_pvt_cc::load_gnss_synchro_map_xml(const std::string file_name) +{ + // load from xml (boost serialize) + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gnss_observables_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_gnss_synchro_map", gnss_observables_map); + //std::cout << "Loaded gnss_synchro map data with " << gnss_synchro_map.size() << " pseudoranges" << std::endl; + } + catch (std::exception& e) + { + std::cout << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool rtklib_pvt_cc::get_latest_PVT(double* longitude_deg, + double* latitude_deg, + double* height_m, + double* ground_speed_kmh, + double* course_over_ground_deg, + time_t* UTC_time) +{ + gr::thread::scoped_lock lock(d_setlock); + if (d_pvt_solver->is_valid_position()) + { + *latitude_deg = d_pvt_solver->get_latitude(); + *longitude_deg = d_pvt_solver->get_longitude(); + *height_m = d_pvt_solver->get_height(); + *ground_speed_kmh = d_pvt_solver->get_speed_over_ground() * 3600.0 / 1000.0; + *course_over_ground_deg = d_pvt_solver->get_course_over_ground(); + *UTC_time = to_time_t(d_pvt_solver->get_position_UTC_time()); + + return true; + } + else + { + return false; + } +} + + int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_items, gr_vector_void_star& output_items __attribute__((unused))) { - for (int epoch = 0; epoch < noutput_items; epoch++) + gr::thread::scoped_lock l(d_setlock); + + for (int32_t epoch = 0; epoch < noutput_items; epoch++) { bool flag_display_pvt = false; bool flag_compute_pvt_output = false; @@ -544,76 +947,75 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item bool flag_write_RTCM_MSM_output = false; bool flag_write_RINEX_obs_output = false; bool flag_write_RINEX_nav_output = false; - unsigned int gps_channel = 0; - unsigned int gal_channel = 0; - unsigned int glo_channel = 0; gnss_observables_map.clear(); const Gnss_Synchro** in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer - // ############ 1. READ PSEUDORANGES #### - for (unsigned int i = 0; i < d_nchannels; i++) + for (uint32_t i = 0; i < d_nchannels; i++) { if (in[i][epoch].Flag_valid_pseudorange) { - std::map::const_iterator tmp_eph_iter_gps = d_ls_pvt->gps_ephemeris_map.find(in[i][epoch].PRN); - std::map::const_iterator tmp_eph_iter_gal = d_ls_pvt->galileo_ephemeris_map.find(in[i][epoch].PRN); - std::map::const_iterator tmp_eph_iter_cnav = d_ls_pvt->gps_cnav_ephemeris_map.find(in[i][epoch].PRN); - std::map::const_iterator tmp_eph_iter_glo_gnav = d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN); + std::map::const_iterator tmp_eph_iter_gps = d_pvt_solver->gps_ephemeris_map.find(in[i][epoch].PRN); + std::map::const_iterator tmp_eph_iter_gal = d_pvt_solver->galileo_ephemeris_map.find(in[i][epoch].PRN); + std::map::const_iterator tmp_eph_iter_cnav = d_pvt_solver->gps_cnav_ephemeris_map.find(in[i][epoch].PRN); + std::map::const_iterator tmp_eph_iter_glo_gnav = d_pvt_solver->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN); if (((tmp_eph_iter_gps->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal).compare("1C") == 0)) or ((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal).compare("2S") == 0)) or ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal).compare("1B") == 0)) or ((tmp_eph_iter_gal->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal).compare("5X") == 0)) or ((tmp_eph_iter_glo_gnav->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal).compare("1G") == 0)) or ((tmp_eph_iter_glo_gnav->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal).compare("2G") == 0)) or ((tmp_eph_iter_cnav->second.i_satellite_PRN == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal).compare("L5") == 0))) { // store valid observables in a map. gnss_observables_map.insert(std::pair(i, in[i][epoch])); } - try + if (b_rtcm_enabled) { - if (d_ls_pvt->gps_ephemeris_map.size() > 0) + try { - if (tmp_eph_iter_gps != d_ls_pvt->gps_ephemeris_map.end()) + if (d_pvt_solver->gps_ephemeris_map.empty() == false) { - d_rtcm_printer->lock_time(d_ls_pvt->gps_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time + if (tmp_eph_iter_gps != d_pvt_solver->gps_ephemeris_map.cend()) + { + d_rtcm_printer->lock_time(d_pvt_solver->gps_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time + } + } + if (d_pvt_solver->galileo_ephemeris_map.empty() == false) + { + if (tmp_eph_iter_gal != d_pvt_solver->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->lock_time(d_pvt_solver->galileo_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time + } + } + if (d_pvt_solver->gps_cnav_ephemeris_map.empty() == false) + { + if (tmp_eph_iter_cnav != d_pvt_solver->gps_cnav_ephemeris_map.cend()) + { + d_rtcm_printer->lock_time(d_pvt_solver->gps_cnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time + } + } + if (d_pvt_solver->glonass_gnav_ephemeris_map.empty() == false) + { + if (tmp_eph_iter_glo_gnav != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->lock_time(d_pvt_solver->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time + } } } - if (d_ls_pvt->galileo_ephemeris_map.size() > 0) + catch (const boost::exception& ex) { - if (tmp_eph_iter_gal != d_ls_pvt->galileo_ephemeris_map.end()) - { - d_rtcm_printer->lock_time(d_ls_pvt->galileo_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time - } + std::cout << "RTCM boost exception: " << boost::diagnostic_information(ex) << std::endl; + LOG(ERROR) << "RTCM boost exception: " << boost::diagnostic_information(ex); } - if (d_ls_pvt->gps_cnav_ephemeris_map.size() > 0) + catch (const std::exception& ex) { - if (tmp_eph_iter_cnav != d_ls_pvt->gps_cnav_ephemeris_map.end()) - { - d_rtcm_printer->lock_time(d_ls_pvt->gps_cnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time - } + std::cout << "RTCM std exception: " << ex.what() << std::endl; + LOG(ERROR) << "RTCM std exception: " << ex.what(); } - if (d_ls_pvt->glonass_gnav_ephemeris_map.size() > 0) - { - if (tmp_eph_iter_glo_gnav != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - d_rtcm_printer->lock_time(d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time - } - } - } - catch (const boost::exception& ex) - { - std::cout << "RTCM boost exception: " << boost::diagnostic_information(ex) << std::endl; - LOG(ERROR) << "RTCM boost exception: " << boost::diagnostic_information(ex); - } - catch (const std::exception& ex) - { - std::cout << "RTCM std exception: " << ex.what() << std::endl; - LOG(ERROR) << "RTCM std exception: " << ex.what(); } } } // ############ 2 COMPUTE THE PVT ################################ - if (gnss_observables_map.size() > 0) + if (gnss_observables_map.empty() == false) { double current_RX_time = gnss_observables_map.begin()->second.RX_time; - unsigned int current_RX_time_ms = static_cast(current_RX_time * 1000.0); + uint32_t current_RX_time_ms = static_cast(current_RX_time * 1000.0); if (current_RX_time_ms % d_output_rate_ms == 0) { flag_compute_pvt_output = true; @@ -626,31 +1028,48 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item if (flag_compute_pvt_output == true) { // receiver clock correction is disabled to be coherent with the RINEX and RTCM standard - // std::cout << TEXT_RED << "(internal) accumulated RX clock offset: " << d_ls_pvt->get_time_offset_s() << "[s]" << TEXT_RESET << std::endl; - // for (std::map::iterator it = gnss_observables_map.begin(); it != gnss_observables_map.end(); ++it) + // std::cout << TEXT_RED << "(internal) accumulated RX clock offset: " << d_pvt_solver->get_time_offset_s() << "[s]" << TEXT_RESET << std::endl; + // for (std::map::iterator it = gnss_observables_map.begin(); it != gnss_observables_map.cend(); ++it) // { // todo: check if it has effect to correct the receiver time for the internal pvt solution // take into account that the RINEX obs with the RX time (integer ms) CAN NOT be corrected to keep the coherence in obs time - // it->second.Pseudorange_m = it->second.Pseudorange_m - d_ls_pvt->get_time_offset_s() * GPS_C_m_s; + // it->second.Pseudorange_m = it->second.Pseudorange_m - d_pvt_solver->get_time_offset_s() * GPS_C_m_s; // } - if (d_ls_pvt->get_PVT(gnss_observables_map, false)) + if (d_pvt_solver->get_PVT(gnss_observables_map, false)) { - if (current_RX_time_ms % d_display_rate_ms == 0) + //Optional debug code: export observables snapshot for rtklib unit testing + //std::cout << "step 1: save gnss_synchro map" << std::endl; + //save_gnss_synchro_map_xml("./gnss_synchro_map.xml"); + //getchar(); //stop the execution + //end debug + if (d_display_rate_ms != 0) { - flag_display_pvt = true; + if (current_RX_time_ms % d_display_rate_ms == 0) + { + flag_display_pvt = true; + } } - if (current_RX_time_ms % d_rtcm_MT1019_rate_ms == 0 and d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 + if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - flag_write_RTCM_1019_output = true; + if (current_RX_time_ms % d_rtcm_MT1019_rate_ms == 0) + { + flag_write_RTCM_1019_output = true; + } } - if (current_RX_time_ms % d_rtcm_MT1020_rate_ms == 0 and d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 + if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - flag_write_RTCM_1020_output = true; + if (current_RX_time_ms % d_rtcm_MT1020_rate_ms == 0) + { + flag_write_RTCM_1020_output = true; + } } - if (current_RX_time_ms % d_rtcm_MT1045_rate_ms == 0 and d_rtcm_MT1045_rate_ms != 0) + if (d_rtcm_MT1045_rate_ms != 0) { - flag_write_RTCM_1045_output = true; + if (current_RX_time_ms % d_rtcm_MT1045_rate_ms == 0) + { + flag_write_RTCM_1045_output = true; + } } // TODO: RTCM 1077, 1087 and 1097 are not used, so, disable the output rates // if (current_RX_time_ms % d_rtcm_MT1077_rate_ms==0 and d_rtcm_MT1077_rate_ms != 0) @@ -665,26 +1084,33 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item // { // last_RTCM_1097_output_time = current_RX_time; // } - - if (current_RX_time_ms % d_rtcm_MSM_rate_ms == 0 and d_rtcm_MSM_rate_ms != 0) + if (d_rtcm_MSM_rate_ms != 0) { - flag_write_RTCM_MSM_output = true; + if (current_RX_time_ms % d_rtcm_MSM_rate_ms == 0) + { + flag_write_RTCM_MSM_output = true; + } } - if (current_RX_time_ms % static_cast(d_rinexobs_rate_ms) == 0) + if (d_rinexobs_rate_ms != 0) { - flag_write_RINEX_obs_output = true; + if (current_RX_time_ms % static_cast(d_rinexobs_rate_ms) == 0) + { + flag_write_RINEX_obs_output = true; + } } - - if (current_RX_time_ms % static_cast(d_rinexnav_rate_ms) == 0) + if (d_rinexnav_rate_ms != 0) { - flag_write_RINEX_nav_output = true; + if (current_RX_time_ms % static_cast(d_rinexnav_rate_ms) == 0) + { + flag_write_RINEX_nav_output = true; + } } if (first_fix == true) { - std::cout << "First position fix at " << boost::posix_time::to_simple_string(d_ls_pvt->get_position_UTC_time()) - << " UTC is Lat = " << d_ls_pvt->get_latitude() << " [deg], Long = " << d_ls_pvt->get_longitude() - << " [deg], Height= " << d_ls_pvt->get_height() << " [m]" << std::endl; + std::cout << "First position fix at " << boost::posix_time::to_simple_string(d_pvt_solver->get_position_UTC_time()) + << " UTC is Lat = " << d_pvt_solver->get_latitude() << " [deg], Long = " << d_pvt_solver->get_longitude() + << " [deg], Height= " << d_pvt_solver->get_height() << " [m]" << std::endl; ttff_msgbuf ttff; ttff.mtype = 1; end = std::chrono::system_clock::now(); @@ -693,10 +1119,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item send_sys_v_ttff_msg(ttff); first_fix = false; } - d_kml_dump->print_position(d_ls_pvt, false); - d_gpx_dump->print_position(d_ls_pvt, false); - d_geojson_printer->print_position(d_ls_pvt, false); - d_nmea_printer->Print_Nmea_Line(d_ls_pvt, false); + if (d_kml_output_enabled) d_kml_dump->print_position(d_pvt_solver, false); + if (d_gpx_output_enabled) d_gpx_dump->print_position(d_pvt_solver, false); + if (d_geojson_output_enabled) d_geojson_printer->print_position(d_pvt_solver, false); + if (d_nmea_output_file_enabled) d_nmea_printer->Print_Nmea_Line(d_pvt_solver, false); /* * TYPE | RECEIVER @@ -732,571 +1158,630 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item * 29 | GPS L1 C/A + GLONASS L2 C/A * 30 | Galileo E1B + GLONASS L2 C/A * 31 | GPS L2C + GLONASS L2 C/A + * 32 | GPS L1 C/A + Galileo E1B + GPS L5 + Galileo E5a */ // ####################### RINEX FILES ################# - - std::map::const_iterator galileo_ephemeris_iter; - std::map::const_iterator gps_ephemeris_iter; - std::map::const_iterator gps_cnav_ephemeris_iter; - std::map::const_iterator glonass_gnav_ephemeris_iter; - std::map::const_iterator gnss_observables_iter; - - if (!b_rinex_header_written) // & we have utc data in nav message! + if (b_rinex_output_enabled) { - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); + std::map::const_iterator galileo_ephemeris_iter; + std::map::const_iterator gps_ephemeris_iter; + std::map::const_iterator gps_cnav_ephemeris_iter; + std::map::const_iterator glonass_gnav_ephemeris_iter; + if (!b_rinex_header_written) // & we have utc data in nav message! + { + galileo_ephemeris_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + gps_ephemeris_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + gps_cnav_ephemeris_iter = d_pvt_solver->gps_cnav_ephemeris_map.cbegin(); + glonass_gnav_ephemeris_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); + switch (type_of_rx) + { + case 1: // GPS L1 C/A only + if (gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, d_rx_time); + rp->rinex_nav_header(rp->navFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 2: // GPS L2C only + if (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend()) + { + std::string signal("2S"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navFile, d_pvt_solver->gps_cnav_iono, d_pvt_solver->gps_cnav_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 3: // GPS L5 only + if (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend()) + { + std::string signal("L5"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navFile, d_pvt_solver->gps_cnav_iono, d_pvt_solver->gps_cnav_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 4: // Galileo E1B only + if (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time); + rp->rinex_nav_header(rp->navGalFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 5: // Galileo E5a only + if (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + std::string signal("5X"); + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGalFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 6: // Galileo E5b only + if (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + std::string signal("7X"); + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGalFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 7: // GPS L1 C/A + GPS L2C + if ((gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + std::string signal("1C 2S"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 8: // GPS L1 + GPS L5 + if ((gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + std::string signal("1C L5"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 9: // GPS L1 C/A + Galileo E1B + if ((galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend())) + { + std::string gal_signal("1B"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 10: // GPS L1 C/A + Galileo E5a + if ((galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend())) + { + std::string gal_signal("5X"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 11: // GPS L1 C/A + Galileo E5b + if ((galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend())) + { + std::string gal_signal("7X"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 13: // L5+E5a + if ((galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + std::string gal_signal("5X"); + std::string gps_signal("L5"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gps_signal, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_pvt_solver->gps_cnav_iono, d_pvt_solver->gps_cnav_utc_model, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 14: // Galileo E1B + Galileo E5a + if ((galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend())) + { + std::string gal_signal("1B 5X"); + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gal_signal); + rp->rinex_nav_header(rp->navGalFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 15: // Galileo E1B + Galileo E5b + if ((galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend())) + { + std::string gal_signal("1B 7X"); + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gal_signal); + rp->rinex_nav_header(rp->navGalFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 23: // GLONASS L1 C/A only + if (glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + std::string signal("1G"); + rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGloFile, d_pvt_solver->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 24: // GLONASS L2 C/A only + if (glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + std::string signal("2G"); + rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGloFile, d_pvt_solver->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 25: // GLONASS L1 C/A + GLONASS L2 C/A + if (glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + std::string signal("1G 2G"); + rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGloFile, d_pvt_solver->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 26: // GPS L1 C/A + GLONASS L1 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend())) + { + std::string glo_signal("1G"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); + if (d_rinex_version == 3) + rp->rinex_nav_header(rp->navMixFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + if (d_rinex_version == 2) + { + rp->rinex_nav_header(rp->navFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model); + rp->rinex_nav_header(rp->navGloFile, d_pvt_solver->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + } + b_rinex_header_written = true; // do not write header anymore + } + break; + case 27: // Galileo E1B + GLONASS L1 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend())) + { + std::string glo_signal("1G"); + std::string gal_signal("1B"); + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 28: // GPS L2C + GLONASS L1 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + std::string glo_signal("1G"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); + rp->rinex_nav_header(rp->navMixFile, d_pvt_solver->gps_cnav_iono, d_pvt_solver->gps_cnav_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 29: // GPS L1 C/A + GLONASS L2 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend())) + { + std::string glo_signal("2G"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); + if (d_rinex_version == 3) + rp->rinex_nav_header(rp->navMixFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + if (d_rinex_version == 2) + { + rp->rinex_nav_header(rp->navFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model); + rp->rinex_nav_header(rp->navGloFile, d_pvt_solver->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + } + b_rinex_header_written = true; // do not write header anymore + } + break; + case 30: // Galileo E1B + GLONASS L2 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend())) + { + std::string glo_signal("2G"); + std::string gal_signal("1B"); + rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 31: // GPS L2C + GLONASS L2 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + std::string glo_signal("2G"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); + rp->rinex_nav_header(rp->navMixFile, d_pvt_solver->gps_cnav_iono, d_pvt_solver->gps_cnav_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + b_rinex_header_written = true; // do not write header anymore + } + break; + case 32: // L1+E1+L5+E5a + if ((gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend()) and + (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend()) and + (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend())) + { + std::string gal_signal("1B 5X"); + std::string gps_signal("1C L5"); + rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gps_signal, gal_signal); + rp->rinex_nav_header(rp->navMixFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_written = true; // do not write header anymore + } + break; + default: + break; + } + } + if (b_rinex_header_written) // The header is already written, we can now log the navigation message data + { + if (flag_write_RINEX_nav_output) + { + switch (type_of_rx) + { + case 1: // GPS L1 C/A only + rp->log_rinex_nav(rp->navFile, d_pvt_solver->gps_ephemeris_map); + break; + case 2: // GPS L2C only + rp->log_rinex_nav(rp->navFile, d_pvt_solver->gps_cnav_ephemeris_map); + break; + case 3: // GPS L5 only + rp->log_rinex_nav(rp->navFile, d_pvt_solver->gps_cnav_ephemeris_map); + break; + case 4: + case 5: + case 6: + rp->log_rinex_nav(rp->navGalFile, d_pvt_solver->galileo_ephemeris_map); + break; + case 7: // GPS L1 C/A + GPS L2C + rp->log_rinex_nav(rp->navFile, d_pvt_solver->gps_cnav_ephemeris_map); + break; + case 8: // L1+L5 + rp->log_rinex_nav(rp->navFile, d_pvt_solver->gps_ephemeris_map); + break; + case 9: + case 10: + case 11: + rp->log_rinex_nav(rp->navMixFile, d_pvt_solver->gps_ephemeris_map, d_pvt_solver->galileo_ephemeris_map); + break; + case 13: // L5+E5a + rp->log_rinex_nav(rp->navFile, d_pvt_solver->gps_cnav_ephemeris_map, d_pvt_solver->galileo_ephemeris_map); + break; + case 14: + case 15: + rp->log_rinex_nav(rp->navGalFile, d_pvt_solver->galileo_ephemeris_map); + break; + case 23: + case 24: + case 25: + rp->log_rinex_nav(rp->navGloFile, d_pvt_solver->glonass_gnav_ephemeris_map); + break; + case 26: // GPS L1 C/A + GLONASS L1 C/A + if (d_rinex_version == 3) + rp->log_rinex_nav(rp->navMixFile, d_pvt_solver->gps_ephemeris_map, d_pvt_solver->glonass_gnav_ephemeris_map); + if (d_rinex_version == 2) + { + rp->log_rinex_nav(rp->navFile, d_pvt_solver->gps_ephemeris_map); + rp->log_rinex_nav(rp->navGloFile, d_pvt_solver->glonass_gnav_ephemeris_map); + } + break; + case 27: // Galileo E1B + GLONASS L1 C/A + rp->log_rinex_nav(rp->navMixFile, d_pvt_solver->galileo_ephemeris_map, d_pvt_solver->glonass_gnav_ephemeris_map); + break; + case 28: // GPS L2C + GLONASS L1 C/A + rp->log_rinex_nav(rp->navMixFile, d_pvt_solver->gps_cnav_ephemeris_map, d_pvt_solver->glonass_gnav_ephemeris_map); + break; + case 29: // GPS L1 C/A + GLONASS L2 C/A + if (d_rinex_version == 3) + rp->log_rinex_nav(rp->navMixFile, d_pvt_solver->gps_ephemeris_map, d_pvt_solver->glonass_gnav_ephemeris_map); + if (d_rinex_version == 2) + { + rp->log_rinex_nav(rp->navFile, d_pvt_solver->gps_ephemeris_map); + rp->log_rinex_nav(rp->navGloFile, d_pvt_solver->glonass_gnav_ephemeris_map); + } + break; + case 30: // Galileo E1B + GLONASS L2 C/A + rp->log_rinex_nav(rp->navMixFile, d_pvt_solver->galileo_ephemeris_map, d_pvt_solver->glonass_gnav_ephemeris_map); + break; + case 31: // GPS L2C + GLONASS L2 C/A + rp->log_rinex_nav(rp->navMixFile, d_pvt_solver->gps_cnav_ephemeris_map, d_pvt_solver->glonass_gnav_ephemeris_map); + break; + case 32: // L1+E1+L5+E5a + rp->log_rinex_nav(rp->navMixFile, d_pvt_solver->gps_ephemeris_map, d_pvt_solver->galileo_ephemeris_map); + break; + default: + break; + } + } + galileo_ephemeris_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + gps_ephemeris_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + gps_cnav_ephemeris_iter = d_pvt_solver->gps_cnav_ephemeris_map.cbegin(); + glonass_gnav_ephemeris_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); - if (type_of_rx == 1) // GPS L1 C/A only - { - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + // Log observables into the RINEX file + if (flag_write_RINEX_obs_output) { - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, d_rx_time); - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 2) // GPS L2C only - { - if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time); - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 3) // GPS L5 only - { - if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time); - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 4) // Galileo E1B only - { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time); - rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 5) // Galileo E5a only - { - std::string signal("5X"); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 6) // Galileo E5b only - { - std::string signal("7X"); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 7) // GPS L1 C/A + GPS L2C - { - if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) - { - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time); - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); - b_rinex_header_written = true; // do not write header anymore - } - } - - if (type_of_rx == 9) // GPS L1 C/A + Galileo E1B - { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) - { - std::string gal_signal("1B"); - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 10) // GPS L1 C/A + Galileo E5a - { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) - { - std::string gal_signal("5X"); - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 11) // GPS L1 C/A + Galileo E5b - { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) - { - std::string gal_signal("7X"); - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gal_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 14) // Galileo E1B + Galileo E5a - { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) - { - std::string gal_signal("1B 5X"); - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gal_signal); - rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 15) // Galileo E1B + Galileo E5b - { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) - { - std::string gal_signal("1B 7X"); - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gal_signal); - rp->rinex_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 23) // GLONASS L1 C/A only - { - std::string signal("1G"); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 24) // GLONASS L2 C/A only - { - std::string signal("2G"); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 25) // GLONASS L1 C/A + GLONASS L2 C/A - { - std::string signal("1G 2G"); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); - b_rinex_header_written = true; // do not write header anymore - } - } - - if (type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) - { - std::string glo_signal("1G"); - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); - if (d_rinex_version == 3) - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - if (d_rinex_version == 2) + switch (type_of_rx) { - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); - } - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) - { - std::string glo_signal("1G"); - std::string gal_signal("1B"); - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal, gal_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 28) // GPS L2C + GLONASS L1 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) - { - std::string glo_signal("1G"); - rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 29) // GPS L1 C/A + GLONASS L2 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend())) - { - std::string glo_signal("2G"); - rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); - if (d_rinex_version == 3) - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - if (d_rinex_version == 2) - { - rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); - } - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 30) // Galileo E1B + GLONASS L2 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend())) - { - std::string glo_signal("2G"); - std::string gal_signal("1B"); - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal, gal_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - if (type_of_rx == 31) // GPS L2C + GLONASS L2 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) - { - std::string glo_signal("2G"); - rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_written = true; // do not write header anymore - } - } - } - if (b_rinex_header_written) // The header is already written, we can now log the navigation message data - { - if (flag_write_RINEX_nav_output) - { - if (type_of_rx == 1) // GPS L1 C/A only - { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); - } - if (type_of_rx == 2) // GPS L2C only - { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map); - } - if (type_of_rx == 3) // GPS L5 only - { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map); - } - if ((type_of_rx == 4) or (type_of_rx == 5) or (type_of_rx == 6)) // Galileo - { - rp->log_rinex_nav(rp->navGalFile, d_ls_pvt->galileo_ephemeris_map); - } - if (type_of_rx == 7) // GPS L1 C/A + GPS L2C - { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_cnav_ephemeris_map); - } - if ((type_of_rx == 9) or (type_of_rx == 10) or (type_of_rx == 11)) // GPS L1 C/A + Galileo - { - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->galileo_ephemeris_map); - } - if ((type_of_rx == 14) or (type_of_rx == 15)) // Galileo E1B + Galileo E5a - { - rp->log_rinex_nav(rp->navGalFile, d_ls_pvt->galileo_ephemeris_map); - } - if ((type_of_rx == 23) or (type_of_rx == 24) or (type_of_rx == 25)) // GLONASS L1 C/A, GLONASS L2 C/A - { - rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); - } - if (type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A - { - if (d_rinex_version == 3) - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - if (d_rinex_version == 2) - { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); - rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); - } - } - if (type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A - { - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->galileo_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - } - if (type_of_rx == 28) // GPS L2C + GLONASS L1 C/A - { - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_cnav_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - } - if (type_of_rx == 29) // GPS L1 C/A + GLONASS L2 C/A - { - if (d_rinex_version == 3) - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - if (d_rinex_version == 2) - { - rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); - rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); - } - } - if (type_of_rx == 30) // Galileo E1B + GLONASS L2 C/A - { - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->galileo_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - } - if (type_of_rx == 31) // GPS L2C + GLONASS L2 C/A - { - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_cnav_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); - } - } - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); - - // Log observables into the RINEX file - if (flag_write_RINEX_obs_output) - { - if (type_of_rx == 1) // GPS L1 C/A only - { - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); - rp->update_nav_header(rp->navFile, d_ls_pvt->gps_utc_model, d_ls_pvt->gps_iono); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 2) // GPS L2C only - { - if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); - rp->update_nav_header(rp->navFile, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->gps_cnav_iono); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 3) // GPS L5 - { - if (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); - rp->update_nav_header(rp->navFile, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->gps_cnav_iono); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 4) // Galileo E1B only - { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B"); - } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 5) // Galileo E5a only - { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "5X"); - } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 6) // Galileo E5b only - { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "7X"); - } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 7) // GPS L1 C/A + GPS L2C - { - if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end())) - { - rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); - rp->update_nav_header(rp->navFile, d_ls_pvt->gps_utc_model, d_ls_pvt->gps_iono); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 9) // GPS L1 C/A + Galileo E1B - { - if ((galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end())) - { - rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 14) // Galileo E1B + Galileo E5a - { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B 5X"); - } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 15) // Galileo E1B + Galileo E5b - { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B 7X"); - } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 23) // GLONASS L1 C/A only - { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1C"); - } - if (!b_rinex_header_updated and (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) - { - rp->update_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 24) // GLONASS L2 C/A only - { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "2C"); - } - if (!b_rinex_header_updated and (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) - { - rp->update_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 25) // GLONASS L1 C/A + GLONASS L2 C/A - { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1C 2C"); - } - if (!b_rinex_header_updated and (d_ls_pvt->glonass_gnav_utc_model.d_tau_c != 0)) - { - rp->update_nav_header(rp->navMixFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - rp->update_obs_header(rp->obsFile, d_ls_pvt->glonass_gnav_utc_model); - b_rinex_header_updated = true; - } - } - if (type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) and (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end())) - { - rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore - } - } - if (type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) and (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end())) - { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore - } - } - if (type_of_rx == 28) // GPS L2C + GLONASS L1 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) and (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end())) - { - rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated and (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore - } - } - if (type_of_rx == 29) // GPS L1 C/A + GLONASS L2 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end())) - { - rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated && (d_ls_pvt->gps_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore - } - } - if (type_of_rx == 30) // Galileo E1B + GLONASS L2 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end())) - { - rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated && (d_ls_pvt->galileo_utc_model.A0_6 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->galileo_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore - } - } - if (type_of_rx == 31) // GPS L2C + GLONASS L2 C/A - { - if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end())) - { - rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); - } - if (!b_rinex_header_updated && (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) - { - rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); - rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); - b_rinex_header_updated = true; // do not write header anymore + case 1: // GPS L1 C/A only + if (gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_utc_model); + rp->update_nav_header(rp->navFile, d_pvt_solver->gps_utc_model, d_pvt_solver->gps_iono); + b_rinex_header_updated = true; + } + break; + case 2: // GPS L2C only + if (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->gps_cnav_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_cnav_utc_model); + rp->update_nav_header(rp->navFile, d_pvt_solver->gps_cnav_utc_model, d_pvt_solver->gps_cnav_iono); + b_rinex_header_updated = true; + } + break; + case 3: // GPS L5 + if (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->gps_cnav_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_cnav_utc_model); + rp->update_nav_header(rp->navFile, d_pvt_solver->gps_cnav_utc_model, d_pvt_solver->gps_cnav_iono); + b_rinex_header_updated = true; + } + break; + case 4: // Galileo E1B only + if (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B"); + } + if (!b_rinex_header_updated and (d_pvt_solver->galileo_utc_model.A0_6 != 0)) + { + rp->update_nav_header(rp->navGalFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + rp->update_obs_header(rp->obsFile, d_pvt_solver->galileo_utc_model); + b_rinex_header_updated = true; + } + break; + case 5: // Galileo E5a only + if (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "5X"); + } + if (!b_rinex_header_updated and (d_pvt_solver->galileo_utc_model.A0_6 != 0)) + { + rp->update_nav_header(rp->navGalFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + rp->update_obs_header(rp->obsFile, d_pvt_solver->galileo_utc_model); + b_rinex_header_updated = true; + } + break; + case 6: // Galileo E5b only + if (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "7X"); + } + if (!b_rinex_header_updated and (d_pvt_solver->galileo_utc_model.A0_6 != 0)) + { + rp->update_nav_header(rp->navGalFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + rp->update_obs_header(rp->obsFile, d_pvt_solver->galileo_utc_model); + b_rinex_header_updated = true; + } + break; + case 7: // GPS L1 C/A + GPS L2C + if ((gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_utc_model); + rp->update_nav_header(rp->navFile, d_pvt_solver->gps_utc_model, d_pvt_solver->gps_iono); + b_rinex_header_updated = true; + } + break; + case 8: // L1+L5 + if ((gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and ((d_pvt_solver->gps_cnav_utc_model.d_A0 != 0) or (d_pvt_solver->gps_utc_model.d_A0 != 0))) + { + if (d_pvt_solver->gps_cnav_utc_model.d_A0 != 0) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_cnav_utc_model); + rp->update_nav_header(rp->navFile, d_pvt_solver->gps_cnav_utc_model, d_pvt_solver->gps_cnav_iono); + } + else + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_utc_model); + rp->update_nav_header(rp->navFile, d_pvt_solver->gps_utc_model, d_pvt_solver->gps_iono); + } + b_rinex_header_updated = true; + } + break; + case 9: // GPS L1 C/A + Galileo E1B + if ((galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) and (gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_utc_model); + rp->update_nav_header(rp->navMixFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_updated = true; + } + break; + case 13: // L5+E5a + if ((gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->gps_cnav_utc_model.d_A0 != 0) and (d_pvt_solver->galileo_utc_model.A0_6 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_cnav_utc_model); + rp->update_nav_header(rp->navMixFile, d_pvt_solver->gps_cnav_utc_model, d_pvt_solver->gps_cnav_iono, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + b_rinex_header_updated = true; // do not write header anymore + } + break; + case 14: // Galileo E1B + Galileo E5a + if (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B 5X"); + } + if (!b_rinex_header_updated and (d_pvt_solver->galileo_utc_model.A0_6 != 0)) + { + rp->update_nav_header(rp->navGalFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + rp->update_obs_header(rp->obsFile, d_pvt_solver->galileo_utc_model); + b_rinex_header_updated = true; + } + break; + case 15: // Galileo E1B + Galileo E5b + if (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1B 7X"); + } + if (!b_rinex_header_updated and (d_pvt_solver->galileo_utc_model.A0_6 != 0)) + { + rp->update_nav_header(rp->navGalFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + rp->update_obs_header(rp->obsFile, d_pvt_solver->galileo_utc_model); + b_rinex_header_updated = true; + } + break; + case 23: // GLONASS L1 C/A only + if (glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1C"); + } + if (!b_rinex_header_updated and (d_pvt_solver->glonass_gnav_utc_model.d_tau_c != 0)) + { + rp->update_nav_header(rp->navGloFile, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + rp->update_obs_header(rp->obsFile, d_pvt_solver->glonass_gnav_utc_model); + b_rinex_header_updated = true; + } + break; + case 24: // GLONASS L2 C/A only + if (glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "2C"); + } + if (!b_rinex_header_updated and (d_pvt_solver->glonass_gnav_utc_model.d_tau_c != 0)) + { + rp->update_nav_header(rp->navGloFile, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + rp->update_obs_header(rp->obsFile, d_pvt_solver->glonass_gnav_utc_model); + b_rinex_header_updated = true; + } + break; + case 25: // GLONASS L1 C/A + GLONASS L2 C/A + if (glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + rp->log_rinex_obs(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "1C 2C"); + } + if (!b_rinex_header_updated and (d_pvt_solver->glonass_gnav_utc_model.d_tau_c != 0)) + { + rp->update_nav_header(rp->navMixFile, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + rp->update_obs_header(rp->obsFile, d_pvt_solver->glonass_gnav_utc_model); + b_rinex_header_updated = true; + } + break; + case 26: // GPS L1 C/A + GLONASS L1 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_utc_model); + rp->update_nav_header(rp->navMixFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + break; + case 27: // Galileo E1B + GLONASS L1 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->galileo_utc_model.A0_6 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->galileo_utc_model); + rp->update_nav_header(rp->navMixFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + break; + case 28: // GPS L2C + GLONASS L1 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->gps_cnav_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_cnav_utc_model); + rp->update_nav_header(rp->navMixFile, d_pvt_solver->gps_cnav_iono, d_pvt_solver->gps_cnav_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + break; + case 29: // GPS L1 C/A + GLONASS L2 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->gps_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_utc_model); + rp->update_nav_header(rp->navMixFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + break; + case 30: // Galileo E1B + GLONASS L2 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->galileo_utc_model.A0_6 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->galileo_utc_model); + rp->update_nav_header(rp->navMixFile, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + break; + case 31: // GPS L2C + GLONASS L2 C/A + if ((glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and (d_pvt_solver->gps_cnav_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_cnav_utc_model); + rp->update_nav_header(rp->navMixFile, d_pvt_solver->gps_cnav_iono, d_pvt_solver->gps_cnav_utc_model, d_pvt_solver->glonass_gnav_utc_model, d_pvt_solver->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + break; + case 32: // L1+E1+L5+E5a + if ((gps_ephemeris_iter != d_pvt_solver->gps_ephemeris_map.cend()) and (gps_cnav_ephemeris_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend()) and (galileo_ephemeris_iter != d_pvt_solver->galileo_ephemeris_map.cend())) + { + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated and ((d_pvt_solver->gps_cnav_utc_model.d_A0 != 0) or (d_pvt_solver->gps_utc_model.d_A0 != 0)) and (d_pvt_solver->galileo_utc_model.A0_6 != 0)) + { + if (d_pvt_solver->gps_cnav_utc_model.d_A0 != 0) + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_cnav_utc_model); + rp->update_nav_header(rp->navMixFile, d_pvt_solver->gps_cnav_utc_model, d_pvt_solver->gps_cnav_iono, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + } + else + { + rp->update_obs_header(rp->obsFile, d_pvt_solver->gps_utc_model); + rp->update_nav_header(rp->navMixFile, d_pvt_solver->gps_iono, d_pvt_solver->gps_utc_model, d_pvt_solver->galileo_iono, d_pvt_solver->galileo_utc_model); + } + b_rinex_header_updated = true; // do not write header anymore + } + break; } } } @@ -1305,89 +1790,104 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item // ####################### RTCM MESSAGES ################# try { - if (b_rtcm_writing_started) + if (b_rtcm_writing_started and b_rtcm_enabled) { - if (type_of_rx == 1) // GPS L1 C/A + switch (type_of_rx) { + case 1: // GPS L1 C/A if (flag_write_RTCM_1019_output == true) { - for (std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - std::map::const_iterator gps_ephemeris_iter; - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } - } - if ((type_of_rx == 4) || (type_of_rx == 5) || (type_of_rx == 6) || (type_of_rx == 14) || (type_of_rx == 15)) // Galileo - { + break; + case 4: + case 5: + case 6: if (flag_write_RTCM_1045_output == true) { - for (std::map::const_iterator gal_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(gal_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - std::map::const_iterator gal_ephemeris_iter; - gal_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); - if (gal_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } - } - if (type_of_rx == 7) // GPS L1 C/A + GPS L2C - { + break; + case 7: // GPS L1 C/A + GPS L2C if (flag_write_RTCM_1019_output == true) { - for (std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - std::map::const_iterator gps_ephemeris_iter; - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - std::map::const_iterator gps_cnav_ephemeris_iter; - gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); - if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + std::map::const_iterator gps_cnav_eph_iter = d_pvt_solver->gps_cnav_ephemeris_map.cbegin(); + if ((gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) and (gps_cnav_eph_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, gps_cnav_eph_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } - } - if (type_of_rx == 9) // GPS L1 C/A + Galileo E1B - { + break; + case 8: // L1+L5 if (flag_write_RTCM_1019_output == true) { - for (gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.begin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } + } + if (flag_write_RTCM_MSM_output == true) + { + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + std::map::const_iterator gps_cnav_eph_iter = d_pvt_solver->gps_cnav_ephemeris_map.cbegin(); + if ((gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) and (gps_cnav_eph_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, gps_cnav_eph_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + break; + case 9: // GPS L1 C/A + Galileo E1B + if (flag_write_RTCM_1019_output == true) + { + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (flag_write_RTCM_1045_output == true) { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.begin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - //gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - //galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - unsigned int i = 0; + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + int gps_channel = 0; + int gal_channel = 0; for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { std::string system(&gnss_observables_iter->second.System, 1); @@ -1396,10 +1896,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item if (system.compare("G") == 0) { // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + gps_eph_iter = d_pvt_solver->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) { - gps_channel = i; + gps_channel = 1; } } } @@ -1407,71 +1907,108 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (system.compare("E") == 0) { - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) { - gal_channel = i; + gal_channel = 1; } } } - i++; } - if (flag_write_RTCM_MSM_output == true) + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - if (flag_write_RTCM_MSM_output == true) + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) { - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } - } - if ((type_of_rx == 23) || (type_of_rx == 24) || (type_of_rx == 25)) // GLONASS - { + break; + case 13: // L5+E5a + if (flag_write_RTCM_1045_output == true) + { + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } + } + + if (flag_write_RTCM_MSM_output == true) + { + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + std::map::const_iterator gps_cnav_eph_iter = d_pvt_solver->gps_cnav_ephemeris_map.cbegin(); + if (gps_cnav_eph_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, gps_cnav_eph_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + break; + case 14: + case 15: + if (flag_write_RTCM_1045_output == true) + { + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } + } + if (flag_write_RTCM_MSM_output == true) + { + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + break; + case 23: + case 24: + case 25: if (flag_write_RTCM_1020_output == true) { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_pvt_solver->glonass_gnav_utc_model); } } - - std::map::const_iterator glo_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); - - if (glo_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + if (flag_write_RTCM_MSM_output == true) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glo_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + std::map::const_iterator glo_gnav_ephemeris_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); + if (glo_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glo_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } } b_rtcm_writing_started = true; - } - if (type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A - { + break; + case 26: // GPS L1 C/A + GLONASS L1 C/A if (flag_write_RTCM_1019_output == true) { - for (gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (flag_write_RTCM_1020_output == true) { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_pvt_solver->glonass_gnav_utc_model); } } if (flag_write_RTCM_MSM_output == true) { - //gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - //galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - unsigned int i = 0; - for (gnss_observables_iter = gnss_observables_map.begin(); gnss_observables_iter != gnss_observables_map.end(); gnss_observables_iter++) + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + int gps_channel = 0; + int glo_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { std::string system(&gnss_observables_iter->second.System, 1); if (gps_channel == 0) @@ -1479,10 +2016,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item if (system.compare("G") == 0) { // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + gps_eph_iter = d_pvt_solver->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) { - gps_channel = i; + gps_channel = 1; } } } @@ -1490,52 +2027,47 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (system.compare("R") == 0) { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) { - glo_channel = i; + glo_channel = 1; } } } - i++; } - if (flag_write_RTCM_MSM_output == true) + + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - if (flag_write_RTCM_MSM_output == true) + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) { - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } - } - if (type_of_rx == 27) // GLONASS L1 C/A + Galileo E1B - { + break; + case 27: // GLONASS L1 C/A + Galileo E1B if (flag_write_RTCM_1020_output == true) { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_pvt_solver->glonass_gnav_utc_model); } } if (flag_write_RTCM_1045_output == true) { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - // galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - unsigned int i = 0; + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); + int gal_channel = 0; + int glo_channel = 0; for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { std::string system(&gnss_observables_iter->second.System, 1); @@ -1544,10 +2076,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item if (system.compare("E") == 0) { // This is a channel with valid GPS signal - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) { - gal_channel = i; + gal_channel = 1; } } } @@ -1555,53 +2087,47 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (system.compare("R") == 0) { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) { - glo_channel = i; + glo_channel = 1; } } } - i++; } - if (flag_write_RTCM_MSM_output == true) + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - if (flag_write_RTCM_MSM_output == true) + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } - } - if (type_of_rx == 29) // GPS L1 C/A + GLONASS L2 C/A - { + break; + case 29: // GPS L1 C/A + GLONASS L2 C/A if (flag_write_RTCM_1019_output == true) { - for (gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (flag_write_RTCM_1020_output == true) { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_pvt_solver->glonass_gnav_utc_model); } } if (flag_write_RTCM_MSM_output == true) { - // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - // galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - unsigned int i = 0; - for (gnss_observables_iter = gnss_observables_map.begin(); gnss_observables_iter != gnss_observables_map.end(); gnss_observables_iter++) + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); + int gps_channel = 0; + int glo_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { std::string system(&gnss_observables_iter->second.System, 1); if (gps_channel == 0) @@ -1609,10 +2135,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item if (system.compare("G") == 0) { // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + gps_eph_iter = d_pvt_solver->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) { - gps_channel = i; + gps_channel = 1; } } } @@ -1620,52 +2146,46 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (system.compare("R") == 0) { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) { - glo_channel = i; + glo_channel = 1; } } } - i++; } - if (flag_write_RTCM_MSM_output == true) + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - if (flag_write_RTCM_MSM_output == true) + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) { - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } - } - if (type_of_rx == 30) // GLONASS L2 C/A + Galileo E1B - { + break; + case 30: // GLONASS L2 C/A + Galileo E1B if (flag_write_RTCM_1020_output == true) { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_pvt_solver->glonass_gnav_utc_model); } } if (flag_write_RTCM_1045_output == true) { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } if (flag_write_RTCM_MSM_output == true) { - // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - // galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - unsigned int i = 0; + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); + int gal_channel = 0; + int glo_channel = 0; for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { std::string system(&gnss_observables_iter->second.System, 1); @@ -1674,10 +2194,10 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item if (system.compare("E") == 0) { // This is a channel with valid GPS signal - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) { - gal_channel = i; + gal_channel = 1; } } } @@ -1685,387 +2205,593 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item { if (system.compare("R") == 0) { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) { - glo_channel = i; + glo_channel = 1; } } } - i++; } - if (flag_write_RTCM_MSM_output == true) + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) { - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - if (flag_write_RTCM_MSM_output == true) + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) { - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } } + break; + case 32: // L1+E1+L5+E5a + if (flag_write_RTCM_1019_output == true) + { + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } + } + if (flag_write_RTCM_1045_output == true) + { + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } + } + if (flag_write_RTCM_MSM_output == true) + { + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + int gal_channel = 0; + int gps_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + { + std::string system(&gnss_observables_iter->second.System, 1); + if (gal_channel == 0) + { + if (system.compare("E") == 0) + { + // This is a channel with valid GPS signal + gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + gal_channel = 1; + } + } + } + if (gps_channel == 0) + { + if (system.compare("G") == 0) + { + gps_eph_iter = d_pvt_solver->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + gps_channel = 1; + } + } + } + } + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + break; + default: + break; } } - if (!b_rtcm_writing_started) // the first time + if (!b_rtcm_writing_started and b_rtcm_enabled) // the first time { - if (type_of_rx == 1) // GPS L1 C/A - { - for (std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) - { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); - } - - std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - b_rtcm_writing_started = true; - } - if ((type_of_rx == 4) || (type_of_rx == 5) || (type_of_rx == 6) || (type_of_rx == 14) || (type_of_rx == 15)) // Galileo - { - for (std::map::const_iterator gal_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gal_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); gal_ephemeris_iter++) - { - d_rtcm_printer->Print_Rtcm_MT1045(gal_ephemeris_iter->second); - } - - std::map::const_iterator gal_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); - - if (gal_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - b_rtcm_writing_started = true; - } - if (type_of_rx == 7) // GPS L1 C/A + GPS L2C - { - for (std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) - { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); - } - - std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); - std::map::const_iterator gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin(); - - if ((gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend())) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, gps_cnav_ephemeris_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - b_rtcm_writing_started = true; - } - if (type_of_rx == 9) // GPS L1 C/A + Galileo E1B + switch (type_of_rx) { + case 1: // GPS L1 C/A if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (std::map::const_iterator gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } + } + if (d_rtcm_MSM_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + b_rtcm_writing_started = true; + break; + case 4: + case 5: + case 6: + if (d_rtcm_MT1045_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } + } + if (d_rtcm_MSM_rate_ms != 0) + { + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + b_rtcm_writing_started = true; + break; + case 7: // GPS L1 C/A + GPS L2C + if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } + } + if (d_rtcm_MSM_rate_ms != 0) + { + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + std::map::const_iterator gps_cnav_eph_iter = d_pvt_solver->gps_cnav_ephemeris_map.cbegin(); + if ((gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) and (gps_cnav_eph_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, gps_cnav_eph_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + b_rtcm_writing_started = true; + break; + case 8: // L1+L5 + if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } + } + if (d_rtcm_MSM_rate_ms != 0) + { + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + std::map::const_iterator gps_cnav_eph_iter = d_pvt_solver->gps_cnav_ephemeris_map.cbegin(); + if ((gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) and (gps_cnav_eph_iter != d_pvt_solver->gps_cnav_ephemeris_map.cend())) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, gps_cnav_eph_iter->second, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + b_rtcm_writing_started = true; + break; + case 9: // GPS L1 C/A + Galileo E1B + if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (d_rtcm_MT1045_rate_ms != 0) { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.begin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } - - unsigned int i = 0; - for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + if (d_rtcm_MSM_rate_ms != 0) { - std::string system(&gnss_observables_iter->second.System, 1); - if (gps_channel == 0) + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + int gps_channel = 0; + int gal_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { - if (system.compare("G") == 0) + std::string system(&gnss_observables_iter->second.System, 1); + if (gps_channel == 0) { - // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) + if (system.compare("G") == 0) { - gps_channel = i; + // This is a channel with valid GPS signal + gps_eph_iter = d_pvt_solver->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + gps_channel = 1; + } + } + } + if (gal_channel == 0) + { + if (system.compare("E") == 0) + { + gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + gal_channel = 1; + } } } } - if (gal_channel == 0) + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) { - if (system.compare("E") == 0) - { - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - gal_channel = i; - } - } + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - i++; - } - - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end() && (d_rtcm_MT1077_rate_ms != 0)) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end() && (d_rtcm_MT1097_rate_ms != 0)) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } b_rtcm_writing_started = true; - } - if ((type_of_rx == 23) || (type_of_rx == 24) || (type_of_rx == 25)) // GLONASS - { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + break; + + case 13: // L5+E5a + if (d_rtcm_MT1045_rate_ms != 0) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } } - - std::map::const_iterator glo_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); - - if (glo_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) + if (d_rtcm_MSM_rate_ms != 0) { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glo_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend() and (d_rtcm_MT1097_rate_ms != 0)) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } } b_rtcm_writing_started = true; - } - if (type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A - { + break; + case 14: + case 15: + if (d_rtcm_MT1045_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } + } + if (d_rtcm_MSM_rate_ms != 0) + { + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + b_rtcm_writing_started = true; + break; + case 23: + case 24: + case 25: + if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for (std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_pvt_solver->glonass_gnav_utc_model); + } + } + if (d_rtcm_MSM_rate_ms != 0) + { + std::map::const_iterator glo_gnav_ephemeris_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); + if (glo_gnav_ephemeris_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glo_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + b_rtcm_writing_started = true; + break; + case 26: // GPS L1 C/A + GLONASS L1 C/A if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_pvt_solver->glonass_gnav_utc_model); } } - - // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - // galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - unsigned int i = 0; - for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + if (d_rtcm_MSM_rate_ms != 0) { - std::string system(&gnss_observables_iter->second.System, 1); - if (gps_channel == 0) + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); + int gps_channel = 0; + int glo_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { - if (system.compare("G") == 0) + std::string system(&gnss_observables_iter->second.System, 1); + if (gps_channel == 0) { - // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + if (system.compare("G") == 0) { - gps_channel = i; + // This is a channel with valid GPS signal + gps_eph_iter = d_pvt_solver->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + gps_channel = 1; + } + } + } + if (glo_channel == 0) + { + if (system.compare("R") == 0) + { + glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + glo_channel = 1; + } } } } - if (glo_channel == 0) + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) { - if (system.compare("R") == 0) - { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - glo_channel = i; - } - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - i++; } - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - b_rtcm_writing_started = true; - } - if (type_of_rx == 27) // GLONASS L1 C/A + Galileo E1B - { + break; + case 27: // GLONASS L1 C/A + Galileo E1B if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_pvt_solver->glonass_gnav_utc_model); } } if (d_rtcm_MT1045_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } - - unsigned int i = 0; - for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + if (d_rtcm_MSM_rate_ms != 0) { - std::string system(&gnss_observables_iter->second.System, 1); - if (gal_channel == 0) + int gal_channel = 0; + int glo_channel = 0; + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { - if (system.compare("E") == 0) + std::string system(&gnss_observables_iter->second.System, 1); + if (gal_channel == 0) { - // This is a channel with valid GPS signal - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + if (system.compare("E") == 0) { - gal_channel = i; + // This is a channel with valid GPS signal + gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + gal_channel = 1; + } + } + } + if (glo_channel == 0) + { + if (system.compare("R") == 0) + { + glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + glo_channel = 1; + } } } } - if (glo_channel == 0) + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) { - if (system.compare("R") == 0) - { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - glo_channel = i; - } - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - i++; } - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - } - if (type_of_rx == 29) // GPS L1 C/A + GLONASS L2 C/A - { + b_rtcm_writing_started = true; + break; + case 29: // GPS L1 C/A + GLONASS L2 C/A if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend(); gps_ephemeris_iter++) + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1019(gps_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); } } if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_pvt_solver->glonass_gnav_utc_model); } } - - // gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.end(); - // galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.end(); - unsigned int i = 0; - for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + if (d_rtcm_MSM_rate_ms != 0) { - std::string system(&gnss_observables_iter->second.System, 1); - if (gps_channel == 0) + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); + std::map::const_iterator gnss_observables_iter; + int gps_channel = 0; + int glo_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { - if (system.compare("G") == 0) + std::string system(&gnss_observables_iter->second.System, 1); + if (gps_channel == 0) { - // This is a channel with valid GPS signal - gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) + if (system.compare("G") == 0) { - gps_channel = i; + // This is a channel with valid GPS signal + gps_eph_iter = d_pvt_solver->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + gps_channel = 1; + } + } + } + if (glo_channel == 0) + { + if (system.compare("R") == 0) + { + glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + glo_channel = 1; + } } } } - if (glo_channel == 0) + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) { - if (system.compare("R") == 0) - { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - glo_channel = i; - } - } + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); } - i++; - } - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - if (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.cend()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, gps_ephemeris_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } } - b_rtcm_writing_started = true; - } - if (type_of_rx == 30) // GLONASS L2 C/A + Galileo E1B - { + break; + case 30: // GLONASS L2 C/A + Galileo E1B if (d_rtcm_MT1020_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (std::map::const_iterator glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend(); glonass_gnav_ephemeris_iter++) + for (std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend(); glonass_gnav_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_ephemeris_iter->second, d_ls_pvt->glonass_gnav_utc_model); + d_rtcm_printer->Print_Rtcm_MT1020(glonass_gnav_eph_iter->second, d_pvt_solver->glonass_gnav_utc_model); } } if (d_rtcm_MT1045_rate_ms != 0) // allows deactivating messages by setting rate = 0 { - for (galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend(); galileo_ephemeris_iter++) + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) { - d_rtcm_printer->Print_Rtcm_MT1045(galileo_ephemeris_iter->second); + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); } } - - unsigned int i = 0; - for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + if (d_rtcm_MSM_rate_ms != 0) { - std::string system(&gnss_observables_iter->second.System, 1); - if (gal_channel == 0) + int gal_channel = 0; + int glo_channel = 0; + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + std::map::const_iterator glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.cbegin(); + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) { - if (system.compare("E") == 0) + std::string system(&gnss_observables_iter->second.System, 1); + if (gal_channel == 0) { - // This is a channel with valid GPS signal - galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.cend()) + if (system.compare("E") == 0) { - gal_channel = i; + // This is a channel with valid GPS signal + gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + gal_channel = 1; + } + } + } + if (glo_channel == 0) + { + if (system.compare("R") == 0) + { + glonass_gnav_eph_iter = d_pvt_solver->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + glo_channel = 1; + } } } } - if (glo_channel == 0) + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) { - if (system.compare("R") == 0) + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (glonass_gnav_eph_iter != d_pvt_solver->glonass_gnav_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_eph_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + } + b_rtcm_writing_started = true; + break; + case 32: // L1+E1+L5+E5a + if (d_rtcm_MT1019_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for (std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend(); gps_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1019(gps_eph_iter->second); + } + } + if (d_rtcm_MT1045_rate_ms != 0) // allows deactivating messages by setting rate = 0 + { + for (std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend(); gal_eph_iter++) + { + d_rtcm_printer->Print_Rtcm_MT1045(gal_eph_iter->second); + } + } + if (d_rtcm_MSM_rate_ms != 0) + { + std::map::const_iterator gnss_observables_iter; + std::map::const_iterator gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.cbegin(); + std::map::const_iterator gps_eph_iter = d_pvt_solver->gps_ephemeris_map.cbegin(); + int gps_channel = 0; + int gal_channel = 0; + for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); gnss_observables_iter++) + { + std::string system(&gnss_observables_iter->second.System, 1); + if (gps_channel == 0) { - glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.find(gnss_observables_iter->second.PRN); - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) + if (system.compare("G") == 0) { - glo_channel = i; + // This is a channel with valid GPS signal + gps_eph_iter = d_pvt_solver->gps_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + gps_channel = 1; + } + } + } + if (gal_channel == 0) + { + if (system.compare("E") == 0) + { + gal_eph_iter = d_pvt_solver->galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + gal_channel = 1; + } } } } - i++; - } - if (galileo_ephemeris_iter != d_ls_pvt->galileo_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, galileo_ephemeris_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); - } - if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) - { - d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, {}, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + if (gps_eph_iter != d_pvt_solver->gps_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, gps_eph_iter->second, {}, {}, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } + if (gal_eph_iter != d_pvt_solver->galileo_ephemeris_map.cend()) + { + d_rtcm_printer->Print_Rtcm_MSM(7, {}, {}, gal_eph_iter->second, {}, d_rx_time, gnss_observables_map, 0, 0, 0, 0, 0); + } } + b_rtcm_writing_started = true; + break; + default: + break; } } } - catch (const boost::exception& ex) { std::cout << "RTCM boost exception: " << boost::diagnostic_information(ex) << std::endl; @@ -2080,59 +2806,37 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item } // DEBUG MESSAGE: Display position in console output - if (d_ls_pvt->is_valid_position() and flag_display_pvt) + if (d_pvt_solver->is_valid_position() and flag_display_pvt) { std::streamsize ss = std::cout.precision(); // save current precision std::cout.setf(std::ios::fixed, std::ios::floatfield); - auto facet = new boost::posix_time::time_facet("%Y-%b-%d %H:%M:%S.%f %z"); std::cout.imbue(std::locale(std::cout.getloc(), facet)); std::cout << TEXT_BOLD_GREEN - << "Position at " << d_ls_pvt->get_position_UTC_time() - << " UTC using " << d_ls_pvt->get_num_valid_observations() + << "Position at " << d_pvt_solver->get_position_UTC_time() + << " UTC using " << d_pvt_solver->get_num_valid_observations() << std::fixed << std::setprecision(9) - << " observations is Lat = " << d_ls_pvt->get_latitude() << " [deg], Long = " << d_ls_pvt->get_longitude() + << " observations is Lat = " << d_pvt_solver->get_latitude() << " [deg], Long = " << d_pvt_solver->get_longitude() << std::fixed << std::setprecision(3) - << " [deg], Height = " << d_ls_pvt->get_height() << " [m]" << TEXT_RESET << std::endl; + << " [deg], Height = " << d_pvt_solver->get_height() << " [m]" << TEXT_RESET << std::endl; std::cout << std::setprecision(ss); - LOG(INFO) << "RX clock offset: " << d_ls_pvt->get_time_offset_s() << "[s]"; + DLOG(INFO) << "RX clock offset: " << d_pvt_solver->get_time_offset_s() << "[s]"; // boost::posix_time::ptime p_time; - // gtime_t rtklib_utc_time = gpst2time(adjgpsweek(d_ls_pvt->gps_ephemeris_map.cbegin()->second.i_GPS_week), d_rx_time); + // gtime_t rtklib_utc_time = gpst2time(adjgpsweek(d_pvt_solver->gps_ephemeris_map.cbegin()->second.i_GPS_week), d_rx_time); // p_time = boost::posix_time::from_time_t(rtklib_utc_time.time); // p_time += boost::posix_time::microseconds(round(rtklib_utc_time.sec * 1e6)); // std::cout << TEXT_MAGENTA << "Observable RX time (GPST) " << boost::posix_time::to_simple_string(p_time) << TEXT_RESET << std::endl; - LOG(INFO) << "Position at " << boost::posix_time::to_simple_string(d_ls_pvt->get_position_UTC_time()) - << " UTC using " << d_ls_pvt->get_num_valid_observations() << " observations is Lat = " << d_ls_pvt->get_latitude() << " [deg], Long = " << d_ls_pvt->get_longitude() - << " [deg], Height = " << d_ls_pvt->get_height() << " [m]"; + DLOG(INFO) << "Position at " << boost::posix_time::to_simple_string(d_pvt_solver->get_position_UTC_time()) + << " UTC using " << d_pvt_solver->get_num_valid_observations() << " observations is Lat = " << d_pvt_solver->get_latitude() << " [deg], Long = " << d_pvt_solver->get_longitude() + << " [deg], Height = " << d_pvt_solver->get_height() << " [m]"; - /* std::cout << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_ls_pvt->get_position_UTC_time()) - << " UTC using "<< d_ls_pvt->get_num_valid_observations() <<" observations is HDOP = " << d_ls_pvt->get_hdop() << " VDOP = " - << d_ls_pvt->get_vdop() - << " GDOP = " << d_ls_pvt->get_gdop() << std::endl; */ - } - - // MULTIPLEXED FILE RECORDING - Record results to file - if (d_dump == true) - { - try - { - double tmp_double; - for (unsigned int i = 0; i < d_nchannels; i++) - { - tmp_double = in[i][epoch].Pseudorange_m; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = 0; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - d_dump_file.write(reinterpret_cast(&d_rx_time), sizeof(double)); - } - } - catch (const std::ifstream::failure& e) - { - LOG(WARNING) << "Exception writing observables dump file " << e.what(); - } + /* std::cout << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_pvt_solver->get_position_UTC_time()) + << " UTC using "<< d_pvt_solver->get_num_valid_observations() <<" observations is HDOP = " << d_pvt_solver->get_hdop() << " VDOP = " + << d_pvt_solver->get_vdop() + << " GDOP = " << d_pvt_solver->get_gdop() << std::endl; */ } } } diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h index 17b735b12..2f6bd32f0 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h @@ -31,19 +31,23 @@ #ifndef GNSS_SDR_RTKLIB_PVT_CC_H #define GNSS_SDR_RTKLIB_PVT_CC_H - +#include "gps_ephemeris.h" #include "nmea_printer.h" #include "kml_printer.h" #include "gpx_printer.h" #include "geojson_printer.h" #include "rinex_printer.h" #include "rtcm_printer.h" +#include "pvt_conf.h" #include "rtklib_solver.h" +#include +#include #include #include #include #include #include +#include #include #include #include @@ -53,78 +57,48 @@ class rtklib_pvt_cc; typedef boost::shared_ptr rtklib_pvt_cc_sptr; -rtklib_pvt_cc_sptr rtklib_make_pvt_cc(unsigned int n_channels, - bool dump, - std::string dump_filename, - int output_rate_ms, - int display_rate_ms, - bool flag_nmea_tty_port, - std::string nmea_dump_filename, - std::string nmea_dump_devname, - int rinex_version, - int rinexobs_rate_ms, - int rinexnav_rate_ms, - bool flag_rtcm_server, - bool flag_rtcm_tty_port, - unsigned short rtcm_tcp_port, - unsigned short rtcm_station_id, - std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname, - const unsigned int type_of_receiver, +rtklib_pvt_cc_sptr rtklib_make_pvt_cc(uint32_t n_channels, + const Pvt_Conf& conf_, rtk_t& rtk); /*! - * \brief This class implements a block that computes the PVT solution with Galileo E1 signals + * \brief This class implements a block that computes the PVT solution using the RTKLIB integrated library */ class rtklib_pvt_cc : public gr::sync_block { private: - friend rtklib_pvt_cc_sptr rtklib_make_pvt_cc(unsigned int nchannels, - bool dump, - std::string dump_filename, - int output_rate_ms, - int display_rate_ms, - bool flag_nmea_tty_port, - std::string nmea_dump_filename, - std::string nmea_dump_devname, - int rinex_version, - int rinexobs_rate_ms, - int rinexnav_rate_ms, - bool flag_rtcm_server, - bool flag_rtcm_tty_port, - unsigned short rtcm_tcp_port, - unsigned short rtcm_station_id, - std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname, - const unsigned int type_of_receiver, + friend rtklib_pvt_cc_sptr rtklib_make_pvt_cc(uint32_t nchannels, + const Pvt_Conf& conf_, rtk_t& rtk); void msg_handler_telemetry(pmt::pmt_t msg); bool d_dump; + bool d_dump_mat; + bool b_rinex_output_enabled; bool b_rinex_header_written; bool b_rinex_header_updated; double d_rinex_version; - int d_rinexobs_rate_ms; - int d_rinexnav_rate_ms; + int32_t d_rinexobs_rate_ms; + int32_t d_rinexnav_rate_ms; bool b_rtcm_writing_started; - int d_rtcm_MT1045_rate_ms; //!< Galileo Broadcast Ephemeris - int d_rtcm_MT1019_rate_ms; //!< GPS Broadcast Ephemeris (orbits) - int d_rtcm_MT1020_rate_ms; //!< GLONASS Broadcast Ephemeris (orbits) - int d_rtcm_MT1077_rate_ms; //!< The type 7 Multiple Signal Message format for the USA’s GPS system, popular - int d_rtcm_MT1087_rate_ms; //!< GLONASS MSM7. The type 7 Multiple Signal Message format for the Russian GLONASS system - int d_rtcm_MT1097_rate_ms; //!< Galileo MSM7. The type 7 Multiple Signal Message format for Europe’s Galileo system - int d_rtcm_MSM_rate_ms; + bool b_rtcm_enabled; + int32_t d_rtcm_MT1045_rate_ms; //!< Galileo Broadcast Ephemeris + int32_t d_rtcm_MT1019_rate_ms; //!< GPS Broadcast Ephemeris (orbits) + int32_t d_rtcm_MT1020_rate_ms; //!< GLONASS Broadcast Ephemeris (orbits) + int32_t d_rtcm_MT1077_rate_ms; //!< The type 7 Multiple Signal Message format for the USA’s GPS system, popular + int32_t d_rtcm_MT1087_rate_ms; //!< GLONASS MSM7. The type 7 Multiple Signal Message format for the Russian GLONASS system + int32_t d_rtcm_MT1097_rate_ms; //!< Galileo MSM7. The type 7 Multiple Signal Message format for Europe’s Galileo system + int32_t d_rtcm_MSM_rate_ms; - int d_last_status_print_seg; //for status printer + int32_t d_last_status_print_seg; //for status printer - unsigned int d_nchannels; + uint32_t d_nchannels; std::string d_dump_filename; - std::ofstream d_dump_file; - int d_output_rate_ms; - int d_display_rate_ms; + int32_t d_output_rate_ms; + int32_t d_display_rate_ms; std::shared_ptr rp; std::shared_ptr d_kml_dump; @@ -134,12 +108,17 @@ private: std::shared_ptr d_rtcm_printer; double d_rx_time; - std::shared_ptr d_ls_pvt; + bool d_geojson_output_enabled; + bool d_gpx_output_enabled; + bool d_kml_output_enabled; + bool d_nmea_output_file_enabled; + + std::shared_ptr d_pvt_solver; std::map gnss_observables_map; bool observables_pairCompare_min(const std::pair& a, const std::pair& b); - unsigned int type_of_rx; + uint32_t type_of_rx; bool first_fix; key_t sysv_msg_key; @@ -152,32 +131,51 @@ private: bool send_sys_v_ttff_msg(ttff_msgbuf ttff); std::chrono::time_point start, end; + bool save_gnss_synchro_map_xml(const std::string file_name); //debug helper function + + bool load_gnss_synchro_map_xml(const std::string file_name); //debug helper function + + bool d_xml_storage; + std::string xml_base_path; + + inline std::time_t to_time_t(boost::posix_time::ptime pt) + { + return (pt - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_seconds(); + } + + public: - rtklib_pvt_cc(unsigned int nchannels, - bool dump, std::string dump_filename, - int output_rate_ms, - int display_rate_ms, - bool flag_nmea_tty_port, - std::string nmea_dump_filename, - std::string nmea_dump_devname, - int rinex_version, - int rinexobs_rate_ms, - int rinexnav_rate_ms, - bool flag_rtcm_server, - bool flag_rtcm_tty_port, - unsigned short rtcm_tcp_port, - unsigned short rtcm_station_id, - std::map rtcm_msg_rate_ms, - std::string rtcm_dump_devname, - const unsigned int type_of_receiver, + rtklib_pvt_cc(uint32_t nchannels, + const Pvt_Conf& conf_, rtk_t& rtk); /*! - * \brief Get latest set of GPS L1 ephemeris from PVT block + * \brief Get latest set of ephemeris from PVT block * - * It is used to save the assistance data at the receiver shutdown */ - std::map get_GPS_L1_ephemeris_map(); + std::map get_gps_ephemeris_map() const; + + std::map get_gps_almanac_map() const; + + std::map get_galileo_ephemeris_map() const; + + std::map get_galileo_almanac_map() const; + + /*! + * \brief Clear all ephemeris information and the almanacs for GPS and Galileo + * + */ + void clear_ephemeris(); + + /*! + * \brief Get the latest Position WGS84 [deg], Ground Velocity, Course over Ground, and UTC Time, if available + */ + bool get_latest_PVT(double* longitude_deg, + double* latitude_deg, + double* height_m, + double* ground_speed_kmh, + double* course_over_ground_deg, + time_t* UTC_time); ~rtklib_pvt_cc(); //!< Default destructor diff --git a/src/algorithms/PVT/libs/CMakeLists.txt b/src/algorithms/PVT/libs/CMakeLists.txt index 82d733a19..cd306531a 100644 --- a/src/algorithms/PVT/libs/CMakeLists.txt +++ b/src/algorithms/PVT/libs/CMakeLists.txt @@ -16,49 +16,79 @@ # along with GNSS-SDR. If not, see . # -add_definitions( -DGNSS_SDR_VERSION="${VERSION}" ) +add_definitions(-DGNSS_SDR_VERSION="${VERSION}") -set(PVT_LIB_SOURCES - pvt_solution.cc - ls_pvt.cc - hybrid_ls_pvt.cc - kml_printer.cc - gpx_printer.cc - rinex_printer.cc - nmea_printer.cc - rtcm_printer.cc - geojson_printer.cc - rtklib_solver.cc +set(PVT_LIB_SOURCES + pvt_solution.cc + ls_pvt.cc + hybrid_ls_pvt.cc + kml_printer.cc + gpx_printer.cc + rinex_printer.cc + nmea_printer.cc + rtcm_printer.cc + geojson_printer.cc + rtklib_solver.cc + pvt_conf.cc +) + +set(PVT_LIB_HEADERS + pvt_solution.h + ls_pvt.h + hybrid_ls_pvt.h + kml_printer.h + gpx_printer.h + rinex_printer.h + nmea_printer.h + rtcm_printer.h + geojson_printer.h + rtklib_solver.h + pvt_conf.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib - ${Boost_INCLUDE_DIRS} - ${ARMADILLO_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib + ${Boost_INCLUDE_DIRS} + ${ARMADILLO_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${MATIO_INCLUDE_DIRS} ) -file(GLOB PVT_LIB_HEADERS "*.h") list(SORT PVT_LIB_HEADERS) +list(SORT PVT_LIB_SOURCES) + add_library(pvt_lib ${PVT_LIB_SOURCES} ${PVT_LIB_HEADERS}) source_group(Headers FILES ${PVT_LIB_HEADERS}) -add_dependencies(pvt_lib rtklib_lib armadillo-${armadillo_RELEASE} glog-${glog_RELEASE}) + +if(MATIO_FOUND) + add_dependencies(pvt_lib + glog-${glog_RELEASE} + armadillo-${armadillo_RELEASE} + ) +else() + add_dependencies(pvt_lib + glog-${glog_RELEASE} + armadillo-${armadillo_RELEASE} + matio-${GNSSSDR_MATIO_LOCAL_VERSION} + ) +endif() target_link_libraries( - pvt_lib + pvt_lib rtklib_lib gnss_sdr_flags - ${Boost_LIBRARIES} - ${GLOG_LIBRARIES} + gnss_sp_libs + ${Boost_LIBRARIES} + ${GLOG_LIBRARIES} ${ARMADILLO_LIBRARIES} ${BLAS} ${LAPACK} - ) - + ${MATIO_LIBRARIES} +) diff --git a/src/algorithms/PVT/libs/geojson_printer.cc b/src/algorithms/PVT/libs/geojson_printer.cc index 5dd3ecdba..b79a4edae 100644 --- a/src/algorithms/PVT/libs/geojson_printer.cc +++ b/src/algorithms/PVT/libs/geojson_printer.cc @@ -32,14 +32,48 @@ #include "geojson_printer.h" #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include #include #include -GeoJSON_Printer::GeoJSON_Printer() +GeoJSON_Printer::GeoJSON_Printer(const std::string& base_path) { first_pos = true; + geojson_base_path = base_path; + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(geojson_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(geojson_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + geojson_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + geojson_base_path = p.string(); + } + if (geojson_base_path.compare(".") != 0) + { + std::cout << "GeoJSON files will be stored at " << geojson_base_path << std::endl; + } + + geojson_base_path = geojson_base_path + boost::filesystem::path::preferred_separator; } @@ -96,6 +130,7 @@ bool GeoJSON_Printer::set_headers(std::string filename, bool time_tag_name) { filename_ = filename + ".geojson"; } + filename_ = geojson_base_path + filename_; geojson_file.open(filename_.c_str()); @@ -124,6 +159,7 @@ bool GeoJSON_Printer::set_headers(std::string filename, bool time_tag_name) } else { + std::cout << "File " << filename_ << " cannot be saved. Wrong permissions?" << std::endl; return false; } } diff --git a/src/algorithms/PVT/libs/geojson_printer.h b/src/algorithms/PVT/libs/geojson_printer.h index 9963e64d2..63630552c 100644 --- a/src/algorithms/PVT/libs/geojson_printer.h +++ b/src/algorithms/PVT/libs/geojson_printer.h @@ -50,9 +50,10 @@ private: std::ofstream geojson_file; bool first_pos; std::string filename_; + std::string geojson_base_path; public: - GeoJSON_Printer(); + GeoJSON_Printer(const std::string& base_path = "."); ~GeoJSON_Printer(); bool set_headers(std::string filename, bool time_tag_name = true); bool print_position(const std::shared_ptr& position, bool print_average_values); diff --git a/src/algorithms/PVT/libs/gpx_printer.cc b/src/algorithms/PVT/libs/gpx_printer.cc index 1949bb7dc..1861139be 100644 --- a/src/algorithms/PVT/libs/gpx_printer.cc +++ b/src/algorithms/PVT/libs/gpx_printer.cc @@ -32,11 +32,53 @@ #include "gpx_printer.h" #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include #include using google::LogMessage; + +Gpx_Printer::Gpx_Printer(const std::string& base_path) +{ + positions_printed = false; + indent = " "; + gpx_base_path = base_path; + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(gpx_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(gpx_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + gpx_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + gpx_base_path = p.string(); + } + if (gpx_base_path.compare(".") != 0) + { + std::cout << "GPX files will be stored at " << gpx_base_path << std::endl; + } + + gpx_base_path = gpx_base_path + boost::filesystem::path::preferred_separator; +} + + bool Gpx_Printer::set_headers(std::string filename, bool time_tag_name) { boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time(); @@ -84,6 +126,8 @@ bool Gpx_Printer::set_headers(std::string filename, bool time_tag_name) { gpx_filename = filename + ".gpx"; } + + gpx_filename = gpx_base_path + gpx_filename; gpx_file.open(gpx_filename.c_str()); if (gpx_file.is_open()) @@ -94,17 +138,20 @@ bool Gpx_Printer::set_headers(std::string filename, bool time_tag_name) gpx_file << std::setprecision(14); gpx_file << "" << std::endl << "" << std::endl - << "" << std::endl - << indent << "Position fixes computed by GNSS-SDR v" << GNSS_SDR_VERSION << "" << std::endl - << indent << "GNSS-SDR position log generated at " << pt << " (local time)" << std::endl - << indent << "" << std::endl; + << indent << "xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v2 http://www.garmin.com/xmlschemas/TrackPointExtensionv2.xsd\"" << std::endl + << indent << "xmlns=\"http://www.topografix.com/GPX/1/1\"" << std::endl + << indent << "xmlns:gpxx=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\"" << std::endl + << indent << "xmlns:gpxtpx=\"http://www.garmin.com/xmlschemas/TrackPointExtension/v2\"" << std::endl + << indent << "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" << std::endl + << indent << "" << std::endl + << indent << indent << "Position fixes computed by GNSS-SDR v" << GNSS_SDR_VERSION << "" << std::endl + << indent << indent << "GNSS-SDR position log generated at " << pt << " (local time)" << std::endl + << indent << indent << "" << std::endl; return true; } else { + std::cout << "File " << gpx_filename << " cannot be saved. Wrong permissions?" << std::endl; return false; } } @@ -119,12 +166,16 @@ bool Gpx_Printer::print_position(const std::shared_ptr& position, positions_printed = true; std::shared_ptr position_ = position; + double speed_over_ground = position_->get_speed_over_ground(); // expressed in m/s + double course_over_ground = position_->get_course_over_ground(); // expressed in deg + double hdop = position_->get_hdop(); double vdop = position_->get_vdop(); double pdop = position_->get_pdop(); std::string utc_time = to_iso_extended_string(position_->get_position_UTC_time()); - utc_time.resize(23); // time up to ms - utc_time.append("Z"); // UTC time zone + if (utc_time.length() < 23) utc_time += "."; + utc_time.resize(23, '0'); // time up to ms + utc_time.append("Z"); // UTC time zone if (print_average_values == false) { @@ -141,9 +192,13 @@ bool Gpx_Printer::print_position(const std::shared_ptr& position, if (gpx_file.is_open()) { - gpx_file << indent << indent << "" << height << "" + gpx_file << indent << indent << indent << "" << height << "" << "" - << "" << hdop << "" << vdop << "" << pdop << "" << std::endl; + << "" << hdop << "" << vdop << "" << pdop << "" + << "" + << "" << speed_over_ground << "" + << "" << course_over_ground << "" + << "" << std::endl; return true; } else @@ -157,8 +212,8 @@ bool Gpx_Printer::close_file() { if (gpx_file.is_open()) { - gpx_file << indent << "" << std::endl - << "" << std::endl + gpx_file << indent << indent << "" << std::endl + << indent << "" << std::endl << ""; gpx_file.close(); return true; @@ -170,13 +225,6 @@ bool Gpx_Printer::close_file() } -Gpx_Printer::Gpx_Printer() -{ - positions_printed = false; - indent = " "; -} - - Gpx_Printer::~Gpx_Printer() { close_file(); diff --git a/src/algorithms/PVT/libs/gpx_printer.h b/src/algorithms/PVT/libs/gpx_printer.h index f158b6fb9..d4efcf81d 100644 --- a/src/algorithms/PVT/libs/gpx_printer.h +++ b/src/algorithms/PVT/libs/gpx_printer.h @@ -52,9 +52,10 @@ private: bool positions_printed; std::string gpx_filename; std::string indent; + std::string gpx_base_path; public: - Gpx_Printer(); + Gpx_Printer(const std::string& base_path = "."); ~Gpx_Printer(); bool set_headers(std::string filename, bool time_tag_name = true); bool print_position(const std::shared_ptr& position, bool print_average_values); diff --git a/src/algorithms/PVT/libs/hybrid_ls_pvt.cc b/src/algorithms/PVT/libs/hybrid_ls_pvt.cc index 6f269b7c7..2bded706f 100644 --- a/src/algorithms/PVT/libs/hybrid_ls_pvt.cc +++ b/src/algorithms/PVT/libs/hybrid_ls_pvt.cc @@ -150,8 +150,6 @@ bool hybrid_ls_pvt::get_PVT(std::map gnss_observables_map, do // 4- fill the observations vector with the corrected observables obs.resize(valid_obs + 1, 1); obs(valid_obs) = gnss_observables_iter->second.Pseudorange_m + SV_clock_bias_s * GALILEO_C_m_s - this->get_time_offset_s() * GALILEO_C_m_s; - this->set_visible_satellites_ID(valid_obs, galileo_ephemeris_iter->second.i_satellite_PRN); - this->set_visible_satellites_CN0_dB(valid_obs, gnss_observables_iter->second.CN0_dB_hz); Galileo_week_number = galileo_ephemeris_iter->second.WN_5; //for GST GST = galileo_ephemeris_iter->second.Galileo_System_Time(Galileo_week_number, hybrid_current_time); @@ -213,8 +211,6 @@ bool hybrid_ls_pvt::get_PVT(std::map gnss_observables_map, do double Code_bias_m = P1_P2 / (1.0 - Gamma); obs.resize(valid_obs + 1, 1); obs(valid_obs) = gnss_observables_iter->second.Pseudorange_m + dtr * GPS_C_m_s - Code_bias_m - this->get_time_offset_s() * GPS_C_m_s; - this->set_visible_satellites_ID(valid_obs, gps_ephemeris_iter->second.i_satellite_PRN); - this->set_visible_satellites_CN0_dB(valid_obs, gnss_observables_iter->second.CN0_dB_hz); // SV ECEF DEBUG OUTPUT LOG(INFO) << "(new)ECEF GPS L1 CA satellite SV ID=" << gps_ephemeris_iter->second.i_satellite_PRN @@ -265,8 +261,6 @@ bool hybrid_ls_pvt::get_PVT(std::map gnss_observables_map, do // 4- fill the observations vector with the corrected observables obs.resize(valid_obs + 1, 1); obs(valid_obs) = gnss_observables_iter->second.Pseudorange_m + dtr * GPS_C_m_s + SV_clock_bias_s * GPS_C_m_s; - this->set_visible_satellites_ID(valid_obs, gps_cnav_ephemeris_iter->second.i_satellite_PRN); - this->set_visible_satellites_CN0_dB(valid_obs, gnss_observables_iter->second.CN0_dB_hz); GPS_week = gps_cnav_ephemeris_iter->second.i_GPS_week; GPS_week = GPS_week % 1024; //Necessary due to the increase of WN bits in CNAV message (10 in GPS NAV and 13 in CNAV) diff --git a/src/algorithms/PVT/libs/hybrid_ls_pvt.h b/src/algorithms/PVT/libs/hybrid_ls_pvt.h index f8a6fc32c..2fe5fd9f3 100644 --- a/src/algorithms/PVT/libs/hybrid_ls_pvt.h +++ b/src/algorithms/PVT/libs/hybrid_ls_pvt.h @@ -36,6 +36,7 @@ #include "galileo_navigation_message.h" #include "gps_navigation_message.h" #include "gps_cnav_navigation_message.h" +#include "galileo_almanac.h" #include "gnss_synchro.h" #include "rtklib_rtkcmn.h" #include diff --git a/src/algorithms/PVT/libs/kml_printer.cc b/src/algorithms/PVT/libs/kml_printer.cc index 1233df036..fb742b385 100644 --- a/src/algorithms/PVT/libs/kml_printer.cc +++ b/src/algorithms/PVT/libs/kml_printer.cc @@ -2,6 +2,7 @@ * \file kml_printer.cc * \brief Implementation of a class that prints PVT information to a kml file * \author Javier Arribas, 2011. jarribas(at)cttc.es + * Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com * * * ------------------------------------------------------------------------- @@ -31,11 +32,61 @@ #include "kml_printer.h" #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include #include using google::LogMessage; + +Kml_Printer::Kml_Printer(const std::string& base_path) +{ + positions_printed = false; + indent = " "; + kml_base_path = base_path; + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(kml_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(kml_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + kml_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + kml_base_path = p.string(); + } + if (kml_base_path.compare(".") != 0) + { + std::cout << "KML files will be stored at " << kml_base_path << std::endl; + } + + kml_base_path = kml_base_path + boost::filesystem::path::preferred_separator; + + boost::filesystem::path tmp_base_path = boost::filesystem::temp_directory_path(); + boost::filesystem::path tmp_filename = boost::filesystem::unique_path(); + boost::filesystem::path tmp_file = tmp_base_path / tmp_filename; + + tmp_file_str = tmp_file.string(); + + point_id = 0; +} + + bool Kml_Printer::set_headers(std::string filename, bool time_tag_name) { boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time(); @@ -83,48 +134,87 @@ bool Kml_Printer::set_headers(std::string filename, bool time_tag_name) { kml_filename = filename + ".kml"; } + kml_filename = kml_base_path + kml_filename; kml_file.open(kml_filename.c_str()); - if (kml_file.is_open()) + tmp_file.open(tmp_file_str.c_str()); + + if (kml_file.is_open() && tmp_file.is_open()) { DLOG(INFO) << "KML printer writing on " << filename.c_str(); // Set iostream numeric format and precision kml_file.setf(kml_file.fixed, kml_file.floatfield); kml_file << std::setprecision(14); + + tmp_file.setf(tmp_file.fixed, tmp_file.floatfield); + tmp_file << std::setprecision(14); + kml_file << "" << std::endl - << "" << std::endl - << " " << std::endl - << " GNSS Track" << std::endl - << " GNSS-SDR Receiver position log file created at " << pt - << " " << std::endl - << "" << std::endl - << "" << std::endl - << "GNSS-SDR PVT" << std::endl - << "GNSS-SDR position log" << std::endl - << "#yellowLineGreenPoly" << std::endl - << "" << std::endl - << "0" << std::endl - << "1" << std::endl - << "absolute" << std::endl - << "" << std::endl; + << "" << std::endl + << indent << "" << std::endl + << indent << indent << "GNSS Track" << std::endl + << indent << indent << "" << std::endl + << indent << indent << indent << indent << "GNSS-SDR Receiver position log file created at " << pt << "" << std::endl + << indent << indent << indent << indent << "https://gnss-sdr.org/" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << "]]>" << std::endl + << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "normal" << std::endl + << indent << indent << indent << indent << "#track_n" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "highlight" << std::endl + << indent << indent << indent << indent << "#track_h" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << indent << indent << "Points" << std::endl; + return true; } else { + std::cout << "File " << kml_filename << " cannot be saved. Wrong permissions?" << std::endl; return false; } } -bool Kml_Printer::print_position(const std::shared_ptr& position, bool print_average_values) +bool Kml_Printer::print_position(const std::shared_ptr& position, bool print_average_values) { double latitude; double longitude; @@ -132,7 +222,18 @@ bool Kml_Printer::print_position(const std::shared_ptr& position, positions_printed = true; - std::shared_ptr position_ = position; + std::shared_ptr position_ = position; + + double speed_over_ground = position_->get_speed_over_ground(); // expressed in m/s + double course_over_ground = position_->get_course_over_ground(); // expressed in deg + + double hdop = position_->get_hdop(); + double vdop = position_->get_vdop(); + double pdop = position_->get_pdop(); + std::string utc_time = to_iso_extended_string(position_->get_position_UTC_time()); + if (utc_time.length() < 23) utc_time += "."; + utc_time.resize(23, '0'); // time up to ms + utc_time.append("Z"); // UTC time zone if (print_average_values == false) { @@ -147,9 +248,38 @@ bool Kml_Printer::print_position(const std::shared_ptr& position, height = position_->get_avg_height(); } - if (kml_file.is_open()) + if (kml_file.is_open() && tmp_file.is_open()) { - kml_file << longitude << "," << latitude << "," << height << std::endl; + point_id++; + kml_file << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "" << point_id << "" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << indent << indent << "Time:" << utc_time << "" << std::endl + << indent << indent << indent << indent << indent << indent << "Longitude:" << longitude << "deg" << std::endl + << indent << indent << indent << indent << indent << indent << "Latitude:" << latitude << "deg" << std::endl + << indent << indent << indent << indent << indent << indent << "Altitude:" << height << "m" << std::endl + << indent << indent << indent << indent << indent << indent << "Speed:" << speed_over_ground << "m/s" << std::endl + << indent << indent << indent << indent << indent << indent << "Course:" << course_over_ground << "deg" << std::endl + << indent << indent << indent << indent << indent << indent << "HDOP:" << hdop << "" << std::endl + << indent << indent << indent << indent << indent << indent << "VDOP:" << vdop << "" << std::endl + << indent << indent << indent << indent << indent << indent << "PDOP:" << pdop << "" << std::endl + << indent << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "]]>" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << indent << "" << utc_time << "" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "#track" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << indent << "absolute" << std::endl + << indent << indent << indent << indent << indent << "" << longitude << "," << latitude << "," << height << "" << std::endl + << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << "" << std::endl; + + tmp_file << indent << indent << indent << indent << indent + << longitude << "," << latitude << "," << height << std::endl; + return true; } else @@ -161,14 +291,32 @@ bool Kml_Printer::print_position(const std::shared_ptr& position, bool Kml_Printer::close_file() { - if (kml_file.is_open()) + if (kml_file.is_open() && tmp_file.is_open()) { - kml_file << "" << std::endl - << "" << std::endl - << "" << std::endl - << "" << std::endl + tmp_file.close(); + + kml_file << indent << indent << "" + << indent << indent << "" << std::endl + << indent << indent << indent << "Path" << std::endl + << indent << indent << indent << "#yellowLineGreenPoly" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << indent << indent << "0" << std::endl + << indent << indent << indent << indent << "1" << std::endl + << indent << indent << indent << indent << "absolute" << std::endl + << indent << indent << indent << indent << "" << std::endl; + + // Copy the contents of tmp_file into kml_file + std::ifstream src(tmp_file_str, std::ios::binary); + kml_file << src.rdbuf(); + + kml_file << indent << indent << indent << indent << "" << std::endl + << indent << indent << indent << "" << std::endl + << indent << indent << "" << std::endl + << indent << "" << std::endl << ""; + kml_file.close(); + return true; } else @@ -178,12 +326,6 @@ bool Kml_Printer::close_file() } -Kml_Printer::Kml_Printer() -{ - positions_printed = false; -} - - Kml_Printer::~Kml_Printer() { close_file(); diff --git a/src/algorithms/PVT/libs/kml_printer.h b/src/algorithms/PVT/libs/kml_printer.h index 435943a6c..27225df7a 100644 --- a/src/algorithms/PVT/libs/kml_printer.h +++ b/src/algorithms/PVT/libs/kml_printer.h @@ -2,7 +2,7 @@ * \file kml_printer.h * \brief Interface of a class that prints PVT information to a kml file * \author Javier Arribas, 2011. jarribas(at)cttc.es - * + * Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com * * ------------------------------------------------------------------------- * @@ -34,6 +34,7 @@ #define GNSS_SDR_KML_PRINTER_H_ #include "pvt_solution.h" +#include "rtklib_solver.h" #include #include #include @@ -48,14 +49,19 @@ class Kml_Printer { private: std::ofstream kml_file; + std::ofstream tmp_file; bool positions_printed; std::string kml_filename; + std::string kml_base_path; + std::string tmp_file_str; + unsigned int point_id; + std::string indent; public: - Kml_Printer(); + Kml_Printer(const std::string& base_path = std::string(".")); ~Kml_Printer(); bool set_headers(std::string filename, bool time_tag_name = true); - bool print_position(const std::shared_ptr& position, bool print_average_values); + bool print_position(const std::shared_ptr& position, bool print_average_values); bool close_file(); }; diff --git a/src/algorithms/PVT/libs/ls_pvt.cc b/src/algorithms/PVT/libs/ls_pvt.cc index 8525d952f..77e2c69a9 100644 --- a/src/algorithms/PVT/libs/ls_pvt.cc +++ b/src/algorithms/PVT/libs/ls_pvt.cc @@ -31,6 +31,7 @@ #include "ls_pvt.h" #include "GPS_L1_CA.h" +#include "geofunctions.h" #include #include #include @@ -235,15 +236,12 @@ arma::vec Ls_Pvt::leastSquarePos(const arma::mat& satpos, const arma::vec& obs, double* azim = 0; double* elev = 0; double* dist = 0; - Ls_Pvt::topocent(azim, elev, dist, pos.subvec(0, 2), Rot_X - pos.subvec(0, 2)); - this->set_visible_satellites_Az(i, *azim); - this->set_visible_satellites_El(i, *elev); - this->set_visible_satellites_Distance(i, *dist); + topocent(azim, elev, dist, pos.subvec(0, 2), Rot_X - pos.subvec(0, 2)); if (traveltime < 0.1 && nmbOfSatellites > 3) { //--- Find receiver's height - Ls_Pvt::togeod(&dphi, &dlambda, &h, 6378137.0, 298.257223563, pos(0), pos(1), pos(2)); + togeod(&dphi, &dlambda, &h, 6378137.0, 298.257223563, pos(0), pos(1), pos(2)); // Add troposphere correction if the receiver is below the troposphere if (h > 15000) { @@ -253,7 +251,7 @@ arma::vec Ls_Pvt::leastSquarePos(const arma::mat& satpos, const arma::vec& obs, else { //--- Find delay due to troposphere (in meters) - Ls_Pvt::tropo(&trop, sin(this->get_visible_satellites_El(i) * GPS_PI / 180.0), h / 1000.0, 1013.0, 293.0, 50.0, 0.0, 0.0, 0.0); + Ls_Pvt::tropo(&trop, sin(*elev * GPS_PI / 180.0), h / 1000.0, 1013.0, 293.0, 50.0, 0.0, 0.0, 0.0); if (trop > 5.0) trop = 0.0; //check for erratic values } } @@ -280,9 +278,6 @@ arma::vec Ls_Pvt::leastSquarePos(const arma::mat& satpos, const arma::vec& obs, } } - //-- compute the Dilution Of Precision values - //this->set_Q(arma::inv(arma::htrans(A) * A)); - // check the consistency of the PVT solution if (((fabs(pos(3)) * 1000.0) / GPS_C_m_s) > GPS_STARTOFFSET_ms * 2) { diff --git a/src/algorithms/PVT/libs/nmea_printer.cc b/src/algorithms/PVT/libs/nmea_printer.cc index 56aad23af..7253b9f79 100644 --- a/src/algorithms/PVT/libs/nmea_printer.cc +++ b/src/algorithms/PVT/libs/nmea_printer.cc @@ -34,8 +34,13 @@ */ #include "nmea_printer.h" +#include "rtklib_solution.h" #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include +#include #include #include @@ -43,13 +48,55 @@ using google::LogMessage; -Nmea_Printer::Nmea_Printer(std::string filename, bool flag_nmea_tty_port, std::string nmea_dump_devname) +Nmea_Printer::Nmea_Printer(std::string filename, bool flag_nmea_output_file, bool flag_nmea_tty_port, std::string nmea_dump_devname, const std::string& base_path) { - nmea_filename = filename; - nmea_file_descriptor.open(nmea_filename.c_str(), std::ios::out); - if (nmea_file_descriptor.is_open()) + nmea_base_path = base_path; + d_flag_nmea_output_file = flag_nmea_output_file; + if (d_flag_nmea_output_file == true) { - DLOG(INFO) << "NMEA printer writing on " << nmea_filename.c_str(); + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(nmea_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(nmea_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + nmea_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + nmea_base_path = p.string(); + } + + if ((nmea_base_path.compare(".") != 0) and (d_flag_nmea_output_file == true)) + { + std::cout << "NMEA files will be stored at " << nmea_base_path << std::endl; + } + + nmea_base_path = nmea_base_path + boost::filesystem::path::preferred_separator; + + nmea_filename = nmea_base_path + filename; + + nmea_file_descriptor.open(nmea_filename.c_str(), std::ios::out); + if (nmea_file_descriptor.is_open()) + { + DLOG(INFO) << "NMEA printer writing on " << nmea_filename.c_str(); + } + else + { + std::cout << "File " << nmea_filename << " cannot be saved. Wrong permissions?" << std::endl; + } } nmea_devname = nmea_dump_devname; @@ -86,20 +133,20 @@ int Nmea_Printer::init_serial(std::string serial_device) */ int fd = 0; struct termios options; - long BAUD; - long DATABITS; - long STOPBITS; - long PARITYON; - long PARITY; + int64_t BAUD; + int64_t DATABITS; + int64_t STOPBITS; + int64_t PARITYON; + int64_t PARITY; fd = open(serial_device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); - if (fd == -1) return fd; //failed to open TTY port + if (fd == -1) return fd; // failed to open TTY port if (fcntl(fd, F_SETFL, 0) == -1) LOG(INFO) << "Error enabling direct I/O"; // clear all flags on descriptor, enable direct I/O tcgetattr(fd, &options); // read serial port options BAUD = B9600; - //BAUD = B38400; + // BAUD = B38400; DATABITS = CS8; STOPBITS = 0; PARITYON = 0; @@ -107,7 +154,7 @@ int Nmea_Printer::init_serial(std::string serial_device) options.c_cflag = BAUD | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD; // enable receiver, set 8 bit data, ignore control lines - //options.c_cflag |= (CLOCAL | CREAD | CS8); + // options.c_cflag |= (CLOCAL | CREAD | CS8); options.c_iflag = IGNPAR; // set the new port options @@ -138,34 +185,36 @@ bool Nmea_Printer::Print_Nmea_Line(const std::shared_ptr& pvt_dat // generate the NMEA sentences - //GPRMC + // GPRMC GPRMC = get_GPRMC(); - //GPGGA (Global Positioning System Fixed Data) + // GPGGA (Global Positioning System Fixed Data) GPGGA = get_GPGGA(); - //GPGSA + // GPGSA GPGSA = get_GPGSA(); - //GPGSV + // GPGSV GPGSV = get_GPGSV(); // write to log file - try + if (d_flag_nmea_output_file) { - //GPRMC - nmea_file_descriptor << GPRMC; - //GPGGA (Global Positioning System Fixed Data) - nmea_file_descriptor << GPGGA; - //GPGSA - nmea_file_descriptor << GPGSA; - //GPGSV - nmea_file_descriptor << GPGSV; - } - catch (const std::exception& ex) - { - DLOG(INFO) << "NMEA printer can not write on output file" << nmea_filename.c_str(); - ; + try + { + // GPRMC + nmea_file_descriptor << GPRMC; + // GPGGA (Global Positioning System Fixed Data) + nmea_file_descriptor << GPGGA; + // GPGSA + nmea_file_descriptor << GPGSA; + // GPGSV + nmea_file_descriptor << GPGSV; + } + catch (const std::exception& ex) + { + DLOG(INFO) << "NMEA printer can not write on output file" << nmea_filename.c_str(); + } } - //write to serial device + // write to serial device if (nmea_dev_descriptor != -1) { if (write(nmea_dev_descriptor, GPRMC.c_str(), GPRMC.length()) == -1) @@ -283,7 +332,7 @@ std::string Nmea_Printer::longitude_to_hm(double longitude) std::string Nmea_Printer::get_UTC_NMEA_time(boost::posix_time::ptime d_position_UTC_time) { - //UTC Time: hhmmss.sss + // UTC Time: hhmmss.sss std::stringstream sentence_str; boost::posix_time::time_duration td = d_position_UTC_time.time_of_day(); @@ -328,184 +377,22 @@ std::string Nmea_Printer::get_UTC_NMEA_time(boost::posix_time::ptime d_position_ std::string Nmea_Printer::get_GPRMC() { // Sample -> $GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598,*10 - bool valid_fix = d_PVT_data->is_valid_position(); - - // ToDo: Compute speed and course over ground - double speed_over_ground_knots = 0; - double course_over_ground_deg = 0; - - //boost::posix_time::ptime d_position_UTC_time=boost::posix_time::microsec_clock::universal_time(); - std::stringstream sentence_str; - - //GPRMC (RMC-Recommended,Minimum Specific GNSS Data) - std::string sentence_header; - sentence_header = "$GPRMC,"; - sentence_str << sentence_header; - - //UTC Time: hhmmss.sss - sentence_str << get_UTC_NMEA_time(d_PVT_data->get_position_UTC_time()); - - //Status: A: data valid, V: data NOT valid - - if (valid_fix == true) - { - sentence_str << ",A"; - } - else - { - sentence_str << ",V"; - }; - - if (print_avg_pos == true) - { - // Latitude ddmm.mmmm,(N or S) - sentence_str << "," << latitude_to_hm(d_PVT_data->get_avg_latitude()); - // longitude dddmm.mmmm,(E or W) - sentence_str << "," << longitude_to_hm(d_PVT_data->get_avg_longitude()); - } - else - { - // Latitude ddmm.mmmm,(N or S) - sentence_str << "," << latitude_to_hm(d_PVT_data->get_latitude()); - // longitude dddmm.mmmm,(E or W) - sentence_str << "," << longitude_to_hm(d_PVT_data->get_longitude()); - } - - //Speed over ground (knots) - sentence_str << ","; - sentence_str.setf(std::ios::fixed, std::ios::floatfield); - sentence_str.precision(2); - sentence_str << speed_over_ground_knots; - - //course over ground (degrees) - sentence_str << ","; - sentence_str.setf(std::ios::fixed, std::ios::floatfield); - sentence_str.precision(2); - sentence_str << course_over_ground_deg; - - // Date ddmmyy - boost::gregorian::date sentence_date = d_PVT_data->get_position_UTC_time().date(); - unsigned int year = sentence_date.year(); - unsigned int day = sentence_date.day(); - unsigned int month = sentence_date.month(); - - sentence_str << ","; - sentence_str.width(2); - sentence_str.fill('0'); - sentence_str << day; - sentence_str.width(2); - sentence_str.fill('0'); - sentence_str << month; - - std::stringstream year_strs; - year_strs << std::dec << year; - sentence_str << std::dec << year_strs.str().substr(2); - - //Magnetic Variation (degrees) - // ToDo: Implement magnetic compass - sentence_str << ","; - - //Magnetic Variation (E or W) - // ToDo: Implement magnetic compass - sentence_str << ","; - - // Checksum - char checksum; - std::string tmpstr; - tmpstr = sentence_str.str(); - checksum = checkSum(tmpstr.substr(1)); - sentence_str << "*"; - sentence_str.width(2); - sentence_str.fill('0'); - sentence_str << std::hex << static_cast(checksum); - - // end NMEA sentence - sentence_str << "\r\n"; + unsigned char buff[1024] = {0}; + outnmea_rmc(buff, &d_PVT_data->pvt_sol); + sentence_str << buff; return sentence_str.str(); } std::string Nmea_Printer::get_GPGSA() { - //$GPGSA,A,3,07,02,26,27,09,04,15, , , , , ,1.8,1.0,1.5*33 + // $GPGSA,A,3,07,02,26,27,09,04,15, , , , , ,1.8,1.0,1.5*33 // GSA-GNSS DOP and Active Satellites - bool valid_fix = d_PVT_data->is_valid_position(); - int n_sats_used = d_PVT_data->get_num_valid_observations(); - double pdop = d_PVT_data->get_pdop(); - double hdop = d_PVT_data->get_hdop(); - double vdop = d_PVT_data->get_vdop(); - std::stringstream sentence_str; - std::string sentence_header; - sentence_header = "$GPGSA,"; - sentence_str << sentence_header; - - // mode1: - // (M) Manual-forced to operate in 2D or 3D mode - // (A) Automatic-allowed to automatically switch 2D/3D - std::string mode1 = "M"; - sentence_str << mode1; - - // mode2: - // 1 fix not available - // 2 fix 2D - // 3 fix 3D - if (valid_fix == true) - { - sentence_str << ",3"; - } - else - { - sentence_str << ",1"; - }; - - // Used satellites - for (int i = 0; i < 12; i++) - { - sentence_str << ","; - if (i < n_sats_used) - { - sentence_str.width(2); - sentence_str.fill('0'); - sentence_str << d_PVT_data->get_visible_satellites_ID(i); - } - } - - // PDOP - sentence_str << ","; - sentence_str.setf(std::ios::fixed, std::ios::floatfield); - sentence_str.width(2); - sentence_str.precision(1); - sentence_str.fill('0'); - sentence_str << pdop; - //HDOP - sentence_str << ","; - sentence_str.setf(std::ios::fixed, std::ios::floatfield); - sentence_str.width(2); - sentence_str.precision(1); - sentence_str.fill('0'); - sentence_str << hdop; - //VDOP - sentence_str << ","; - sentence_str.setf(std::ios::fixed, std::ios::floatfield); - sentence_str.width(2); - sentence_str.precision(1); - sentence_str.fill('0'); - sentence_str << vdop; - - // Checksum - char checksum; - std::string tmpstr; - tmpstr = sentence_str.str(); - checksum = checkSum(tmpstr.substr(1)); - sentence_str << "*"; - sentence_str.width(2); - sentence_str.fill('0'); - sentence_str << std::hex << static_cast(checksum); - - // end NMEA sentence - sentence_str << "\r\n"; + unsigned char buff[1024] = {0}; + outnmea_gsa(buff, &d_PVT_data->pvt_sol, d_PVT_data->pvt_ssat); + sentence_str << buff; return sentence_str.str(); } @@ -513,199 +400,22 @@ std::string Nmea_Printer::get_GPGSA() std::string Nmea_Printer::get_GPGSV() { // GSV-GNSS Satellites in View + // $GPGSV,2,1,07,07,79,048,42,02,51,062,43,26,36,256,42,27,27,138,42*71 // Notice that NMEA 2.1 only supports 12 channels - int n_sats_used = d_PVT_data->get_num_valid_observations(); std::stringstream sentence_str; - std::stringstream frame_str; - std::string sentence_header; - sentence_header = "$GPGSV,"; - char checksum; - std::string tmpstr; - - // 1st step: How many GPGSV frames we need? (up to 3) - // Each frame contains up to 4 satellites - int n_frames; - n_frames = std::ceil((static_cast(n_sats_used)) / 4.0); - - // generate the frames - int current_satellite = 0; - for (int i = 1; i < (n_frames + 1); i++) - { - frame_str.str(""); - frame_str << sentence_header; - - // number of messages - frame_str << n_frames; - - // message number - frame_str << ","; - frame_str << i; - - // total number of satellites in view - frame_str << ","; - frame_str.width(2); - frame_str.fill('0'); - frame_str << std::dec << n_sats_used; - - //satellites info - for (int j = 0; j < 4; j++) - { - // write satellite info - frame_str << ","; - frame_str.width(2); - frame_str.fill('0'); - frame_str << std::dec << d_PVT_data->get_visible_satellites_ID(current_satellite); - - frame_str << ","; - frame_str.width(2); - frame_str.fill('0'); - frame_str << std::dec << static_cast(d_PVT_data->get_visible_satellites_El(current_satellite)); - - frame_str << ","; - frame_str.width(3); - frame_str.fill('0'); - frame_str << std::dec << static_cast(d_PVT_data->get_visible_satellites_Az(current_satellite)); - - frame_str << ","; - frame_str.width(2); - frame_str.fill('0'); - frame_str << std::dec << static_cast(d_PVT_data->get_visible_satellites_CN0_dB(current_satellite)); - - current_satellite++; - - if (current_satellite == n_sats_used) - { - break; - } - } - - // frame checksum - tmpstr = frame_str.str(); - checksum = checkSum(tmpstr.substr(1)); - frame_str << "*"; - frame_str.width(2); - frame_str.fill('0'); - frame_str << std::hex << static_cast(checksum); - - // end NMEA sentence - frame_str << "\r\n"; - - //add frame to sentence - sentence_str << frame_str.str(); - } + unsigned char buff[1024] = {0}; + outnmea_gsv(buff, &d_PVT_data->pvt_sol, d_PVT_data->pvt_ssat); + sentence_str << buff; return sentence_str.str(); - //$GPGSV,2,1,07,07,79,048,42,02,51,062,43,26,36,256,42,27,27,138,42*71 } std::string Nmea_Printer::get_GPGGA() { - //boost::posix_time::ptime d_position_UTC_time=boost::posix_time::microsec_clock::universal_time(); - bool valid_fix = d_PVT_data->is_valid_position(); - int n_channels = d_PVT_data->get_num_valid_observations(); //d_nchannels - double hdop = d_PVT_data->get_hdop(); - double MSL_altitude; - - if (d_PVT_data->is_averaging() == true) - { - MSL_altitude = d_PVT_data->get_avg_height(); - } - else - { - MSL_altitude = d_PVT_data->get_height(); - } - std::stringstream sentence_str; - - //GPGGA (Global Positioning System Fixed Data) - std::string sentence_header; - sentence_header = "$GPGGA,"; - sentence_str << sentence_header; - - //UTC Time: hhmmss.sss - sentence_str << get_UTC_NMEA_time(d_PVT_data->get_position_UTC_time()); - - if (d_PVT_data->is_averaging() == true) - { - // Latitude ddmm.mmmm,(N or S) - sentence_str << "," << latitude_to_hm(d_PVT_data->get_avg_latitude()); - // longitude dddmm.mmmm,(E or W) - sentence_str << "," << longitude_to_hm(d_PVT_data->get_avg_longitude()); - } - else - { - // Latitude ddmm.mmmm,(N or S) - sentence_str << "," << latitude_to_hm(d_PVT_data->get_latitude()); - // longitude dddmm.mmmm,(E or W) - sentence_str << "," << longitude_to_hm(d_PVT_data->get_longitude()); - } - - // Position fix indicator - // 0 - Fix not available or invalid - // 1 - GPS SPS Mode, fix valid - // 2 - Differential GPS, SPS Mode, fix valid - // 3-5 - Not supported - // 6 - Dead Reckoning Mode, fix valid - // ToDo: Update PVT module to identify the fix mode - - if (valid_fix == true) - { - sentence_str << ",1"; - } - else - { - sentence_str << ",0"; - } - - // Number of satellites used in PVT - sentence_str << ","; - if (n_channels < 10) - { - sentence_str << '0' << n_channels; - } - else - { - sentence_str << n_channels; - } - - // HDOP - sentence_str << ","; - sentence_str.setf(std::ios::fixed, std::ios::floatfield); - sentence_str.width(2); - sentence_str.precision(1); - sentence_str.fill('0'); - sentence_str << hdop; - - // MSL Altitude - sentence_str << ","; - sentence_str.precision(1); - sentence_str << MSL_altitude; - sentence_str << ",M"; - - // Geoid-to-ellipsoid separation. Ellipsoid altitude = MSL Altitude + Geoid Separation. - // ToDo: Compute this value - sentence_str << ","; - sentence_str << "0.0"; - sentence_str << ",M"; - - // Age of Diff. Corr. (Seconds) Null fields when DGPS is not used - // Diff. Ref. Station ID (0000) - // ToDo: Implement this fields for Differential GPS - sentence_str << ","; - sentence_str << "0.0,0000"; - - // Checksum - char checksum; - std::string tmpstr; - tmpstr = sentence_str.str(); - checksum = checkSum(tmpstr.substr(1)); - sentence_str << "*"; - sentence_str.width(2); - sentence_str.fill('0'); - sentence_str << std::hex << static_cast(checksum); - - // end NMEA sentence - sentence_str << "\r\n"; + unsigned char buff[1024] = {0}; + outnmea_gga(buff, &d_PVT_data->pvt_sol); + sentence_str << buff; return sentence_str.str(); - //$GPGGA,104427.591,5920.7009,N,01803.2938,E,1,05,3.3,78.2,M,23.2,M,0.0,0000*4A + // $GPGGA,104427.591,5920.7009,N,01803.2938,E,1,05,3.3,78.2,M,23.2,M,0.0,0000*4A } diff --git a/src/algorithms/PVT/libs/nmea_printer.h b/src/algorithms/PVT/libs/nmea_printer.h index 318745e1c..b2f961756 100644 --- a/src/algorithms/PVT/libs/nmea_printer.h +++ b/src/algorithms/PVT/libs/nmea_printer.h @@ -53,7 +53,7 @@ public: /*! * \brief Default constructor. */ - Nmea_Printer(std::string filename, bool flag_nmea_tty_port, std::string nmea_dump_filename); + Nmea_Printer(std::string filename, bool flag_nmea_output_file, bool flag_nmea_tty_port, std::string nmea_dump_filename, const std::string& base_path = "."); /*! * \brief Print NMEA PVT and satellite info to the initialized device @@ -66,7 +66,8 @@ public: ~Nmea_Printer(); private: - std::string nmea_filename; // String with the NMEA log filename + std::string nmea_filename; // String with the NMEA log filename + std::string nmea_base_path; std::ofstream nmea_file_descriptor; // Output file stream for NMEA log file std::string nmea_devname; int nmea_dev_descriptor; // NMEA serial device descriptor (i.e. COM port) @@ -82,6 +83,7 @@ private: std::string latitude_to_hm(double lat); char checkSum(std::string sentence); bool print_avg_pos; + bool d_flag_nmea_output_file; }; #endif diff --git a/src/algorithms/PVT/libs/pvt_conf.cc b/src/algorithms/PVT/libs/pvt_conf.cc new file mode 100644 index 000000000..0f528f438 --- /dev/null +++ b/src/algorithms/PVT/libs/pvt_conf.cc @@ -0,0 +1,70 @@ +/*! + * \file pvt_conf.cc + * \brief Class that contains all the configuration parameters for a PVT block + * \author Carles Fernandez, 2018. cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "pvt_conf.h" + +Pvt_Conf::Pvt_Conf() +{ + type_of_receiver = 0U; + output_rate_ms = 0; + display_rate_ms = 0; + + rinex_version = 0; + rinexobs_rate_ms = 0; + rinexnav_rate_ms = 0; + + dump = false; + dump_mat = true; + + flag_nmea_tty_port = false; + + flag_rtcm_server = false; + flag_rtcm_tty_port = false; + rtcm_tcp_port = 0U; + rtcm_station_id = 0U; + + output_enabled = true; + rinex_output_enabled = true; + gpx_output_enabled = true; + geojson_output_enabled = true; + nmea_output_file_enabled = true; + kml_output_enabled = true; + xml_output_enabled = true; + rtcm_output_file_enabled = true; + + output_path = std::string("."); + rinex_output_path = std::string("."); + gpx_output_path = std::string("."); + geojson_output_path = std::string("."); + nmea_output_file_path = std::string("."); + kml_output_path = std::string("."); + xml_output_path = std::string("."); + rtcm_output_file_path = std::string("."); +} diff --git a/src/algorithms/PVT/libs/pvt_conf.h b/src/algorithms/PVT/libs/pvt_conf.h new file mode 100644 index 000000000..1719863e1 --- /dev/null +++ b/src/algorithms/PVT/libs/pvt_conf.h @@ -0,0 +1,86 @@ +/*! + * \file pvt_conf.h + * \brief Class that contains all the configuration parameters for the PVT block + * \author Carles Fernandez, 2018. cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_PVT_CONF_H_ +#define GNSS_SDR_PVT_CONF_H_ + +#include +#include +#include +#include + +class Pvt_Conf +{ +public: + uint32_t type_of_receiver; + int32_t output_rate_ms; + int32_t display_rate_ms; + + int32_t rinex_version; + int32_t rinexobs_rate_ms; + int32_t rinexnav_rate_ms; + std::map rtcm_msg_rate_ms; + + bool dump; + bool dump_mat; + std::string dump_filename; + + bool flag_nmea_tty_port; + std::string nmea_dump_filename; + std::string nmea_dump_devname; + + bool flag_rtcm_server; + bool flag_rtcm_tty_port; + uint16_t rtcm_tcp_port; + uint16_t rtcm_station_id; + std::string rtcm_dump_devname; + + bool output_enabled; + bool rinex_output_enabled; + bool gpx_output_enabled; + bool geojson_output_enabled; + bool nmea_output_file_enabled; + bool kml_output_enabled; + bool xml_output_enabled; + bool rtcm_output_file_enabled; + + std::string output_path; + std::string rinex_output_path; + std::string gpx_output_path; + std::string geojson_output_path; + std::string nmea_output_file_path; + std::string kml_output_path; + std::string xml_output_path; + std::string rtcm_output_file_path; + + Pvt_Conf(); +}; + +#endif diff --git a/src/algorithms/PVT/libs/pvt_solution.cc b/src/algorithms/PVT/libs/pvt_solution.cc index d0f31cc39..6071f38b0 100644 --- a/src/algorithms/PVT/libs/pvt_solution.cc +++ b/src/algorithms/PVT/libs/pvt_solution.cc @@ -31,6 +31,7 @@ #include "pvt_solution.h" #include "GPS_L1_CA.h" +#include "geofunctions.h" #include #include @@ -43,6 +44,8 @@ Pvt_Solution::Pvt_Solution() d_latitude_d = 0.0; d_longitude_d = 0.0; d_height_m = 0.0; + d_speed_over_ground_m_s = 0.0; + d_course_over_ground_d = 0.0; d_avg_latitude_d = 0.0; d_avg_longitude_d = 0.0; d_avg_height_m = 0.0; @@ -73,16 +76,9 @@ arma::vec Pvt_Solution::rotateSatellite(double const traveltime, const arma::vec omegatau = OMEGA_EARTH_DOT * traveltime; //--- Build a rotation matrix ---------------------------------------------- - arma::mat R3 = arma::zeros(3, 3); - R3(0, 0) = cos(omegatau); - R3(0, 1) = sin(omegatau); - R3(0, 2) = 0.0; - R3(1, 0) = -sin(omegatau); - R3(1, 1) = cos(omegatau); - R3(1, 2) = 0.0; - R3(2, 0) = 0.0; - R3(2, 1) = 0.0; - R3(2, 2) = 1; + arma::mat R3 = {{cos(omegatau), sin(omegatau), 0.0}, + {-sin(omegatau), cos(omegatau), 0.0}, + {0.0, 0.0, 1.0}}; //--- Do the rotation ------------------------------------------------------ arma::vec X_sat_rot; @@ -133,125 +129,7 @@ int Pvt_Solution::cart2geo(double X, double Y, double Z, int elipsoid_selection) d_latitude_d = phi * 180.0 / GPS_PI; d_longitude_d = lambda * 180.0 / GPS_PI; d_height_m = h; - return 0; -} - - -int Pvt_Solution::togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z) -{ - /* Subroutine to calculate geodetic coordinates latitude, longitude, - height given Cartesian coordinates X,Y,Z, and reference ellipsoid - values semi-major axis (a) and the inverse of flattening (finv). - - The output units of angular quantities will be in decimal degrees - (15.5 degrees not 15 deg 30 min). The output units of h will be the - same as the units of X,Y,Z,a. - - Inputs: - a - semi-major axis of the reference ellipsoid - finv - inverse of flattening of the reference ellipsoid - X,Y,Z - Cartesian coordinates - - Outputs: - dphi - latitude - dlambda - longitude - h - height above reference ellipsoid - - Based in a Matlab function by Kai Borre - */ - - *h = 0; - double tolsq = 1.e-10; // tolerance to accept convergence - int maxit = 10; // max number of iterations - double rtd = 180.0 / GPS_PI; - - // compute square of eccentricity - double esq; - if (finv < 1.0E-20) - { - esq = 0.0; - } - else - { - esq = (2.0 - 1.0 / finv) / finv; - } - - // first guess - double P = sqrt(X * X + Y * Y); // P is distance from spin axis - - //direct calculation of longitude - if (P > 1.0E-20) - { - *dlambda = atan2(Y, X) * rtd; - } - else - { - *dlambda = 0.0; - } - - // correct longitude bound - if (*dlambda < 0) - { - *dlambda = *dlambda + 360.0; - } - - double r = sqrt(P * P + Z * Z); // r is distance from origin (0,0,0) - - double sinphi; - if (r > 1.0E-20) - { - sinphi = Z / r; - } - else - { - sinphi = 0.0; - } - *dphi = asin(sinphi); - - // initial value of height = distance from origin minus - // approximate distance from origin to surface of ellipsoid - if (r < 1.0E-20) - { - *h = 0; - return 1; - } - - *h = r - a * (1 - sinphi * sinphi / finv); - - // iterate - double cosphi; - double N_phi; - double dP; - double dZ; - double oneesq = 1.0 - esq; - - for (int i = 0; i < maxit; i++) - { - sinphi = sin(*dphi); - cosphi = cos(*dphi); - - // compute radius of curvature in prime vertical direction - N_phi = a / sqrt(1 - esq * sinphi * sinphi); - - // compute residuals in P and Z - dP = P - (N_phi + (*h)) * cosphi; - dZ = Z - (N_phi * oneesq + (*h)) * sinphi; - - // update height and latitude - *h = *h + (sinphi * dZ + cosphi * dP); - *dphi = *dphi + (cosphi * dZ - sinphi * dP) / (N_phi + (*h)); - - // test for convergence - if ((dP * dP + dZ * dZ) < tolsq) - { - break; - } - if (i == (maxit - 1)) - { - LOG(WARNING) << "The computation of geodetic coordinates did not converge"; - } - } - *dphi = (*dphi) * rtd; + //todo: refactor this class. Mix of duplicated functions, use either RTKLIB geodetic functions or geofunctions.h return 0; } @@ -363,83 +241,6 @@ int Pvt_Solution::tropo(double *ddr_m, double sinel, double hsta_km, double p_mb } -int Pvt_Solution::topocent(double *Az, double *El, double *D, const arma::vec &x, const arma::vec &dx) -{ - /* Transformation of vector dx into topocentric coordinate - system with origin at x - Inputs: - x - vector origin coordinates (in ECEF system [X; Y; Z;]) - dx - vector ([dX; dY; dZ;]). - - Outputs: - D - vector length. Units like the input - Az - azimuth from north positive clockwise, degrees - El - elevation angle, degrees - - Based on a Matlab function by Kai Borre - */ - - double lambda; - double phi; - double h; - double dtr = GPS_PI / 180.0; - double a = 6378137.0; // semi-major axis of the reference ellipsoid WGS-84 - double finv = 298.257223563; // inverse of flattening of the reference ellipsoid WGS-84 - - // Transform x into geodetic coordinates - Pvt_Solution::togeod(&phi, &lambda, &h, a, finv, x(0), x(1), x(2)); - - double cl = cos(lambda * dtr); - double sl = sin(lambda * dtr); - double cb = cos(phi * dtr); - double sb = sin(phi * dtr); - - arma::mat F = arma::zeros(3, 3); - - F(0, 0) = -sl; - F(0, 1) = -sb * cl; - F(0, 2) = cb * cl; - - F(1, 0) = cl; - F(1, 1) = -sb * sl; - F(1, 2) = cb * sl; - - F(2, 0) = 0; - F(2, 1) = cb; - F(2, 2) = sb; - - arma::vec local_vector; - - local_vector = arma::htrans(F) * dx; - - double E = local_vector(0); - double N = local_vector(1); - double U = local_vector(2); - - double hor_dis; - hor_dis = sqrt(E * E + N * N); - - if (hor_dis < 1.0E-20) - { - *Az = 0; - *El = 90; - } - else - { - *Az = atan2(E, N) / dtr; - *El = atan2(U, hor_dis) / dtr; - } - - if (*Az < 0) - { - *Az = *Az + 360.0; - } - - *D = sqrt(dx(0) * dx(0) + dx(1) * dx(1) + dx(2) * dx(2)); - return 0; -} - - void Pvt_Solution::set_averaging_depth(int depth) { d_averaging_depth = depth; @@ -534,6 +335,30 @@ double Pvt_Solution::get_height() const } +double Pvt_Solution::get_speed_over_ground() const +{ + return d_speed_over_ground_m_s; +} + + +void Pvt_Solution::set_speed_over_ground(double speed_m_s) +{ + d_speed_over_ground_m_s = speed_m_s; +} + + +void Pvt_Solution::set_course_over_ground(double cog_deg) +{ + d_course_over_ground_d = cog_deg; +} + + +double Pvt_Solution::get_course_over_ground() const +{ + return d_course_over_ground_d; +} + + double Pvt_Solution::get_avg_latitude() const { return d_avg_latitude_d; @@ -557,6 +382,7 @@ bool Pvt_Solution::is_averaging() const return d_flag_averaging; } + bool Pvt_Solution::is_valid_position() const { return b_valid_position; @@ -606,172 +432,3 @@ void Pvt_Solution::set_num_valid_observations(int num) { d_valid_observations = num; } - - -bool Pvt_Solution::set_visible_satellites_ID(size_t index, unsigned int prn) -{ - if (index >= PVT_MAX_CHANNELS) - { - LOG(WARNING) << "Setting sat ID to channel " << index << " (the maximum is " << PVT_MAX_CHANNELS << ")"; - return false; - } - else - { - if (prn >= PVT_MAX_PRN) - { - LOG(WARNING) << "Setting to channel " << index << " a PRN of " << prn << " (the maximum is " << PVT_MAX_PRN << ")"; - return false; - } - else - { - d_visible_satellites_IDs[index] = prn; - return true; - } - } -} - - -unsigned int Pvt_Solution::get_visible_satellites_ID(size_t index) const -{ - if (index >= PVT_MAX_CHANNELS) - { - LOG(WARNING) << "Getting sat ID for channel " << index << " (the maximum is " << PVT_MAX_CHANNELS << ")"; - return 0; - } - else - { - return d_visible_satellites_IDs[index]; - } -} - - -bool Pvt_Solution::set_visible_satellites_El(size_t index, double el) -{ - if (index >= PVT_MAX_CHANNELS) - { - LOG(WARNING) << "Setting sat elevation for channel " << index << " (the maximum is " << PVT_MAX_CHANNELS << ")"; - return false; - } - else - { - if (el > 90.0) - { - LOG(WARNING) << "Setting a sat elevation > 90 [degrees]. Saturating to 90"; - d_visible_satellites_El[index] = 90.0; - } - else - { - if (el < -90.0) - { - LOG(WARNING) << "Setting a sat elevation < -90 [degrees]. Saturating to -90"; - d_visible_satellites_El[index] = -90.0; - } - else - { - d_visible_satellites_El[index] = el; - } - } - return true; - } -} - - -double Pvt_Solution::get_visible_satellites_El(size_t index) const -{ - if (index >= PVT_MAX_CHANNELS) - { - LOG(WARNING) << "Getting sat elevation for channel " << index << " (the maximum is " << PVT_MAX_CHANNELS << ")"; - return 0.0; - } - else - { - return d_visible_satellites_El[index]; - } -} - - -bool Pvt_Solution::set_visible_satellites_Az(size_t index, double az) -{ - if (index >= PVT_MAX_CHANNELS) - { - LOG(WARNING) << "Getting sat azimuth for channel " << index << " (the maximum is " << PVT_MAX_CHANNELS << ")"; - return false; - } - else - { - d_visible_satellites_Az[index] = az; - return true; - } -} - - -double Pvt_Solution::get_visible_satellites_Az(size_t index) const -{ - if (index >= PVT_MAX_CHANNELS) - { - LOG(WARNING) << "Getting sat azimuth for channel " << index << " (the maximum is " << PVT_MAX_CHANNELS << ")"; - return 0.0; - } - else - { - return d_visible_satellites_Az[index]; - } -} - - -bool Pvt_Solution::set_visible_satellites_Distance(size_t index, double dist) -{ - if (index >= PVT_MAX_CHANNELS) - { - LOG(WARNING) << "Setting sat distance for channel " << index << " (the maximum is " << PVT_MAX_CHANNELS << ")"; - return false; - } - else - { - d_visible_satellites_Distance[index] = dist; - return true; - } -} - - -double Pvt_Solution::get_visible_satellites_Distance(size_t index) const -{ - if (index >= PVT_MAX_CHANNELS) - { - LOG(WARNING) << "Getting sat distance for channel " << index << " (the maximum is " << PVT_MAX_CHANNELS << ")"; - return 0.0; - } - else - { - return d_visible_satellites_Distance[index]; - } -} - - -bool Pvt_Solution::set_visible_satellites_CN0_dB(size_t index, double cn0) -{ - if (index >= PVT_MAX_CHANNELS) - { - LOG(WARNING) << "Setting sat Cn0 for channel " << index << " (the maximum is " << PVT_MAX_CHANNELS << ")"; - return false; - } - else - { - d_visible_satellites_CN0_dB[index] = cn0; - return true; - } -} - - -double Pvt_Solution::get_visible_satellites_CN0_dB(size_t index) const -{ - if (index >= PVT_MAX_CHANNELS) - { - LOG(WARNING) << "Getting received CN0 for channel " << index << " (the maximum is " << PVT_MAX_CHANNELS << ")"; - return 0.0; - } - else - { - return d_visible_satellites_CN0_dB[index]; - } -} diff --git a/src/algorithms/PVT/libs/pvt_solution.h b/src/algorithms/PVT/libs/pvt_solution.h index 958bf4668..bfdc217b7 100644 --- a/src/algorithms/PVT/libs/pvt_solution.h +++ b/src/algorithms/PVT/libs/pvt_solution.h @@ -49,9 +49,11 @@ class Pvt_Solution private: double d_rx_dt_s; // RX time offset [s] - double d_latitude_d; // RX position Latitude WGS84 [deg] - double d_longitude_d; // RX position Longitude WGS84 [deg] - double d_height_m; // RX position height WGS84 [m] + double d_latitude_d; // RX position Latitude WGS84 [deg] + double d_longitude_d; // RX position Longitude WGS84 [deg] + double d_height_m; // RX position height WGS84 [m] + double d_speed_over_ground_m_s; // RX speed over ground [m/s] + double d_course_over_ground_d; // RX course over ground [deg] double d_avg_latitude_d; // Averaged latitude in degrees double d_avg_longitude_d; // Averaged longitude in degrees @@ -70,12 +72,6 @@ private: boost::posix_time::ptime d_position_UTC_time; int d_valid_observations; - int d_visible_satellites_IDs[PVT_MAX_CHANNELS] = {}; // Array with the IDs of the valid satellites - double d_visible_satellites_El[PVT_MAX_CHANNELS] = {}; // Array with the LOS Elevation of the valid satellites - double d_visible_satellites_Az[PVT_MAX_CHANNELS] = {}; // Array with the LOS Azimuth of the valid satellites - double d_visible_satellites_Distance[PVT_MAX_CHANNELS] = {}; // Array with the LOS Distance of the valid satellites - double d_visible_satellites_CN0_dB[PVT_MAX_CHANNELS] = {}; // Array with the IDs of the valid satellites - public: Pvt_Solution(); @@ -86,6 +82,12 @@ public: double get_longitude() const; //!< Get RX position Longitude WGS84 [deg] double get_height() const; //!< Get RX position height WGS84 [m] + double get_speed_over_ground() const; //!< Get RX speed over ground [m/s] + void set_speed_over_ground(double speed_m_s); //!< Set RX speed over ground [m/s] + + double get_course_over_ground() const; //!< Get RX course over ground [deg] + void set_course_over_ground(double cog_deg); //!< Set RX course over ground [deg] + double get_avg_latitude() const; //!< Get RX position averaged Latitude WGS84 [deg] double get_avg_longitude() const; //!< Get RX position averaged Longitude WGS84 [deg] double get_avg_height() const; //!< Get RX position averaged height WGS84 [m] @@ -102,21 +104,6 @@ public: int get_num_valid_observations() const; //!< Get the number of valid pseudorange observations (valid satellites) void set_num_valid_observations(int num); //!< Set the number of valid pseudorange observations (valid satellites) - bool set_visible_satellites_ID(size_t index, unsigned int prn); //!< Set the ID of the visible satellite index channel - unsigned int get_visible_satellites_ID(size_t index) const; //!< Get the ID of the visible satellite index channel - - bool set_visible_satellites_El(size_t index, double el); //!< Set the LOS Elevation, in degrees, of the visible satellite index channel - double get_visible_satellites_El(size_t index) const; //!< Get the LOS Elevation, in degrees, of the visible satellite index channel - - bool set_visible_satellites_Az(size_t index, double az); //!< Set the LOS Azimuth, in degrees, of the visible satellite index channel - double get_visible_satellites_Az(size_t index) const; //!< Get the LOS Azimuth, in degrees, of the visible satellite index channel - - bool set_visible_satellites_Distance(size_t index, double dist); //!< Set the LOS Distance of the visible satellite index channel - double get_visible_satellites_Distance(size_t index) const; //!< Get the LOS Distance of the visible satellite index channel - - bool set_visible_satellites_CN0_dB(size_t index, double cn0); //!< Set the CN0 in dB of the visible satellite index channel - double get_visible_satellites_CN0_dB(size_t index) const; //!< Get the CN0 in dB of the visible satellite index channel - //averaging void perform_pos_averaging(); void set_averaging_depth(int depth); //!< Set length of averaging window @@ -142,41 +129,6 @@ public: */ int cart2geo(double X, double Y, double Z, int elipsoid_selection); - /*! - * \brief Transformation of vector dx into topocentric coordinate system with origin at x - * - * \param[in] x Vector origin coordinates (in ECEF system [X; Y; Z;]) - * \param[in] dx Vector ([dX; dY; dZ;]). - * - * \param[out] D Vector length. Units like the input - * \param[out] Az Azimuth from north positive clockwise, degrees - * \param[out] El Elevation angle, degrees - * - * Based on a Matlab function by Kai Borre - */ - int topocent(double *Az, double *El, double *D, const arma::vec &x, const arma::vec &dx); - - /*! - * \brief Subroutine to calculate geodetic coordinates latitude, longitude, - * height given Cartesian coordinates X,Y,Z, and reference ellipsoid - * values semi-major axis (a) and the inverse of flattening (finv). - * - * The output units of angular quantities will be in decimal degrees - * (15.5 degrees not 15 deg 30 min). The output units of h will be the - * same as the units of X,Y,Z,a. - * - * \param[in] a - semi-major axis of the reference ellipsoid - * \param[in] finv - inverse of flattening of the reference ellipsoid - * \param[in] X,Y,Z - Cartesian coordinates - * - * \param[out] dphi - latitude - * \param[out] dlambda - longitude - * \param[out] h - height above reference ellipsoid - * - * Based in a Matlab function by Kai Borre - */ - int togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z); - /*! * \brief Tropospheric correction * diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index d4a228b4e..88c001e2b 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -33,6 +33,9 @@ #include #include #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include #include // for getlogin_r() #include // for min and max @@ -48,14 +51,44 @@ using google::LogMessage; -Rinex_Printer::Rinex_Printer(int conf_version) +Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path) { - navfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GPS_NAV"); - obsfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_OBS"); - sbsfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_SBAS"); - navGalfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GAL_NAV"); - navMixfilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_MIXED_NAV"); - navGlofilename = Rinex_Printer::createFilename("RINEX_FILE_TYPE_GLO_NAV"); + std::string base_rinex_path = base_path; + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(base_rinex_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(base_rinex_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + base_rinex_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + base_rinex_path = p.string(); + } + if (base_rinex_path.compare(".") != 0) + { + std::cout << "RINEX files will be stored at " << base_rinex_path << std::endl; + } + + navfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_GPS_NAV"); + obsfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_OBS"); + sbsfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_SBAS"); + navGalfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_GAL_NAV"); + navMixfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_MIXED_NAV"); + navGlofilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_GLO_NAV"); Rinex_Printer::navFile.open(navfilename, std::ios::out | std::ios::in | std::ios::app); Rinex_Printer::obsFile.open(obsfilename, std::ios::out | std::ios::in | std::ios::app); @@ -64,6 +97,13 @@ Rinex_Printer::Rinex_Printer(int conf_version) Rinex_Printer::navMixFile.open(navMixfilename, std::ios::out | std::ios::in | std::ios::app); Rinex_Printer::navGloFile.open(navGlofilename, std::ios::out | std::ios::in | std::ios::app); + if (!Rinex_Printer::navFile.is_open() or !Rinex_Printer::obsFile.is_open() or + !Rinex_Printer::sbsFile.is_open() or !Rinex_Printer::navGalFile.is_open() or + !Rinex_Printer::navMixFile.is_open() or !Rinex_Printer::navGloFile.is_open()) + { + std::cout << "RINEX files cannot be saved. Wrong permissions?" << std::endl; + } + // RINEX v3.02 codes satelliteSystem["GPS"] = "G"; satelliteSystem["GLONASS"] = "R"; @@ -161,7 +201,7 @@ Rinex_Printer::Rinex_Printer(int conf_version) Rinex_Printer::~Rinex_Printer() { // close RINEX files - long posn, poso, poss, posng, posmn, posnr; + int64_t posn, poso, poss, posng, posmn, posnr; posn = navFile.tellp(); poso = obsFile.tellp(); poss = sbsFile.tellp(); @@ -218,7 +258,7 @@ std::string Rinex_Printer::createFilename(std::string type) { const std::string stationName = "GSDR"; // 4-character station name designator boost::gregorian::date today = boost::gregorian::day_clock::local_day(); - const int dayOfTheYear = today.day_of_year(); + const int32_t dayOfTheYear = today.day_of_year(); std::stringstream strm0; if (dayOfTheYear < 100) strm0 << "0"; // three digits for day of the year if (dayOfTheYear < 10) strm0 << "0"; // three digits for day of the year @@ -239,7 +279,7 @@ std::string Rinex_Printer::createFilename(std::string type) boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time(); tm pt_tm = boost::posix_time::to_tm(pt); - int local_hour = pt_tm.tm_hour; + int32_t local_hour = pt_tm.tm_hour; std::stringstream strm; strm << local_hour; @@ -271,14 +311,14 @@ std::string Rinex_Printer::createFilename(std::string type) std::string hourTag = Hmap[strm.str()]; - int local_minute = pt_tm.tm_min; + int32_t local_minute = pt_tm.tm_min; std::stringstream strm2; if (local_minute < 10) strm2 << "0"; // at least two digits for minutes strm2 << local_minute; std::string minTag = strm2.str(); - int local_year = pt_tm.tm_year - 100; // 2012 is 112 + int32_t local_year = pt_tm.tm_year - 100; // 2012 is 112 std::stringstream strm3; strm3 << local_year; std::string yearTag = strm3.str(); @@ -297,7 +337,7 @@ std::string Rinex_Printer::getLocalTime() line += std::string(12, ' '); std::string username; char c_username[20] = {0}; - int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); if (nGet == 0) { username = c_username; @@ -314,22 +354,22 @@ std::string Rinex_Printer::getLocalTime() tm pt_tm = boost::local_time::to_tm(pt); std::stringstream strmHour; - int utc_hour = pt_tm.tm_hour; + int32_t utc_hour = pt_tm.tm_hour; if (utc_hour < 10) strmHour << "0"; // two digits for hours strmHour << utc_hour; std::stringstream strmMin; - int utc_minute = pt_tm.tm_min; + int32_t utc_minute = pt_tm.tm_min; if (utc_minute < 10) strmMin << "0"; // two digits for minutes strmMin << utc_minute; if (version == 2) { - int day = pt_tm.tm_mday; + int32_t day = pt_tm.tm_mday; line += Rinex_Printer::rightJustify(boost::lexical_cast(day), 2); line += std::string("-"); - std::map months; + std::map months; months[0] = "JAN"; months[1] = "FEB"; months[2] = "MAR"; @@ -361,7 +401,7 @@ std::string Rinex_Printer::getLocalTime() line += strmMin.str(); std::stringstream strm2; - int utc_seconds = pt_tm.tm_sec; + int32_t utc_seconds = pt_tm.tm_sec; if (utc_seconds < 10) strm2 << "0"; // two digits for seconds strm2 << utc_seconds; line += strm2.str(); @@ -477,6 +517,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Glonass_Gnav_Utc_M out << line << std::endl; } + void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { if (glonass_gnav_almanac.i_satellite_freq_channel) @@ -725,13 +766,13 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps } -void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { if (glonass_gnav_almanac.i_satellite_freq_channel) { } //Avoid compiler warning //Avoid compiler warning, there is not time system correction between Galileo and GLONASS - if (galileo_almanac.A_0G_10) + if (galileo_utc_model.A_0G_10) { } std::string line; @@ -839,7 +880,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& gali } -void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model) { std::string line; @@ -915,10 +956,10 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono // -------- Line system time correction 2 line.clear(); line += std::string("GPGA"); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16); - line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.t_0G_10), 7); - line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.WN_0G_10), 5); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A_0G_10, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A_1G_10, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.t_0G_10), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.WN_0G_10), 5); line += std::string(10, ' '); line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); Rinex_Printer::lengthCheck(line); @@ -1061,6 +1102,138 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& ion } +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& iono, const Gps_CNAV_Utc_Model& utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model) +{ + std::string line; + + // -------- Line 1 + line = std::string(5, ' '); + line += stringVersion; + line += std::string(11, ' '); + line += std::string("N: GNSS NAV DATA"); + line += std::string(4, ' '); + line += std::string("M: MIXED"); + line += std::string(12, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("GNSS NAVIGATION MESSAGE FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See https://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line ionospheric info 1 + line.clear(); + line += std::string("GAL "); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai0_5, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai1_5, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai2_5, 10, 2), 12); + double zero = 0.0; + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(zero, 10, 2), 12); + line += std::string(7, ' '); + line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line ionospheric info 2 + line.clear(); + line += std::string("GPSA"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha0, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha1, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha2, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha3, 10, 2), 12); + line += std::string(7, ' '); + line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line ionospheric info 3 + line.clear(); + line += std::string("GPSB"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta0, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta1, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta2, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta3, 10, 2), 12); + line += std::string(7, ' '); + line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction + line.clear(); + line += std::string("GAUT"); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A0_6, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A1_6, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t0t_6), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WNot_6), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 2 + line.clear(); + line += std::string("GPUT"); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_t_OT), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_T + 1024), 5); // valid until 2019 + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 6 leap seconds + // For leap second information, see http://www.endruntechnologies.com/leap.htm + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LS), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LSF), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_LSF), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_DN), 6); + line += std::string(36, ' '); + line += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- End of Header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, const Gps_Utc_Model& utc_model) { std::string line; @@ -1238,7 +1411,7 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co } -void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac) +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model) { std::string line; @@ -1327,10 +1500,10 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono // -------- Line system time correction 2 line.clear(); line += std::string("GPGA"); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16); - line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.t_0G_10), 7); - line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.WN_0G_10), 5); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_0G_10, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_1G_10, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t_0G_10), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WN_0G_10), 5); line += std::string(10, ' '); line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); Rinex_Printer::lengthCheck(line); @@ -1390,7 +1563,7 @@ void Rinex_Printer::rinex_sbs_header(std::fstream& out) line += Rinex_Printer::leftJustify("GNSS-SDR", 20); std::string username; char c_username[20] = {0}; - int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); if (nGet == 0) { username = c_username; @@ -1405,23 +1578,23 @@ void Rinex_Printer::rinex_sbs_header(std::fstream& out) boost::local_time::local_date_time pt = boost::local_time::local_sec_clock::local_time(zone); tm pt_tm = boost::local_time::to_tm(pt); std::stringstream strYear; - int utc_year = pt.date().year(); + int32_t utc_year = pt.date().year(); utc_year -= 2000; // two digits for year strYear << utc_year; std::stringstream strMonth; - int utc_month = pt.date().month().as_number(); + int32_t utc_month = pt.date().month().as_number(); if (utc_month < 10) strMonth << "0"; // two digits for months strMonth << utc_month; std::stringstream strmDay; - int utc_day = pt.date().day().as_number(); + int32_t utc_day = pt.date().day().as_number(); if (utc_day < 10) strmDay << "0"; // two digits for days strmDay << utc_day; std::stringstream strmHour; - int utc_hour = pt_tm.tm_hour; + int32_t utc_hour = pt_tm.tm_hour; if (utc_hour < 10) strmHour << "0"; // two digits for hours strmHour << utc_hour; std::stringstream strmMin; - int utc_minute = pt_tm.tm_min; + int32_t utc_minute = pt_tm.tm_min; if (utc_minute < 10) strmMin << "0"; // two digits for minutes strmMin << utc_minute; std::string time_str; @@ -1485,7 +1658,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Glonass_Gnav_Utc_ std::vector data; std::string line_aux; - long pos = out.tellp(); + int64_t pos = out.tellp(); out.seekp(0); data.clear(); @@ -1541,7 +1714,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Glonass_Gnav_Utc_ out.close(); out.open(navGlofilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < static_cast(data.size()) - 1; i++) + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) { out << data[i] << std::endl; } @@ -1552,12 +1725,12 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Glonass_Gnav_Utc_ } -void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) +void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model) { std::vector data; std::string line_aux; - long pos = out.tellp(); + int64_t pos = out.tellp(); out.seekp(0); data.clear(); @@ -1599,10 +1772,10 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal else if ((line_str.find("GPGA", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) { line_aux += std::string("GPGA"); - line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18); - line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16); - line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.t_0G_10), 7); - line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.WN_0G_10), 5); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A_0G_10, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A_1G_10, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.t_0G_10), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.WN_0G_10), 5); line_aux += std::string(10, ' '); line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); data.push_back(line_aux); @@ -1636,7 +1809,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal out.close(); out.open(navGalfilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < (int)data.size() - 1; i++) + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) { out << data[i] << std::endl; } @@ -1652,7 +1825,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Utc_Model& ut std::vector data; std::string line_aux; - long pos = out.tellp(); + int64_t pos = out.tellp(); out.seekp(0); data.clear(); @@ -1787,7 +1960,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Utc_Model& ut out.close(); out.open(navfilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < static_cast(data.size()) - 1; i++) + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) { out << data[i] << std::endl; } @@ -1803,7 +1976,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Utc_Mode std::vector data; std::string line_aux; - long pos = out.tellp(); + int64_t pos = out.tellp(); out.seekp(0); data.clear(); @@ -1882,7 +2055,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Utc_Mode out.close(); out.open(navfilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < static_cast(data.size()) - 1; i++) + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) { out << data[i] << std::endl; } @@ -1893,12 +2066,141 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Utc_Mode } -void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac) +void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Utc_Model& utc_model, const Gps_CNAV_Iono& iono, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model) { std::vector data; std::string line_aux; - long pos = out.tellp(); + int64_t pos = out.tellp(); + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while (!out.eof()) + { + std::getline(out, line_str); + + if (!no_more_finds) + { + line_aux.clear(); + if ((line_str.find("GAL", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos)) + { + line_aux += std::string("GAL "); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai0_5, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai1_5, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai2_5, 10, 2), 12); + double zero = 0.0; + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(zero, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPSA", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPSA"); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha3, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPSB", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPSB"); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta3, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + + else if ((line_str.find("GAUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GAUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A0_6, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A1_6, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t0t_6), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WNot_6), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPGA", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPGA"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_0G_10, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_1G_10, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t_0G_10), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WN_0G_10), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("GPUT", 0) != std::string::npos) + { + line_aux += std::string("GPUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_t_OT), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_T + 1024), 5); // valid until 2019 + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("LEAP SECONDS", 59) != std::string::npos) + { + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LS), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.d_DeltaT_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_WN_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(utc_model.i_DN), 6); + line_aux += std::string(36, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + } + else + { + data.push_back(line_str); + } + } + out.close(); + out.open(navfilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(navfilename, std::ios::out | std::ios::app); + out.seekp(pos); + std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; +} + + +void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model) +{ + std::vector data; + std::string line_aux; + + int64_t pos = out.tellp(); out.seekp(0); data.clear(); @@ -1975,10 +2277,10 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_ion else if ((line_str.find("GPGA", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) { line_aux += std::string("GPGA"); - line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18); - line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16); - line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.t_0G_10), 7); - line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_almanac.WN_0G_10), 5); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_0G_10, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A_1G_10, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.t_0G_10), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(galileo_utc_model.WN_0G_10), 5); line_aux += std::string(10, ' '); line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); data.push_back(line_aux); @@ -2012,7 +2314,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_ion out.close(); out.open(navMixfilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < static_cast(data.size()) - 1; i++) + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) { out << data[i] << std::endl; } @@ -2031,7 +2333,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_ion std::vector data; std::string line_aux; - long pos = out.tellp(); + int64_t pos = out.tellp(); out.seekp(0); data.clear(); @@ -2120,7 +2422,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_ion out.close(); out.open(navMixfilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < (int)data.size() - 1; i++) + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) { out << data[i] << std::endl; } @@ -2139,7 +2441,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Iono& gp std::vector data; std::string line_aux; - long pos = out.tellp(); + int64_t pos = out.tellp(); out.seekp(0); data.clear(); @@ -2228,7 +2530,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Iono& gp out.close(); out.open(navMixfilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < (int)data.size() - 1; i++) + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) { out << data[i] << std::endl; } @@ -2239,19 +2541,19 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Iono& gp } -void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { if (glonass_gnav_almanac.i_satellite_freq_channel) { } //Avoid compiler warning //Avoid compiler warning, there is not time system correction between Galileo and GLONASS - if (galileo_almanac.A_0G_10) + if (galileo_utc_model.A_0G_10) { } std::vector data; std::string line_aux; - long pos = out.tellp(); + int64_t pos = out.tellp(); out.seekp(0); data.clear(); @@ -2330,7 +2632,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal out.close(); out.open(navMixfilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < (int)data.size() - 1; i++) + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) { out << data[i] << std::endl; } @@ -2341,10 +2643,10 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal } -void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) { std::string line; - std::map::const_iterator gps_ephemeris_iter; + std::map::const_iterator gps_ephemeris_iter; for (gps_ephemeris_iter = eph_map.cbegin(); gps_ephemeris_iter != eph_map.cend(); @@ -2365,7 +2667,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(month) < 10) + if (boost::lexical_cast(month) < 10) { line += std::string(1, ' '); line += std::string(month, 1, 1); @@ -2375,7 +2677,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(day) < 10) + if (boost::lexical_cast(day) < 10) { line += std::string(1, ' '); line += std::string(day, 1, 1); @@ -2385,7 +2687,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(hour) < 10) + if (boost::lexical_cast(hour) < 10) { line += std::string(1, ' '); line += std::string(hour, 1, 1); @@ -2395,7 +2697,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(minutes) < 10) + if (boost::lexical_cast(minutes) < 10) { line += std::string(1, ' '); line += std::string(minutes, 1, 1); @@ -2405,7 +2707,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(seconds) < 10) + if (boost::lexical_cast(seconds) < 10) { line += std::string(1, ' '); line += std::string(seconds, 1, 1); @@ -2663,10 +2965,10 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) { std::string line; - std::map::const_iterator gps_ephemeris_iter; + std::map::const_iterator gps_ephemeris_iter; for (gps_ephemeris_iter = eph_map.cbegin(); gps_ephemeris_iter != eph_map.cend(); @@ -2819,10 +3121,10 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) { std::string line; - std::map::const_iterator galileo_ephemeris_iter; + std::map::const_iterator galileo_ephemeris_iter; line.clear(); for (galileo_ephemeris_iter = eph_map.cbegin(); galileo_ephemeris_iter != eph_map.cend(); @@ -2922,7 +3224,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(data_source_INAV), 18, 2); line += std::string(1, ' '); double GST_week = static_cast(galileo_ephemeris_iter->second.WN_5); @@ -2963,7 +3265,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(galileo_ephemeris_iter->second.E5b_DVS_5) + "11" + "1" + E1B_DVS + E1B_HS + boost::lexical_cast(galileo_ephemeris_iter->second.E1B_DVS_5); SVhealth_str = "000000000"; // *************** CHANGE THIS WHEN GALILEO SIGNAL IS VALID - int SVhealth = Rinex_Printer::toInt(SVhealth_str, 9); + int32_t SVhealth = Rinex_Printer::toInt(SVhealth_str, 9); line += Rinex_Printer::doub2for(static_cast(SVhealth), 18, 2); line += std::string(1, ' '); line += Rinex_Printer::doub2for(galileo_ephemeris_iter->second.BGD_E1E5a_5, 18, 2); @@ -2989,13 +3291,13 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) { std::string line; - std::map::const_iterator glonass_gnav_ephemeris_iter; + std::map::const_iterator glonass_gnav_ephemeris_iter; - for (glonass_gnav_ephemeris_iter = eph_map.begin(); - glonass_gnav_ephemeris_iter != eph_map.end(); + for (glonass_gnav_ephemeris_iter = eph_map.cbegin(); + glonass_gnav_ephemeris_iter != eph_map.cend(); glonass_gnav_ephemeris_iter++) { // -------- SV / EPOCH / SV CLK @@ -3013,7 +3315,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(month) < 10) + if (boost::lexical_cast(month) < 10) { line += std::string(1, ' '); line += std::string(month, 1, 1); @@ -3023,7 +3325,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(day) < 10) + if (boost::lexical_cast(day) < 10) { line += std::string(1, ' '); line += std::string(day, 1, 1); @@ -3033,7 +3335,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(hour) < 10) + if (boost::lexical_cast(hour) < 10) { line += std::string(1, ' '); line += std::string(hour, 1, 1); @@ -3043,7 +3345,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(minutes) < 10) + if (boost::lexical_cast(minutes) < 10) { line += std::string(1, ' '); line += std::string(minutes, 1, 1); @@ -3053,7 +3355,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(seconds) < 10) + if (boost::lexical_cast(seconds) < 10) { line += std::string(1, ' '); line += std::string(seconds, 1, 1); @@ -3186,7 +3488,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map) +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map) { version = 3; stringVersion = "3.02"; @@ -3195,21 +3497,30 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map) +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_cnav_eph_map, const std::map& galileo_eph_map) +{ + version = 3; + stringVersion = "3.02"; + Rinex_Printer::log_rinex_nav(out, gps_cnav_eph_map); + Rinex_Printer::log_rinex_nav(out, galileo_eph_map); +} + + +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map) { Rinex_Printer::log_rinex_nav(out, gps_eph_map); Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map); } -void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map) +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map) { Rinex_Printer::log_rinex_nav(out, gps_eph_map); Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map); } -void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& galileo_eph_map, const std::map& glonass_gnav_eph_map) +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& galileo_eph_map, const std::map& glonass_gnav_eph_map) { version = 3; stringVersion = "3.02"; @@ -3224,7 +3535,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Glonass_Gnav_Ephem { } //Avoid compiler warning std::string line; - std::map::const_iterator glonass_gnav_ephemeris_iter; + std::map::const_iterator glonass_gnav_ephemeris_iter; // -------- Line 1 line = std::string(5, ' '); @@ -3313,7 +3624,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Glonass_Gnav_Ephem line.clear(); std::string username; char c_username[20] = {0}; - int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); if (nGet == 0) { username = c_username; @@ -3636,7 +3947,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps line.clear(); std::string username; char c_username[20] = {0}; - int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); if (nGet == 0) { username = c_username; @@ -3733,7 +4044,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps out << line << std::endl; // Find GLONASS Signal in Mixed file - unsigned int number_of_observations_glo = 0; + uint32_t number_of_observations_glo = 0; std::string signal_("1G"); std::size_t found_1G = glonass_bands.find(signal_); if (found_1G != std::string::npos) @@ -3988,7 +4299,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris line.clear(); std::string username; char c_username[20] = {0}; - int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); if (nGet == 0) { username = c_username; @@ -4083,7 +4394,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris out << line << std::endl; // Find GLONASS Signal in Mixed file - unsigned int number_of_observations_glo = 0; + uint32_t number_of_observations_glo = 0; std::string signal_("1G"); std::size_t found_1G = glonass_bands.find(signal_); if (found_1G != std::string::npos) @@ -4294,7 +4605,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& line.clear(); std::string username; char c_username[20] = {0}; - int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); if (nGet == 0) { username = c_username; @@ -4359,7 +4670,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& // -------- SYS / OBS TYPES line.clear(); - unsigned int number_of_observations_gal = 0; + uint32_t number_of_observations_gal = 0; std::string signal_("1B"); std::size_t found_1B = galileo_bands.find(signal_); if (found_1B != std::string::npos) @@ -4440,7 +4751,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& out << line << std::endl; line.clear(); - unsigned int number_of_observations_glo = 0; + uint32_t number_of_observations_glo = 0; signal_ = "1G"; std::size_t found_1G = glonass_bands.find(signal_); if (found_1G != std::string::npos) @@ -4614,7 +4925,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph line.clear(); std::string username; char c_username[20] = {0}; - int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); if (nGet == 0) { username = c_username; @@ -4796,7 +5107,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph } -void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const double d_TOW_first_observation) +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const double d_TOW_first_observation, const std::string gps_bands) { std::string line; @@ -4868,7 +5179,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris line.clear(); std::string username; char c_username[20] = {0}; - int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); if (nGet == 0) { username = c_username; @@ -4934,30 +5245,66 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris // -------- SYS / OBS TYPES // one line per available system line.clear(); + uint32_t number_of_observations_gps = 0; + std::string signal_("2S"); + std::size_t found_2S = gps_bands.find(signal_); + if (found_2S != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "L5"; + std::size_t found_L5 = gps_bands.find(signal_); + if (found_L5 != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } line += satelliteSystem["GPS"]; line += std::string(2, ' '); std::stringstream strm; - numberTypesObservations = 4; + numberTypesObservations = number_of_observations_gps; strm << numberTypesObservations; line += Rinex_Printer::rightJustify(strm.str(), 3); // per type of observation - // GPS L2 PSEUDORANGE - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS L2 PHASE - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS DOPPLER L2 - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS L2 SIGNAL STRENGTH - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GPS_L2_L2CM"]; + if (found_2S != std::string::npos) + { + // GPS L2 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS DOPPLER L2 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L2_L2CM"]; + } + + if (found_L5 != std::string::npos) + { + // GPS L5 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L5_Q"]; + // GPS DOPPLER L5 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L5_Q"]; + } line += std::string(60 - line.size(), ' '); line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); Rinex_Printer::lengthCheck(line); @@ -5005,7 +5352,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris } -void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, const double d_TOW_first_observation) +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, const double d_TOW_first_observation, const std::string gps_bands) { if (eph_cnav.d_i_0) { @@ -5080,7 +5427,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph line.clear(); std::string username; char c_username[20] = {0}; - int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); if (nGet == 0) { username = c_username; @@ -5146,46 +5493,90 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph // -------- SYS / OBS TYPES // one line per available system line.clear(); + uint32_t number_of_observations_gps = 0; + std::string signal_("1C"); + std::size_t found_1C = gps_bands.find(signal_); + if (found_1C != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "2S"; + std::size_t found_2S = gps_bands.find(signal_); + if (found_2S != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "L5"; + std::size_t found_L5 = gps_bands.find(signal_); + if (found_L5 != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } line += satelliteSystem["GPS"]; line += std::string(2, ' '); std::stringstream strm; - numberTypesObservations = 8; + numberTypesObservations = number_of_observations_gps; strm << numberTypesObservations; line += Rinex_Printer::rightJustify(strm.str(), 3); // per type of observation - // GPS L1 PSEUDORANGE - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GPS_L1_CA"]; - // GPS L1 PHASE - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GPS_L1_CA"]; - // GPS DOPPLER L1 - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GPS_L1_CA"]; - // GPS L1 CA SIGNAL STRENGTH - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GPS_L1_CA"]; - // GPS L2 PSEUDORANGE - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS L2 PHASE - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS DOPPLER L2 - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GPS_L2_L2CM"]; - // GPS L2 SIGNAL STRENGTH - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GPS_L2_L2CM"]; + if (found_1C != std::string::npos) + { + // GPS L1 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L1_CA"]; + // GPS DOPPLER L1 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 CA SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L1_CA"]; + } + if (found_2S != std::string::npos) + { + // GPS L2 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS DOPPLER L2 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L2_L2CM"]; + } + if (found_L5 != std::string::npos) + { + // GPS L5 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L5_Q"]; + // GPS DOPPLER L5 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L5_Q"]; + } line += std::string(60 - line.size(), ' '); line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); Rinex_Printer::lengthCheck(line); @@ -5233,6 +5624,672 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph } +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& eph_cnav, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation, const std::string gps_bands, const std::string galileo_bands) +{ + std::string line; + version = 3; + if (eph_cnav.d_e_eccentricity == 0) + { + // avoid warning + } + if (galileo_eph.e_1 == 0) + { + // avoid warning + } + + // -------- Line 1 + line = std::string(5, ' '); + line += "3.02"; + line += std::string(11, ' '); + line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); + line += satelliteSystem["Mixed"]; + line += std::string(19, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::leftJustify("G = GPS R = GLONASS E = GALILEO S = GEO M = MIXED", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 3 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("MIXED (GPS/GALILEO) OBSERVATION DATA FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See https://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER NAME + line.clear(); + line += Rinex_Printer::leftJustify("DEFAULT MARKER NAME", 60); // put a flag or a property, + line += Rinex_Printer::leftJustify("MARKER NAME", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER TYPE + //line.clear(); + //line += Rinex_Printer::leftJustify("NON_GEODETIC", 20); // put a flag or a property + //line += std::string(40, ' '); + //line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + //Rinex_Printer::lengthCheck(line); + //out << line << std::endl; + + // -------- Line OBSERVER / AGENCY + line.clear(); + std::string username; + char c_username[20] = {0}; + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); + if (nGet == 0) + { + username = c_username; + } + else + { + username = "UNKNOWN USER"; + } + line += leftJustify(username, 20); + line += Rinex_Printer::leftJustify("CTTC", 40); // add flag and property + line += Rinex_Printer::leftJustify("OBSERVER / AGENCY", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line REC / TYPE VERS + line.clear(); + line += Rinex_Printer::leftJustify("GNSS-SDR", 20); // add flag and property + line += Rinex_Printer::leftJustify("Software Receiver", 20); // add flag and property + //line += Rinex_Printer::leftJustify(google::VersionString(), 20); // add flag and property + if (gnss_sdr_version.length() > 20) gnss_sdr_version.resize(9, ' '); + line += Rinex_Printer::leftJustify(gnss_sdr_version, 20); + line += Rinex_Printer::leftJustify("REC # / TYPE / VERS", 20); + lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA TYPE + line.clear(); + line += Rinex_Printer::leftJustify("Antenna number", 20); // add flag and property + line += Rinex_Printer::leftJustify("Antenna type", 20); // add flag and property + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("ANT # / TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- APPROX POSITION (optional for moving platforms) + // put here real data! + double antena_x = 0.0; + double antena_y = 0.0; + double antena_z = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_x, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_y, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_z, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("APPROX POSITION XYZ", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA: DELTA H/E/N + // put here real data! + double antena_h = 0.0; + double antena_e = 0.0; + double antena_n = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_h, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_e, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_n, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("ANTENNA: DELTA H/E/N", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- SYS / OBS TYPES + // one line per available system + line.clear(); + uint32_t number_of_observations_gps = 0; + std::string signal_("1C"); + std::size_t found_1C = gps_bands.find(signal_); + if (found_1C != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "2S"; + std::size_t found_2S = gps_bands.find(signal_); + if (found_2S != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "L5"; + std::size_t found_L5 = gps_bands.find(signal_); + if (found_L5 != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + line += satelliteSystem["GPS"]; + line += std::string(2, ' '); + std::stringstream strm; + numberTypesObservations = number_of_observations_gps; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 3); + // per type of observation + if (found_1C != std::string::npos) + { + // GPS L1 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L1_CA"]; + // GPS DOPPLER L1 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 CA SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L1_CA"]; + } + if (found_2S != std::string::npos) + { + // GPS L2 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS DOPPLER L2 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L2_L2CM"]; + } + if (found_L5 != std::string::npos) + { + // GPS L5 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L5_Q"]; + // GPS DOPPLER L5 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L5_Q"]; + } + line += std::string(60 - line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + line.clear(); + uint32_t number_of_observations_gal = 0; + signal_ = "1B"; + std::size_t found_1B = galileo_bands.find(signal_); + if (found_1B != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + signal_ = "5X"; + std::size_t found_5X = galileo_bands.find(signal_); + if (found_5X != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + signal_ = "7X"; + std::size_t found_7X = galileo_bands.find(signal_); + if (found_7X != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + line += satelliteSystem["Galileo"]; + line += std::string(2, ' '); + line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_gal), 3); + if (found_1B != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E1_B"]; + } + if (found_5X != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E5a_IQ"]; + } + if (found_7X != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E5b_IQ"]; + } + line += std::string(60 - line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Signal Strength units + line.clear(); + line += Rinex_Printer::leftJustify("DBHZ", 20); + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- TIME OF FIRST OBS + line.clear(); + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, d_TOW_first_observation); + std::string timestring = boost::posix_time::to_iso_string(p_gps_time); + std::string year(timestring, 0, 4); + std::string month(timestring, 4, 2); + std::string day(timestring, 6, 2); + std::string hour(timestring, 9, 2); + std::string minutes(timestring, 11, 2); + double gps_t = d_TOW_first_observation; + double seconds = fmod(gps_t, 60); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += Rinex_Printer::rightJustify(hour, 6); + line += Rinex_Printer::rightJustify(minutes, 6); + line += Rinex_Printer::rightJustify(asString(seconds, 7), 13); + line += Rinex_Printer::rightJustify(std::string("GPS"), 8); + line += std::string(9, ' '); + line += Rinex_Printer::leftJustify("TIME OF FIRST OBS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- end of header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph_cnav, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation, const std::string gps_bands, const std::string galileo_bands) +{ + std::string line; + version = 3; + if (galileo_eph.e_1 == 0) + { + // avoid warning + } + // -------- Line 1 + line = std::string(5, ' '); + line += "3.02"; + line += std::string(11, ' '); + line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); + line += satelliteSystem["Mixed"]; + line += std::string(19, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::leftJustify("G = GPS R = GLONASS E = GALILEO S = GEO M = MIXED", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 3 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("MIXED (GPS/GALILEO) OBSERVATION DATA FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See https://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER NAME + line.clear(); + line += Rinex_Printer::leftJustify("DEFAULT MARKER NAME", 60); // put a flag or a property, + line += Rinex_Printer::leftJustify("MARKER NAME", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER TYPE + //line.clear(); + //line += Rinex_Printer::leftJustify("NON_GEODETIC", 20); // put a flag or a property + //line += std::string(40, ' '); + //line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + //Rinex_Printer::lengthCheck(line); + //out << line << std::endl; + + // -------- Line OBSERVER / AGENCY + line.clear(); + std::string username; + char c_username[20] = {0}; + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); + if (nGet == 0) + { + username = c_username; + } + else + { + username = "UNKNOWN USER"; + } + line += leftJustify(username, 20); + line += Rinex_Printer::leftJustify("CTTC", 40); // add flag and property + line += Rinex_Printer::leftJustify("OBSERVER / AGENCY", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line REC / TYPE VERS + line.clear(); + line += Rinex_Printer::leftJustify("GNSS-SDR", 20); // add flag and property + line += Rinex_Printer::leftJustify("Software Receiver", 20); // add flag and property + //line += Rinex_Printer::leftJustify(google::VersionString(), 20); // add flag and property + if (gnss_sdr_version.length() > 20) gnss_sdr_version.resize(9, ' '); + line += Rinex_Printer::leftJustify(gnss_sdr_version, 20); + line += Rinex_Printer::leftJustify("REC # / TYPE / VERS", 20); + lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA TYPE + line.clear(); + line += Rinex_Printer::leftJustify("Antenna number", 20); // add flag and property + line += Rinex_Printer::leftJustify("Antenna type", 20); // add flag and property + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("ANT # / TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- APPROX POSITION (optional for moving platforms) + // put here real data! + double antena_x = 0.0; + double antena_y = 0.0; + double antena_z = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_x, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_y, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_z, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("APPROX POSITION XYZ", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA: DELTA H/E/N + // put here real data! + double antena_h = 0.0; + double antena_e = 0.0; + double antena_n = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_h, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_e, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_n, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("ANTENNA: DELTA H/E/N", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- SYS / OBS TYPES + // one line per available system + line.clear(); + uint32_t number_of_observations_gps = 0; + std::string signal_("2S"); + std::size_t found_2S = gps_bands.find(signal_); + if (found_2S != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + signal_ = "L5"; + std::size_t found_L5 = gps_bands.find(signal_); + if (found_L5 != std::string::npos) + { + number_of_observations_gps = number_of_observations_gps + 4; + } + line += satelliteSystem["GPS"]; + line += std::string(2, ' '); + std::stringstream strm; + numberTypesObservations = number_of_observations_gps; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 3); + // per type of observation + if (found_2S != std::string::npos) + { + // GPS L2 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS DOPPLER L2 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L2 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L2_L2CM"]; + } + if (found_L5 != std::string::npos) + { + // GPS L5 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L5_Q"]; + // GPS DOPPLER L5 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L5_Q"]; + // GPS L5 SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L5_Q"]; + } + line += std::string(60 - line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + line.clear(); + uint32_t number_of_observations_gal = 0; + signal_ = "1B"; + std::size_t found_1B = galileo_bands.find(signal_); + if (found_1B != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + signal_ = "5X"; + std::size_t found_5X = galileo_bands.find(signal_); + if (found_5X != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + signal_ = "7X"; + std::size_t found_7X = galileo_bands.find(signal_); + if (found_7X != std::string::npos) + { + number_of_observations_gal = number_of_observations_gal + 4; + } + line += satelliteSystem["Galileo"]; + line += std::string(2, ' '); + line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_gal), 3); + if (found_1B != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E1_B"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E1_B"]; + } + if (found_5X != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E5a_IQ"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E5a_IQ"]; + } + if (found_7X != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GALILEO_E5b_IQ"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GALILEO_E5b_IQ"]; + } + line += std::string(60 - line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Signal Strength units + line.clear(); + line += Rinex_Printer::leftJustify("DBHZ", 20); + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- TIME OF FIRST OBS + line.clear(); + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(eph_cnav, d_TOW_first_observation); + std::string timestring = boost::posix_time::to_iso_string(p_gps_time); + std::string year(timestring, 0, 4); + std::string month(timestring, 4, 2); + std::string day(timestring, 6, 2); + std::string hour(timestring, 9, 2); + std::string minutes(timestring, 11, 2); + double gps_t = d_TOW_first_observation; + double seconds = fmod(gps_t, 60); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += Rinex_Printer::rightJustify(hour, 6); + line += Rinex_Printer::rightJustify(minutes, 6); + line += Rinex_Printer::rightJustify(asString(seconds, 7), 13); + line += Rinex_Printer::rightJustify(std::string("GPS"), 8); + line += std::string(9, ' '); + line += Rinex_Printer::leftJustify("TIME OF FIRST OBS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- end of header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& eph, const double d_TOW_first_observation, const std::string bands) { std::string line; @@ -5306,7 +6363,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& line.clear(); std::string username; char c_username[20] = {0}; - int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); if (nGet == 0) { username = c_username; @@ -5371,7 +6428,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& // -------- SYS / OBS TYPES // one line per available system - unsigned int number_of_observations = 0; + uint32_t number_of_observations = 0; std::string signal_("1B"); std::size_t found_1B = bands.find(signal_); if (found_1B != std::string::npos) @@ -5570,7 +6627,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps line.clear(); std::string username; char c_username[20] = {0}; - int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + int32_t nGet = getlogin_r(c_username, sizeof(c_username) - 1); if (nGet == 0) { username = c_username; @@ -5665,7 +6722,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps out << line << std::endl; line.clear(); - unsigned int number_of_observations_gal = 0; + uint32_t number_of_observations_gal = 0; std::string signal_("1B"); std::size_t found_1B = galileo_bands.find(signal_); if (found_1B != std::string::npos) @@ -5866,7 +6923,7 @@ void Rinex_Printer::update_obs_header(std::fstream& out, const Gps_Utc_Model& ut out.close(); out.open(obsfilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < static_cast(data.size()) - 1; i++) + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) { out << data[i] << std::endl; } @@ -5924,7 +6981,7 @@ void Rinex_Printer::update_obs_header(std::fstream& out, const Gps_CNAV_Utc_Mode out.close(); out.open(obsfilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < static_cast(data.size()) - 1; i++) + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) { out << data[i] << std::endl; } @@ -5983,7 +7040,7 @@ void Rinex_Printer::update_obs_header(std::fstream& out, const Galileo_Utc_Model out.close(); out.open(obsfilename, std::ios::out | std::ios::trunc); out.seekp(0); - for (int i = 0; i < static_cast(data.size()) - 1; i++) + for (int32_t i = 0; i < static_cast(data.size()) - 1; i++) { out << data[i] << std::endl; } @@ -5993,7 +7050,7 @@ void Rinex_Printer::update_obs_header(std::fstream& out, const Galileo_Utc_Model } -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, const double obs_time, const std::map& observables, const std::string glonass_band) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, const double obs_time, const std::map& observables, const std::string glonass_band) { // RINEX observations timestamps are GPS timestamps. std::string line; @@ -6055,22 +7112,22 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event line += std::string(1, '0'); //Number of satellites observed in current epoch - int numSatellitesObserved = 0; - std::map::const_iterator observables_iter; - for (observables_iter = observables.begin(); - observables_iter != observables.end(); + int32_t numSatellitesObserved = 0; + std::map::const_iterator observables_iter; + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); observables_iter++) { numSatellitesObserved++; } line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); - for (observables_iter = observables.begin(); - observables_iter != observables.end(); + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); observables_iter++) { line += satelliteSystem["GLONASS"]; - if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); - line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); } // Receiver clock offset (optional) //line += rightJustify(asString(clockOffset, 12), 15); @@ -6078,8 +7135,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri Rinex_Printer::lengthCheck(line); out << line << std::endl; - for (observables_iter = observables.begin(); - observables_iter != observables.end(); + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); observables_iter++) { std::string lineObs; @@ -6090,7 +7147,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -6101,8 +7158,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS L1 CA PHASE lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads / GLONASS_TWO_PI, 3), 14); if (lli == 0) @@ -6113,7 +7170,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS L1 CA DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); if (lli == 0) @@ -6124,7 +7181,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); //GLONASS L1 SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); @@ -6159,10 +7216,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri line += std::string(1, '0'); //Number of satellites observed in current epoch - int numSatellitesObserved = 0; - std::map::const_iterator observables_iter; - for (observables_iter = observables.begin(); - observables_iter != observables.end(); + int32_t numSatellitesObserved = 0; + std::map::const_iterator observables_iter; + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); observables_iter++) { numSatellitesObserved++; @@ -6176,20 +7233,20 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri Rinex_Printer::lengthCheck(line); out << line << std::endl; - for (observables_iter = observables.begin(); - observables_iter != observables.end(); + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); observables_iter++) { std::string lineObs; lineObs.clear(); lineObs += satelliteSystem["GLONASS"]; - if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); //lineObs += std::string(2, ' '); lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -6200,8 +7257,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS L1 CA PHASE lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads / GLONASS_TWO_PI, 3), 14); @@ -6213,7 +7270,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS L1 CA DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); @@ -6226,7 +7283,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); //GLONASS L1 SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); @@ -6238,7 +7295,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri } -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double gps_obs_time, const std::map& observables) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double gps_obs_time, const std::map& observables) { if (glonass_gnav_eph.d_m) { @@ -6328,40 +7385,40 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep //Number of satellites observed in current epoch //Get maps with observations - std::map observablesG1C; - std::map observablesR1C; - std::map observablesR2C; - std::map::const_iterator observables_iter; + std::map observablesG1C; + std::map observablesR1C; + std::map observablesR2C; + std::map::const_iterator observables_iter; - for (observables_iter = observables.begin(); - observables_iter != observables.end(); + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); observables_iter++) { std::string system_(&observables_iter->second.System, 1); std::string sig_(observables_iter->second.Signal); if ((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) { - observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) { - observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) { - observablesG1C.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesG1C.insert(std::pair(observables_iter->first, observables_iter->second)); } } - std::multimap total_glo_map; - std::set available_glo_prns; - std::set::iterator it; - for (observables_iter = observablesR1C.begin(); - observables_iter != observablesR1C.end(); + std::multimap total_glo_map; + std::set available_glo_prns; + std::set::iterator it; + for (observables_iter = observablesR1C.cbegin(); + observables_iter != observablesR1C.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); + uint32_t prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); it = available_glo_prns.find(prn_); if (it == available_glo_prns.end()) { @@ -6369,12 +7426,12 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } } - for (observables_iter = observablesR2C.begin(); - observables_iter != observablesR2C.end(); + for (observables_iter = observablesR2C.cbegin(); + observables_iter != observablesR2C.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); + uint32_t prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); it = available_glo_prns.find(prn_); if (it == available_glo_prns.end()) { @@ -6382,38 +7439,38 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } } - int numGloSatellitesObserved = available_glo_prns.size(); - int numGpsSatellitesObserved = observablesG1C.size(); - int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; + int32_t numGloSatellitesObserved = available_glo_prns.size(); + int32_t numGpsSatellitesObserved = observablesG1C.size(); + int32_t numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); if (version == 2) { // Add list of GPS satellites - for (observables_iter = observablesG1C.begin(); - observables_iter != observablesG1C.end(); + for (observables_iter = observablesG1C.cbegin(); + observables_iter != observablesG1C.cend(); observables_iter++) { line += satelliteSystem["GPS"]; - if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); - line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); } // Add list of GLONASS L1 satellites - for (observables_iter = observablesR1C.begin(); - observables_iter != observablesR1C.end(); + for (observables_iter = observablesR1C.cbegin(); + observables_iter != observablesR1C.cend(); observables_iter++) { line += satelliteSystem["GLONASS"]; - if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); - line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); } // Add list of GLONASS L2 satellites - for (observables_iter = observablesR2C.begin(); - observables_iter != observablesR2C.end(); + for (observables_iter = observablesR2C.cbegin(); + observables_iter != observablesR2C.cend(); observables_iter++) { line += satelliteSystem["GLONASS"]; - if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); - line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); } } line += std::string(80 - line.size(), ' '); @@ -6423,8 +7480,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // -------- OBSERVATION record std::string s; std::string lineObs; - for (observables_iter = observablesG1C.begin(); - observables_iter != observablesG1C.end(); + for (observables_iter = observablesG1C.cbegin(); + observables_iter != observablesG1C.cend(); observables_iter++) { lineObs.clear(); @@ -6435,15 +7492,15 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // Specify system only if in version 3 if (s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; if (s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen - if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); } // Pseudorange Measurements lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -6454,8 +7511,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // PHASE lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads / GPS_TWO_PI, 3), 14); @@ -6467,7 +7524,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); @@ -6479,7 +7536,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); @@ -6488,7 +7545,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep out << lineObs << std::endl; } - std::pair::iterator, std::multimap::iterator> ret; + std::pair::iterator, std::multimap::iterator> ret; for (it = available_glo_prns.begin(); it != available_glo_prns.end(); it++) @@ -6497,18 +7554,18 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep if (version == 3) { lineObs += satelliteSystem["GLONASS"]; - if (static_cast(*it) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(*it)); + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); } ret = total_glo_map.equal_range(*it); - for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) { /// \todo Need to account for pseudorange correction for glonass //double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -6519,8 +7576,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS CARRIER PHASE lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); @@ -6532,7 +7589,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS DOPPLER lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); @@ -6544,7 +7601,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); @@ -6556,7 +7613,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double gps_obs_time, const std::map& observables) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double gps_obs_time, const std::map& observables) { if (glonass_gnav_eph.d_m) { @@ -6602,40 +7659,40 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g //Number of satellites observed in current epoch //Get maps with observations - std::map observablesG2S; - std::map observablesR1C; - std::map observablesR2C; - std::map::const_iterator observables_iter; + std::map observablesG2S; + std::map observablesR1C; + std::map observablesR2C; + std::map::const_iterator observables_iter; - for (observables_iter = observables.begin(); - observables_iter != observables.end(); + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); observables_iter++) { std::string system_(&observables_iter->second.System, 1); std::string sig_(observables_iter->second.Signal); if ((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) { - observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) { - observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) { - observablesG2S.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesG2S.insert(std::pair(observables_iter->first, observables_iter->second)); } } - std::multimap total_glo_map; - std::set available_glo_prns; - std::set::iterator it; - for (observables_iter = observablesR1C.begin(); - observables_iter != observablesR1C.end(); + std::multimap total_glo_map; + std::set available_glo_prns; + std::set::iterator it; + for (observables_iter = observablesR1C.cbegin(); + observables_iter != observablesR1C.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); + uint32_t prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); it = available_glo_prns.find(prn_); if (it == available_glo_prns.end()) { @@ -6643,12 +7700,12 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g } } - for (observables_iter = observablesR2C.begin(); - observables_iter != observablesR2C.end(); + for (observables_iter = observablesR2C.cbegin(); + observables_iter != observablesR2C.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); + uint32_t prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); it = available_glo_prns.find(prn_); if (it == available_glo_prns.end()) { @@ -6656,9 +7713,9 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g } } - int numGloSatellitesObserved = available_glo_prns.size(); - int numGpsSatellitesObserved = observablesG2S.size(); - int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; + int32_t numGloSatellitesObserved = available_glo_prns.size(); + int32_t numGpsSatellitesObserved = observablesG2S.size(); + int32_t numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); line += std::string(80 - line.size(), ' '); @@ -6668,8 +7725,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g // -------- OBSERVATION record std::string s; std::string lineObs; - for (observables_iter = observablesG2S.begin(); - observables_iter != observablesG2S.end(); + for (observables_iter = observablesG2S.cbegin(); + observables_iter != observablesG2S.cend(); observables_iter++) { lineObs.clear(); @@ -6678,14 +7735,14 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g // Specify system only if in version 3 if (s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; if (s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen - if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); // Pseudorange Measurements lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -6696,8 +7753,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // PHASE lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads / GPS_TWO_PI, 3), 14); @@ -6709,7 +7766,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); @@ -6721,7 +7778,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); @@ -6730,25 +7787,25 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g out << lineObs << std::endl; } - std::pair::iterator, std::multimap::iterator> ret; + std::pair::iterator, std::multimap::iterator> ret; for (it = available_glo_prns.begin(); it != available_glo_prns.end(); it++) { lineObs.clear(); lineObs += satelliteSystem["GLONASS"]; - if (static_cast(*it) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(*it)); + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); ret = total_glo_map.equal_range(*it); - for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) { /// \todo Need to account for pseudorange correction for glonass //double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -6759,8 +7816,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS CARRIER PHASE lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); @@ -6772,7 +7829,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS DOPPLER lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); @@ -6784,7 +7841,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); @@ -6796,7 +7853,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g } -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double galileo_obs_time, const std::map& observables) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double galileo_obs_time, const std::map& observables) { if (glonass_gnav_eph.d_m) { @@ -6842,52 +7899,52 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga //Number of satellites observed in current epoch //Get maps with observations - std::map observablesE1B; - std::map observablesR1C; - std::map observablesR2C; - std::map::const_iterator observables_iter; + std::map observablesE1B; + std::map observablesR1C; + std::map observablesR2C; + std::map::const_iterator observables_iter; - for (observables_iter = observables.begin(); - observables_iter != observables.end(); + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); observables_iter++) { std::string system_(&observables_iter->second.System, 1); std::string sig_(observables_iter->second.Signal); if ((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) { - observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) { - observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("E") == 0) && (sig_.compare("1B") == 0)) { - observablesE1B.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesE1B.insert(std::pair(observables_iter->first, observables_iter->second)); } } - std::multimap total_glo_map; - std::set available_glo_prns; - std::set::iterator it; - for (observables_iter = observablesR1C.begin(); - observables_iter != observablesR1C.end(); + std::multimap total_glo_map; + std::set available_glo_prns; + std::set::iterator it; + for (observables_iter = observablesR1C.cbegin(); + observables_iter != observablesR1C.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); + uint32_t prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); it = available_glo_prns.find(prn_); if (it == available_glo_prns.end()) { available_glo_prns.insert(prn_); } } - for (observables_iter = observablesR2C.begin(); - observables_iter != observablesR2C.end(); + for (observables_iter = observablesR2C.cbegin(); + observables_iter != observablesR2C.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); + uint32_t prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); it = available_glo_prns.find(prn_); if (it == available_glo_prns.end()) { @@ -6895,9 +7952,9 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga } } - int numGloSatellitesObserved = available_glo_prns.size(); - int numGalSatellitesObserved = observablesE1B.size(); - int numSatellitesObserved = numGalSatellitesObserved + numGloSatellitesObserved; + int32_t numGloSatellitesObserved = available_glo_prns.size(); + int32_t numGalSatellitesObserved = observablesE1B.size(); + int32_t numSatellitesObserved = numGalSatellitesObserved + numGloSatellitesObserved; line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); // Receiver clock offset (optional) @@ -6909,8 +7966,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga std::string s; std::string lineObs; - for (observables_iter = observablesE1B.begin(); - observables_iter != observablesE1B.end(); + for (observables_iter = observablesE1B.cbegin(); + observables_iter != observablesE1B.cend(); observables_iter++) { lineObs.clear(); @@ -6918,12 +7975,12 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga s.assign(1, observables_iter->second.System); if (s.compare("E") == 0) lineObs += satelliteSystem["Galileo"]; if (s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen - if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -6934,8 +7991,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // PHASE lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads / GPS_TWO_PI, 3), 14); @@ -6947,7 +8004,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); @@ -6959,7 +8016,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); @@ -6968,22 +8025,22 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga out << lineObs << std::endl; } - std::pair::iterator, std::multimap::iterator> ret; + std::pair::iterator, std::multimap::iterator> ret; for (it = available_glo_prns.begin(); it != available_glo_prns.end(); it++) { lineObs.clear(); lineObs += satelliteSystem["Galileo"]; - if (static_cast(*it) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(*it)); + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); ret = total_glo_map.equal_range(*it); - for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) { lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -6994,8 +8051,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS CARRIER PHASE lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); @@ -7007,7 +8064,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS DOPPLER lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); @@ -7019,7 +8076,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GLONASS SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); @@ -7031,7 +8088,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga } -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, const double obs_time, const std::map& observables) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, const double obs_time, const std::map& observables) { // RINEX observations timestamps are GPS timestamps. std::string line; @@ -7088,8 +8145,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event line += std::string(1, '0'); //Number of satellites observed in current epoch - int numSatellitesObserved = 0; - std::map::const_iterator observables_iter; + int32_t numSatellitesObserved = 0; + std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); observables_iter != observables.cend(); observables_iter++) @@ -7102,8 +8159,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c observables_iter++) { line += satelliteSystem["GPS"]; - if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); - line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); } // Receiver clock offset (optional) //line += rightJustify(asString(clockOffset, 12), 15); @@ -7123,7 +8180,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -7134,8 +8191,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L1 CA PHASE lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads / GPS_TWO_PI, 3), 14); if (lli == 0) @@ -7146,7 +8203,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L1 CA DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); if (lli == 0) @@ -7157,7 +8214,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); //GPS L1 SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); @@ -7193,8 +8250,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c line += std::string(1, '0'); //Number of satellites observed in current epoch - int numSatellitesObserved = 0; - std::map::const_iterator observables_iter; + int32_t numSatellitesObserved = 0; + std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); observables_iter != observables.cend(); observables_iter++) @@ -7217,13 +8274,13 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c std::string lineObs; lineObs.clear(); lineObs += satelliteSystem["GPS"]; - if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); //lineObs += std::string(2, ' '); lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -7234,8 +8291,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L1 CA PHASE lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads / GPS_TWO_PI, 3), 14); @@ -7247,7 +8304,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L1 CA DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); @@ -7260,7 +8317,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); //GPS L1 SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); @@ -7272,7 +8329,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c } -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, double obs_time, const std::map& observables) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, double obs_time, const std::map& observables) { // RINEX observations timestamps are GPS timestamps. std::string line; @@ -7314,8 +8371,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e line += std::string(1, '0'); //Number of satellites observed in current epoch - int numSatellitesObserved = 0; - std::map::const_iterator observables_iter; + int32_t numSatellitesObserved = 0; + std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); observables_iter != observables.cend(); observables_iter++) @@ -7338,14 +8395,14 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e std::string lineObs; lineObs.clear(); lineObs += satelliteSystem["GPS"]; - if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); //lineObs += std::string(2, ' '); //GPS L2 PSEUDORANGE lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -7356,8 +8413,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L2 PHASE lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads / GPS_TWO_PI, 3), 14); @@ -7369,7 +8426,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS L2 DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); @@ -7382,7 +8439,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); //GPS L2 SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); @@ -7393,7 +8450,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e } -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, double obs_time, const std::map& observables) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, double obs_time, const std::map& observables) { if (eph_cnav.d_i_0) { @@ -7440,12 +8497,13 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c //Number of satellites observed in current epoch //Get maps with GPS L1 and L2 observations - std::map observablesL1; - std::map observablesL2; - std::map::const_iterator observables_iter; + std::map observablesL1; + std::map observablesL2; + std::map observablesL5; + std::map::const_iterator observables_iter; - std::multimap total_mmap; - std::multimap::iterator mmap_iter; + std::multimap total_mmap; + std::multimap::iterator mmap_iter; for (observables_iter = observables.cbegin(); observables_iter != observables.cend(); observables_iter++) @@ -7454,24 +8512,36 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c std::string sig_(observables_iter->second.Signal); if ((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) { - observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); - total_mmap.insert(std::pair(observables_iter->second.PRN, observables_iter->second)); + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + total_mmap.insert(std::pair(observables_iter->second.PRN, observables_iter->second)); } if ((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) { - observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); mmap_iter = total_mmap.find(observables_iter->second.PRN); if (mmap_iter == total_mmap.end()) { Gnss_Synchro gs = Gnss_Synchro(); - total_mmap.insert(std::pair(observables_iter->second.PRN, gs)); + total_mmap.insert(std::pair(observables_iter->second.PRN, gs)); } - total_mmap.insert(std::pair(observables_iter->second.PRN, observables_iter->second)); + total_mmap.insert(std::pair(observables_iter->second.PRN, observables_iter->second)); + } + + if ((system_.compare("G") == 0) && (sig_.compare("L5") == 0)) + { + observablesL5.insert(std::pair(observables_iter->first, observables_iter->second)); + mmap_iter = total_mmap.find(observables_iter->second.PRN); + if (mmap_iter == total_mmap.end()) + { + Gnss_Synchro gs = Gnss_Synchro(); + total_mmap.insert(std::pair(observables_iter->second.PRN, gs)); + } + total_mmap.insert(std::pair(observables_iter->second.PRN, observables_iter->second)); } } // Fill with zeros satellites with L1 obs but not L2 - std::multimap mmap_aux; + std::multimap mmap_aux; mmap_aux = total_mmap; for (mmap_iter = mmap_aux.begin(); mmap_iter != mmap_aux.end(); @@ -7485,17 +8555,17 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c std::string sig = "2S"; std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); gs.PRN = mmap_iter->second.PRN; - total_mmap.insert(std::pair(mmap_iter->second.PRN, gs)); + total_mmap.insert(std::pair(mmap_iter->second.PRN, gs)); } } - std::set available_prns; - std::set::iterator it; + std::set available_prns; + std::set::iterator it; for (observables_iter = observablesL1.cbegin(); observables_iter != observablesL1.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; + uint32_t prn_ = observables_iter->second.PRN; it = available_prns.find(prn_); if (it == available_prns.end()) { @@ -7507,7 +8577,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c observables_iter != observablesL2.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; + uint32_t prn_ = observables_iter->second.PRN; it = available_prns.find(prn_); if (it == available_prns.end()) { @@ -7515,7 +8585,19 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c } } - int numSatellitesObserved = available_prns.size(); + for (observables_iter = observablesL5.cbegin(); + observables_iter != observablesL5.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + it = available_prns.find(prn_); + if (it == available_prns.end()) + { + available_prns.insert(prn_); + } + } + + int32_t numSatellitesObserved = available_prns.size(); line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); // Receiver clock offset (optional) //line += rightJustify(asString(clockOffset, 12), 15); @@ -7524,22 +8606,22 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c out << line << std::endl; std::string lineObs; - std::pair::iterator, std::multimap::iterator> ret; + std::pair::iterator, std::multimap::iterator> ret; for (it = available_prns.begin(); it != available_prns.end(); it++) { lineObs.clear(); lineObs += satelliteSystem["GPS"]; - if (static_cast(*it) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(*it)); + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); ret = total_mmap.equal_range(*it); - for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) { lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -7550,8 +8632,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS CARRIER PHASE lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); @@ -7563,7 +8645,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS DOPPLER lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); @@ -7575,7 +8657,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // GPS SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); @@ -7587,7 +8669,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c } -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& eph, double obs_time, const std::map& observables, const std::string galileo_bands) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& eph, double obs_time, const std::map& observables, const std::string galileo_bands) { // RINEX observations timestamps are Galileo timestamps. // See http://gage14.upc.es/gLAB/HTML/Observation_Rinex_v3.01.html @@ -7632,10 +8714,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep //Number of satellites observed in current epoch //Get maps with Galileo observations - std::map observablesE1B; - std::map observablesE5A; - std::map observablesE5B; - std::map::const_iterator observables_iter; + std::map observablesE1B; + std::map observablesE5A; + std::map observablesE5B; + std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); observables_iter != observables.cend(); @@ -7645,32 +8727,32 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep std::string sig_(observables_iter->second.Signal); if ((system_.compare("E") == 0) && (sig_.compare("1B") == 0)) { - observablesE1B.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesE1B.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("E") == 0) && (sig_.compare("5X") == 0)) { - observablesE5A.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesE5A.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("E") == 0) && (sig_.compare("7X") == 0)) { - observablesE5B.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesE5B.insert(std::pair(observables_iter->first, observables_iter->second)); } } std::size_t found_1B = galileo_bands.find("1B"); std::size_t found_E5a = galileo_bands.find("5X"); std::size_t found_E5b = galileo_bands.find("7X"); - std::multimap total_map; - std::set available_prns; - std::set::iterator it; + std::multimap total_map; + std::set available_prns; + std::set::iterator it; if (found_1B != std::string::npos) { - for (observables_iter = observablesE1B.begin(); - observables_iter != observablesE1B.end(); + for (observables_iter = observablesE1B.cbegin(); + observables_iter != observablesE1B.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; - total_map.insert(std::pair(prn_, observables_iter->second)); + uint32_t prn_ = observables_iter->second.PRN; + total_map.insert(std::pair(prn_, observables_iter->second)); it = available_prns.find(prn_); if (it == available_prns.end()) { @@ -7684,7 +8766,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep observables_iter != observablesE5A.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; + uint32_t prn_ = observables_iter->second.PRN; it = available_prns.find(prn_); if (it == available_prns.end()) { @@ -7697,10 +8779,10 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep std::string sig = "1B"; std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); + total_map.insert(std::pair(prn_, gs)); } } - total_map.insert(std::pair(prn_, observables_iter->second)); + total_map.insert(std::pair(prn_, observables_iter->second)); } } if (found_E5b != std::string::npos) @@ -7709,7 +8791,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep observables_iter != observablesE5B.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; + uint32_t prn_ = observables_iter->second.PRN; it = available_prns.find(prn_); if (it == available_prns.end()) { @@ -7722,7 +8804,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep std::string sig = "1B"; std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); + total_map.insert(std::pair(prn_, gs)); } if (found_E5a != std::string::npos) { @@ -7732,7 +8814,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep std::string sig = "5X"; std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); + total_map.insert(std::pair(prn_, gs)); } } else @@ -7748,14 +8830,14 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep std::string sig = "5X"; std::memcpy(static_cast(gs.Signal), sig.c_str(), 3); gs.PRN = prn_; - total_map.insert(std::pair(prn_, gs)); + total_map.insert(std::pair(prn_, gs)); } } } - total_map.insert(std::pair(prn_, observables_iter->second)); + total_map.insert(std::pair(prn_, observables_iter->second)); } } - int numSatellitesObserved = available_prns.size(); + int32_t numSatellitesObserved = available_prns.size(); line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); // Receiver clock offset (optional) //line += rightJustify(asString(clockOffset, 12), 15); @@ -7764,22 +8846,22 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep out << line << std::endl; std::string lineObs; - std::pair::iterator, std::multimap::iterator> ret; + std::pair::iterator, std::multimap::iterator> ret; for (it = available_prns.begin(); it != available_prns.end(); it++) { lineObs.clear(); lineObs += satelliteSystem["Galileo"]; - if (static_cast(*it) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(*it)); + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); ret = total_map.equal_range(*it); - for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) { lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -7790,8 +8872,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo CARRIER PHASE lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); @@ -7803,7 +8885,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo DOPPLER lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); @@ -7815,7 +8897,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); @@ -7827,7 +8909,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep } -void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& observables) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& observables) { if (galileo_eph.e_1) { @@ -7873,11 +8955,11 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep //Number of satellites observed in current epoch //Get maps with observations - std::map observablesG1C; - std::map observablesE1B; - std::map observablesE5A; - std::map observablesE5B; - std::map::const_iterator observables_iter; + std::map observablesG1C; + std::map observablesE1B; + std::map observablesE5A; + std::map observablesE5B; + std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); observables_iter != observables.cend(); @@ -7887,31 +8969,31 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep std::string sig_(observables_iter->second.Signal); if ((system_.compare("E") == 0) && (sig_.compare("1B") == 0)) { - observablesE1B.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesE1B.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("E") == 0) && (sig_.compare("5X") == 0)) { - observablesE5A.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesE5A.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("E") == 0) && (sig_.compare("7X") == 0)) { - observablesE5B.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesE5B.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) { - observablesG1C.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesG1C.insert(std::pair(observables_iter->first, observables_iter->second)); } } - std::multimap total_gal_map; - std::set available_gal_prns; - std::set::iterator it; + std::multimap total_gal_map; + std::set available_gal_prns; + std::set::iterator it; for (observables_iter = observablesE1B.cbegin(); observables_iter != observablesE1B.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; - total_gal_map.insert(std::pair(prn_, observables_iter->second)); + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); it = available_gal_prns.find(prn_); if (it == available_gal_prns.end()) { @@ -7923,8 +9005,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep observables_iter != observablesE5A.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; - total_gal_map.insert(std::pair(prn_, observables_iter->second)); + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); it = available_gal_prns.find(prn_); if (it == available_gal_prns.end()) { @@ -7936,8 +9018,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep observables_iter != observablesE5B.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; - total_gal_map.insert(std::pair(prn_, observables_iter->second)); + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); it = available_gal_prns.find(prn_); if (it == available_gal_prns.end()) { @@ -7945,9 +9027,9 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } } - int numGalSatellitesObserved = available_gal_prns.size(); - int numGpsSatellitesObserved = observablesG1C.size(); - int numSatellitesObserved = numGalSatellitesObserved + numGpsSatellitesObserved; + int32_t numGalSatellitesObserved = available_gal_prns.size(); + int32_t numGpsSatellitesObserved = observablesG1C.size(); + int32_t numSatellitesObserved = numGalSatellitesObserved + numGpsSatellitesObserved; line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); // Receiver clock offset (optional) @@ -7968,12 +9050,12 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep s.assign(1, observables_iter->second.System); if (s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; if (s.compare("E") == 0) lineObs += satelliteSystem["Galileo"]; // should not happen - if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -7984,8 +9066,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // PHASE lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads / GPS_TWO_PI, 3), 14); @@ -7997,7 +9079,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); @@ -8009,7 +9091,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); @@ -8018,22 +9100,22 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep out << lineObs << std::endl; } - std::pair::iterator, std::multimap::iterator> ret; + std::pair::iterator, std::multimap::iterator> ret; for (it = available_gal_prns.begin(); it != available_gal_prns.end(); it++) { lineObs.clear(); lineObs += satelliteSystem["Galileo"]; - if (static_cast(*it) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(*it)); + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); ret = total_gal_map.equal_range(*it); - for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) { lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! + int32_t lli = 0; // Include in the observation!! if (lli == 0) { lineObs += std::string(1, ' '); @@ -8044,8 +9126,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // } // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo CARRIER PHASE lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); @@ -8057,7 +9139,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo DOPPLER lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); @@ -8069,7 +9151,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // { // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); // } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); // Galileo SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); @@ -8081,29 +9163,626 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } -void Rinex_Printer::to_date_time(int gps_week, int gps_tow, int& year, int& month, int& day, int& hour, int& minute, int& second) +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& observables) +{ + if (galileo_eph.e_1) + { + } // avoid warning, not needed + std::string line; + + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(eph, gps_obs_time); + std::string timestring = boost::posix_time::to_iso_string(p_gps_time); + //double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); + //double gps_t = eph.sv_clock_correction(obs_time); + double gps_t = gps_obs_time; + + std::string month(timestring, 4, 2); + std::string day(timestring, 6, 2); + std::string hour(timestring, 9, 2); + std::string minutes(timestring, 11, 2); + + std::string year(timestring, 0, 4); + line += std::string(1, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + + line += std::string(1, ' '); + double seconds = fmod(gps_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line += std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + + //Number of satellites observed in current epoch + + //Get maps with observations + std::map observablesG2S; + std::map observablesGL5; + std::map observablesE1B; + std::map observablesE5A; + std::map observablesE5B; + std::map::const_iterator observables_iter; + + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if ((system_.compare("E") == 0) && (sig_.compare("1B") == 0)) + { + observablesE1B.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("E") == 0) && (sig_.compare("5X") == 0)) + { + observablesE5A.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("E") == 0) && (sig_.compare("7X") == 0)) + { + observablesE5B.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) + { + observablesG2S.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("G") == 0) && (sig_.compare("L5") == 0)) + { + observablesGL5.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + std::multimap total_gps_map; + std::multimap total_gal_map; + std::set available_gal_prns; + std::set available_gps_prns; + std::set::iterator it; + for (observables_iter = observablesE1B.cbegin(); + observables_iter != observablesE1B.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesE5A.cbegin(); + observables_iter != observablesE5A.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesE5B.cbegin(); + observables_iter != observablesE5B.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesG2S.cbegin(); + observables_iter != observablesG2S.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gps_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gps_prns.find(prn_); + if (it == available_gps_prns.end()) + { + available_gps_prns.insert(prn_); + } + } + + for (observables_iter = observablesGL5.cbegin(); + observables_iter != observablesGL5.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gps_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gps_prns.find(prn_); + if (it == available_gps_prns.end()) + { + available_gps_prns.insert(prn_); + } + } + + int32_t numGalSatellitesObserved = available_gal_prns.size(); + int32_t numGpsSatellitesObserved = available_gps_prns.size(); + int32_t numSatellitesObserved = numGalSatellitesObserved + numGpsSatellitesObserved; + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + + // Receiver clock offset (optional) + //line += rightJustify(asString(clockOffset, 12), 15); + + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + std::string s; + std::string lineObs; + + std::pair::iterator, std::multimap::iterator> ret; + for (it = available_gps_prns.begin(); + it != available_gps_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["GPS"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + ret = total_gps_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int32_t lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + out << lineObs << std::endl; + } + + for (it = available_gal_prns.begin(); + it != available_gal_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["Galileo"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + ret = total_gal_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int32_t lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + //if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } +} + + +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& gps_cnav_eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& observables) +{ + if (galileo_eph.e_1) + { + } // avoid warning, not needed + if (gps_cnav_eph.d_e_eccentricity) + { + } // avoid warning, not needed + std::string line; + + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, gps_obs_time); + std::string timestring = boost::posix_time::to_iso_string(p_gps_time); + //double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); + //double gps_t = eph.sv_clock_correction(obs_time); + double gps_t = gps_obs_time; + + std::string month(timestring, 4, 2); + std::string day(timestring, 6, 2); + std::string hour(timestring, 9, 2); + std::string minutes(timestring, 11, 2); + + std::string year(timestring, 0, 4); + line += std::string(1, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + + line += std::string(1, ' '); + double seconds = fmod(gps_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line += std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + + //Number of satellites observed in current epoch + + //Get maps with observations + std::map observablesG2S; + std::map observablesGL5; + std::map observablesG1C; + std::map observablesE1B; + std::map observablesE5A; + std::map observablesE5B; + std::map::const_iterator observables_iter; + + for (observables_iter = observables.cbegin(); + observables_iter != observables.cend(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if ((system_.compare("E") == 0) && (sig_.compare("1B") == 0)) + { + observablesE1B.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("E") == 0) && (sig_.compare("5X") == 0)) + { + observablesE5A.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("E") == 0) && (sig_.compare("7X") == 0)) + { + observablesE5B.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) + { + observablesG2S.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("G") == 0) && (sig_.compare("L5") == 0)) + { + observablesGL5.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if ((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) + { + observablesG1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + std::multimap total_gps_map; + std::multimap total_gal_map; + std::set available_gal_prns; + std::set available_gps_prns; + std::set::iterator it; + for (observables_iter = observablesE1B.cbegin(); + observables_iter != observablesE1B.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesE5A.cbegin(); + observables_iter != observablesE5A.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesE5B.cbegin(); + observables_iter != observablesE5B.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gal_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gal_prns.find(prn_); + if (it == available_gal_prns.end()) + { + available_gal_prns.insert(prn_); + } + } + + for (observables_iter = observablesG1C.cbegin(); + observables_iter != observablesG1C.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gps_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gps_prns.find(prn_); + if (it == available_gps_prns.end()) + { + available_gps_prns.insert(prn_); + } + } + + for (observables_iter = observablesG2S.cbegin(); + observables_iter != observablesG2S.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gps_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gps_prns.find(prn_); + if (it == available_gps_prns.end()) + { + available_gps_prns.insert(prn_); + } + } + + for (observables_iter = observablesGL5.cbegin(); + observables_iter != observablesGL5.cend(); + observables_iter++) + { + uint32_t prn_ = observables_iter->second.PRN; + total_gps_map.insert(std::pair(prn_, observables_iter->second)); + it = available_gps_prns.find(prn_); + if (it == available_gps_prns.end()) + { + available_gps_prns.insert(prn_); + } + } + + int32_t numGalSatellitesObserved = available_gal_prns.size(); + int32_t numGpsSatellitesObserved = available_gps_prns.size(); + int32_t numSatellitesObserved = numGalSatellitesObserved + numGpsSatellitesObserved; + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + + // Receiver clock offset (optional) + //line += rightJustify(asString(clockOffset, 12), 15); + + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + std::string s; + std::string lineObs; + + std::pair::iterator, std::multimap::iterator> ret; + for (it = available_gps_prns.begin(); + it != available_gps_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["GPS"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + ret = total_gps_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int32_t lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + out << lineObs << std::endl; + } + + for (it = available_gal_prns.begin(); + it != available_gal_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["Galileo"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + ret = total_gal_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int32_t lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + + // Signal Strength Indicator (SSI) + int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + //else + // { + // lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + // } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // Galileo SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + //if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } +} + + +void Rinex_Printer::to_date_time(int32_t gps_week, int32_t gps_tow, int& year, int& month, int& day, int& hour, int& minute, int& second) { // represents GPS time (week, TOW) in the date time format of the Gregorian calendar. // -> Leap years are considered, but leap seconds are not. - int days_per_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + int32_t days_per_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // seconds in a not leap year - const int secs_per_day = 24 * 60 * 60; - const int secs_per_week = 7 * secs_per_day; - const int secs_per_normal_year = 365 * secs_per_day; - const int secs_per_leap_year = secs_per_normal_year + secs_per_day; + const int32_t secs_per_day = 24 * 60 * 60; + const int32_t secs_per_week = 7 * secs_per_day; + const int32_t secs_per_normal_year = 365 * secs_per_day; + const int32_t secs_per_leap_year = secs_per_normal_year + secs_per_day; // the GPS epoch is 06.01.1980 00:00, i.e. midnight 5. / 6. January 1980 // -> seconds since then - int secs_since_gps_epoch = gps_week * secs_per_week + gps_tow; + int32_t secs_since_gps_epoch = gps_week * secs_per_week + gps_tow; // find year, consider leap years bool is_leap_year; - int remaining_secs = secs_since_gps_epoch + 5 * secs_per_day; - for (int y = 1980; true; y++) + int32_t remaining_secs = secs_since_gps_epoch + 5 * secs_per_day; + for (int32_t y = 1980; true; y++) { is_leap_year = y % 4 == 0 && (y % 100 != 0 || y % 400 == 0); - int secs_in_year_y = is_leap_year ? secs_per_leap_year : secs_per_normal_year; + int32_t secs_in_year_y = is_leap_year ? secs_per_leap_year : secs_per_normal_year; if (secs_in_year_y <= remaining_secs) { @@ -8119,9 +9798,9 @@ void Rinex_Printer::to_date_time(int gps_week, int gps_tow, int& year, int& mont } // find month - for (int m = 1; true; m++) + for (int32_t m = 1; true; m++) { - int secs_in_month_m = days_per_month[m - 1] * secs_per_day; + int32_t secs_in_month_m = days_per_month[m - 1] * secs_per_day; if (is_leap_year && m == 2) // consider February of leap year { secs_in_month_m += secs_per_day; @@ -8161,19 +9840,19 @@ void Rinex_Printer::to_date_time(int gps_week, int gps_tow, int& year, int& mont // line1 << " "; // // // gps time of reception -// int gps_week; +// int32_t gps_week; // double gps_sec; // if(sbs_message.get_rx_time_obj().get_gps_time(gps_week, gps_sec)) // { -// int year; -// int month; -// int day; -// int hour; -// int minute; -// int second; +// int32_t year; +// int32_t month; +// int32_t day; +// int32_t hour; +// int32_t minute; +// int32_t second; // // double gps_sec_one_digit_precicion = round(gps_sec *10)/10; // to prevent rounding towards 60.0sec in the stream output -// int gps_tow = trunc(gps_sec_one_digit_precicion); +// int32_t gps_tow = trunc(gps_sec_one_digit_precicion); // double sub_sec = gps_sec_one_digit_precicion - double(gps_tow); // // to_date_time(gps_week, gps_tow, year, month, day, hour, minute, second); @@ -8234,9 +9913,9 @@ void Rinex_Printer::to_date_time(int gps_week, int gps_tow, int& year, int& mont //} -int Rinex_Printer::signalStrength(const double snr) +int32_t Rinex_Printer::signalStrength(const double snr) { - int ss; + int32_t ss; ss = int(std::min(std::max(int(floor(snr / 6)), 1), 9)); return ss; } @@ -8247,7 +9926,7 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Gps_Navigation_Me // if we are processing a file -> wait to leap second to resolve the ambiguity else take the week from the local system time //: idea resolve the ambiguity with the leap second http://www.colorado.edu/geography/gcraft/notes/gps/gpseow.htm const double utc_t = nav_msg.utc_time(nav_msg.d_TOW); - boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((utc_t + 604800 * static_cast(nav_msg.i_GPS_week)) * 1000)); + boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((utc_t + 604800 * static_cast(nav_msg.i_GPS_week)) * 1000)); boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); return p_time; } @@ -8260,7 +9939,7 @@ boost::posix_time::ptime Rinex_Printer::compute_GPS_time(const Gps_Ephemeris& ep // (see Pag. 17 in http://igscb.jpl.nasa.gov/igscb/data/format/rinex300.pdf) // --??? No time correction here, since it will be done in the RINEX processor const double gps_t = obs_time; - boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((gps_t + 604800 * static_cast(eph.i_GPS_week % 1024)) * 1000)); + boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((gps_t + 604800 * static_cast(eph.i_GPS_week % 1024)) * 1000)); boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); return p_time; } @@ -8273,7 +9952,7 @@ boost::posix_time::ptime Rinex_Printer::compute_GPS_time(const Gps_CNAV_Ephemeri // (see Pag. 17 in http://igscb.jpl.nasa.gov/igscb/data/format/rinex300.pdf) // --??? No time correction here, since it will be done in the RINEX processor const double gps_t = obs_time; - boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((gps_t + 604800 * static_cast(eph.i_GPS_week % 1024)) * 1000)); + boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((gps_t + 604800 * static_cast(eph.i_GPS_week % 1024)) * 1000)); boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); return p_time; } @@ -8285,7 +9964,7 @@ boost::posix_time::ptime Rinex_Printer::compute_Galileo_time(const Galileo_Ephem // (see Pag. 17 in http://igscb.jpl.nasa.gov/igscb/data/format/rinex301.pdf) // --??? No time correction here, since it will be done in the RINEX processor double galileo_t = obs_time; - boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((galileo_t + 604800 * static_cast(eph.WN_5)) * 1000)); // + boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((galileo_t + 604800 * static_cast(eph.WN_5)) * 1000)); // boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); return p_time; } @@ -8296,7 +9975,7 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephe double tod = 0.0; double glot2utc = 3 * 3600; double obs_time_glot = 0.0; - int i = 0; + int32_t i = 0; // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end obs_time_glot = obs_time + glot2utc; @@ -8336,7 +10015,7 @@ double Rinex_Printer::get_leap_second(const Glonass_Gnav_Ephemeris& eph, const d double tod = 0.0; double glot2utc = 3 * 3600; double obs_time_glot = 0.0; - int i = 0; + int32_t i = 0; double leap_second = 0; // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end diff --git a/src/algorithms/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index 2cd961956..dde6724a6 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -60,6 +60,7 @@ #include "GLONASS_L1_L2_CA.h" #include "gnss_synchro.h" #include +#include #include #include #include // for stringstream @@ -76,12 +77,12 @@ class Rinex_Printer { public: /*! - * \brief Default constructor. Creates GPS Navigation and Observables RINEX files and their headers + * \brief Default constructor. Creates GNSS Navigation and Observables RINEX files and their headers */ - Rinex_Printer(int version = 0); + Rinex_Printer(int version = 0, const std::string& base_path = "."); /*! - * \brief Default destructor. Closes GPS Navigation and Observables RINEX files + * \brief Default destructor. Closes GNSS Navigation and Observables RINEX files */ ~Rinex_Printer(); @@ -105,12 +106,17 @@ public: /*! * \brief Generates the Galileo Navigation Data header */ - void rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac); + void rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model); /*! * \brief Generates the Mixed (GPS/Galileo) Navigation Data header */ - void rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac); + void rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model); + + /*! + * \brief Generates the Mixed (GPS CNAV/Galileo) Navigation Data header + */ + void rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& iono, const Gps_CNAV_Utc_Model& utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model); /*! * \brief Generates the GLONASS L1, L2 C/A Navigation Data header @@ -120,7 +126,7 @@ public: /*! * \brief Generates the Mixed (Galileo/GLONASS) Navigation Data header */ - void rinex_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); + void rinex_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); /*! * \brief Generates the Mixed (GPS L1 C/A/GLONASS L1, L2) Navigation Data header @@ -128,8 +134,8 @@ public: void rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); /*! - * \brief Generates the Mixed (GPS L2C C/A/GLONASS L1, L2) Navigation Data header - */ + * \brief Generates the Mixed (GPS L2C C/A/GLONASS L1, L2) Navigation Data header + */ void rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps_iono, const Gps_CNAV_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); /*! @@ -140,12 +146,12 @@ public: /*! * \brief Generates the GPS L2 Observation data header */ - void rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const double d_TOW_first_observation); + void rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const double d_TOW_first_observation, const std::string gps_bands = "2S"); /*! - * \brief Generates the dual frequency GPS L1 & L2 Observation data header + * \brief Generates the dual frequency GPS L1 & L2/L5 Observation data header */ - void rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, const double d_TOW_first_observation); + void rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, const double d_TOW_first_observation, const std::string gps_bands = "1C 2S"); /*! * \brief Generates the Galileo Observation data header. Example: bands("1B"), bands("1B 5X"), bands("5X"), ... Default: "1B". @@ -157,6 +163,16 @@ public: */ void rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation, const std::string galileo_bands = "1B"); + /*! + * \brief Generates the Mixed (GPS/Galileo) Observation data header. Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". + */ + void rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& eph_cnav, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation, const std::string gps_bands = "1C 2S", const std::string galileo_bands = "1B"); + + /*! + * \brief Generates the Mixed (GPS/Galileo) Observation data header. Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". + */ + void rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& eph_cnav, const Galileo_Ephemeris& galileo_eph, const double d_TOW_first_observation, const std::string gps_bands = "2S", const std::string galileo_bands = "1B"); + /*! * \brief Generates the GLONASS GNAV Observation data header. Example: bands("1C"), bands("1C 2C"), bands("2C"), ... Default: "1C". */ @@ -221,87 +237,102 @@ public: /*! * \brief Writes data from the GPS L1 C/A navigation message into the RINEX file */ - void log_rinex_nav(std::fstream& out, const std::map& eph_map); + void log_rinex_nav(std::fstream& out, const std::map& eph_map); /*! * \brief Writes data from the GPS L2 navigation message into the RINEX file */ - void log_rinex_nav(std::fstream& out, const std::map& eph_map); + void log_rinex_nav(std::fstream& out, const std::map& eph_map); /*! * \brief Writes data from the Galileo navigation message into the RINEX file */ - void log_rinex_nav(std::fstream& out, const std::map& eph_map); + void log_rinex_nav(std::fstream& out, const std::map& eph_map); /*! * \brief Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file */ - void log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map); + void log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map); + + /*! + * \brief Writes data from the Mixed (GPS/Galileo) navigation message into the RINEX file + */ + void log_rinex_nav(std::fstream& out, const std::map& gps_cnav_eph_map, const std::map& galileo_eph_map); /*! * \brief Writes data from the GLONASS GNAV navigation message into the RINEX file */ - void log_rinex_nav(std::fstream& out, const std::map& eph_map); + void log_rinex_nav(std::fstream& out, const std::map& eph_map); /*! * \brief Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file */ - void log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map); + void log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map); /*! * \brief Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file */ - void log_rinex_nav(std::fstream& out, const std::map& gps_cnav_eph_map, const std::map& glonass_gnav_eph_map); + void log_rinex_nav(std::fstream& out, const std::map& gps_cnav_eph_map, const std::map& glonass_gnav_eph_map); /*! * \brief Writes data from the Mixed (Galileo/ GLONASS GNAV) navigation message into the RINEX file */ - void log_rinex_nav(std::fstream& out, const std::map& galileo_eph_map, const std::map& glonass_gnav_eph_map); + void log_rinex_nav(std::fstream& out, const std::map& galileo_eph_map, const std::map& glonass_gnav_eph_map); /*! * \brief Writes GPS L1 observables into the RINEX file */ - void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, double obs_time, const std::map& observables); + void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, double obs_time, const std::map& observables); /*! * \brief Writes GPS L2 observables into the RINEX file */ - void log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, double obs_time, const std::map& observables); + void log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, double obs_time, const std::map& observables); /*! * \brief Writes dual frequency GPS L1 and L2 observables into the RINEX file */ - void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, double obs_time, const std::map& observables); + void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, const Gps_CNAV_Ephemeris& eph_cnav, double obs_time, const std::map& observables); /*! * \brief Writes Galileo observables into the RINEX file. Example: galileo_bands("1B"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". */ - void log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& eph, double obs_time, const std::map& observables, const std::string galileo_bands = "1B"); + void log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& eph, double obs_time, const std::map& observables, const std::string galileo_bands = "1B"); /*! * \brief Writes Mixed GPS / Galileo observables into the RINEX file */ - void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, const double gps_obs_time, const std::map& observables); + void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& galileo_eph, const double gps_obs_time, const std::map& observables); + + /*! + * \brief Writes Mixed GPS / Galileo observables into the RINEX file + */ + void log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& observables); + + /*! + * \brief Writes Mixed GPS / Galileo observables into the RINEX file + */ + void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& gps_cnav_eph, const Galileo_Ephemeris& galileo_eph, double gps_obs_time, const std::map& observables); /*! * \brief Writes GLONASS GNAV observables into the RINEX file. Example: glonass_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". */ - void log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, double obs_time, const std::map& observables, const std::string glonass_bands = "1C"); + void log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, double obs_time, const std::map& observables, const std::string glonass_bands = "1C"); /*! * \brief Writes Mixed GPS L1 C/A - GLONASS observables into the RINEX file */ - void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map& observables); + void log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map& observables); /*! * \brief Writes Mixed GPS L2C - GLONASS observables into the RINEX file */ - void log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& gps_cnav_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map& observables); + void log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& gps_cnav_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map& observables); /*! * \brief Writes Mixed Galileo/GLONASS observables into the RINEX file */ - void log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map& observables); + void log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map& observables); /*! * \brief Represents GPS time in the date time format. Leap years are considered, but leap seconds are not. @@ -317,9 +348,11 @@ public: void update_nav_header(std::fstream& out, const Gps_CNAV_Utc_Model& utc_model, const Gps_CNAV_Iono& iono); - void update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac); + void update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model); - void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac); + void update_nav_header(std::fstream& out, const Gps_CNAV_Utc_Model& utc_model, const Gps_CNAV_Iono& iono, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model); + + void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model); void update_nav_header(std::fstream& out, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); @@ -327,7 +360,7 @@ public: void update_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps_cnav_iono, const Gps_CNAV_Utc_Model& gps_cnav_utc, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); - void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); + void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac); void update_obs_header(std::fstream& out, const Gps_Utc_Model& utc_model); @@ -523,9 +556,9 @@ private: /* * Convert a string to an integer. * @param s string containing a number. - * @return long integer representation of string. + * @return int64_t integer representation of string. */ - inline long asInt(const std::string& s) + inline int64_t asInt(const std::string& s) { return strtol(s.c_str(), 0, 10); } @@ -658,7 +691,7 @@ inline std::string& Rinex_Printer::sci2for(std::string& aStr, std::string::size_type idx = aStr.find('.', startPos); int expAdd = 0; std::string exp; - long iexp; + int64_t iexp; //If checkSwitch is false, always redo the exponential. Otherwise, //set it to false. bool redoexp = !checkSwitch; @@ -761,7 +794,7 @@ inline std::string Rinex_Printer::asFixWidthString(const int x, const int width, } -inline long asInt(const std::string& s) +inline int64_t asInt(const std::string& s) { return strtol(s.c_str(), 0, 10); } diff --git a/src/algorithms/PVT/libs/rtcm_printer.cc b/src/algorithms/PVT/libs/rtcm_printer.cc index cd400ed4b..400132e0c 100644 --- a/src/algorithms/PVT/libs/rtcm_printer.cc +++ b/src/algorithms/PVT/libs/rtcm_printer.cc @@ -33,6 +33,9 @@ #include "rtcm_printer.h" #include +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem #include #include #include // for O_RDWR @@ -42,41 +45,76 @@ using google::LogMessage; -Rtcm_Printer::Rtcm_Printer(std::string filename, bool flag_rtcm_server, bool flag_rtcm_tty_port, unsigned short rtcm_tcp_port, unsigned short rtcm_station_id, std::string rtcm_dump_devname, bool time_tag_name) +Rtcm_Printer::Rtcm_Printer(std::string filename, bool flag_rtcm_file_dump, bool flag_rtcm_server, bool flag_rtcm_tty_port, uint16_t rtcm_tcp_port, uint16_t rtcm_station_id, std::string rtcm_dump_devname, bool time_tag_name, const std::string& base_path) { boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time(); tm timeinfo = boost::posix_time::to_tm(pt); + d_rtcm_file_dump = flag_rtcm_file_dump; + rtcm_base_path = base_path; + if (d_rtcm_file_dump) + { + boost::filesystem::path full_path(boost::filesystem::current_path()); + const boost::filesystem::path p(rtcm_base_path); + if (!boost::filesystem::exists(p)) + { + std::string new_folder; + for (auto& folder : boost::filesystem::path(rtcm_base_path)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + std::cout << "Could not create the " << new_folder << " folder." << std::endl; + rtcm_base_path = full_path.string(); + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + } + else + { + rtcm_base_path = p.string(); + } + if (rtcm_base_path.compare(".") != 0) + { + std::cout << "RTCM binary file will be stored at " << rtcm_base_path << std::endl; + } + + rtcm_base_path = rtcm_base_path + boost::filesystem::path::preferred_separator; + } if (time_tag_name) { std::stringstream strm0; - const int year = timeinfo.tm_year - 100; + const int32_t year = timeinfo.tm_year - 100; strm0 << year; - const int month = timeinfo.tm_mon + 1; + const int32_t month = timeinfo.tm_mon + 1; if (month < 10) { strm0 << "0"; } strm0 << month; - const int day = timeinfo.tm_mday; + const int32_t day = timeinfo.tm_mday; if (day < 10) { strm0 << "0"; } strm0 << day << "_"; - const int hour = timeinfo.tm_hour; + const int32_t hour = timeinfo.tm_hour; if (hour < 10) { strm0 << "0"; } strm0 << hour; - const int min = timeinfo.tm_min; + const int32_t min = timeinfo.tm_min; if (min < 10) { strm0 << "0"; } strm0 << min; - const int sec = timeinfo.tm_sec; + const int32_t sec = timeinfo.tm_sec; if (sec < 10) { strm0 << "0"; @@ -89,11 +127,18 @@ Rtcm_Printer::Rtcm_Printer(std::string filename, bool flag_rtcm_server, bool fla { rtcm_filename = filename + ".rtcm"; } - - rtcm_file_descriptor.open(rtcm_filename.c_str(), std::ios::out); - if (rtcm_file_descriptor.is_open()) + rtcm_filename = rtcm_base_path + rtcm_filename; + if (d_rtcm_file_dump) { - DLOG(INFO) << "RTCM printer writing on " << rtcm_filename.c_str(); + rtcm_file_descriptor.open(rtcm_filename.c_str(), std::ios::out); + if (rtcm_file_descriptor.is_open()) + { + DLOG(INFO) << "RTCM printer writing on " << rtcm_filename.c_str(); + } + else + { + std::cout << "File " << rtcm_filename << "cannot be saved. Wrong permissions?" << std::endl; + } } rtcm_devname = rtcm_dump_devname; @@ -153,7 +198,7 @@ Rtcm_Printer::~Rtcm_Printer() } -bool Rtcm_Printer::Print_Rtcm_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables) +bool Rtcm_Printer::Print_Rtcm_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables) { std::string m1001 = rtcm->print_MT1001(gps_eph, obs_time, observables, station_id); Rtcm_Printer::Print_Message(m1001); @@ -161,7 +206,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1001(const Gps_Ephemeris& gps_eph, double obs_ti } -bool Rtcm_Printer::Print_Rtcm_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables) +bool Rtcm_Printer::Print_Rtcm_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables) { std::string m1002 = rtcm->print_MT1002(gps_eph, obs_time, observables, station_id); Rtcm_Printer::Print_Message(m1002); @@ -169,7 +214,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1002(const Gps_Ephemeris& gps_eph, double obs_ti } -bool Rtcm_Printer::Print_Rtcm_MT1003(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map& observables) +bool Rtcm_Printer::Print_Rtcm_MT1003(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map& observables) { std::string m1003 = rtcm->print_MT1003(gps_eph, cnav_eph, obs_time, observables, station_id); Rtcm_Printer::Print_Message(m1003); @@ -177,7 +222,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1003(const Gps_Ephemeris& gps_eph, const Gps_CNA } -bool Rtcm_Printer::Print_Rtcm_MT1004(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map& observables) +bool Rtcm_Printer::Print_Rtcm_MT1004(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map& observables) { std::string m1003 = rtcm->print_MT1004(gps_eph, cnav_eph, obs_time, observables, station_id); Rtcm_Printer::Print_Message(m1003); @@ -185,7 +230,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1004(const Gps_Ephemeris& gps_eph, const Gps_CNA } -bool Rtcm_Printer::Print_Rtcm_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables) +bool Rtcm_Printer::Print_Rtcm_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables) { std::string m1009 = rtcm->print_MT1009(glonass_gnav_eph, obs_time, observables, station_id); Rtcm_Printer::Print_Message(m1009); @@ -193,7 +238,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_ } -bool Rtcm_Printer::Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables) +bool Rtcm_Printer::Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables) { std::string m1010 = rtcm->print_MT1010(glonass_gnav_eph, obs_time, observables, station_id); Rtcm_Printer::Print_Message(m1010); @@ -201,7 +246,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_ } -bool Rtcm_Printer::Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables) +bool Rtcm_Printer::Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables) { std::string m1011 = rtcm->print_MT1011(glonass_gnav_ephL1, glonass_gnav_ephL2, obs_time, observables, station_id); Rtcm_Printer::Print_Message(m1011); @@ -209,7 +254,7 @@ bool Rtcm_Printer::Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ } -bool Rtcm_Printer::Print_Rtcm_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables) +bool Rtcm_Printer::Print_Rtcm_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables) { std::string m1012 = rtcm->print_MT1012(glonass_gnav_ephL1, glonass_gnav_ephL2, obs_time, observables, station_id); Rtcm_Printer::Print_Message(m1012); @@ -241,15 +286,15 @@ bool Rtcm_Printer::Print_Rtcm_MT1045(const Galileo_Ephemeris& gal_eph) } -bool Rtcm_Printer::Print_Rtcm_MSM(unsigned int msm_number, const Gps_Ephemeris& gps_eph, +bool Rtcm_Printer::Print_Rtcm_MSM(uint32_t msm_number, const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& gps_cnav_eph, const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages) { @@ -297,7 +342,7 @@ int Rtcm_Printer::init_serial(std::string serial_device) /* * Opens the serial device and sets the default baud rate for a RTCM transmission (9600,8,N,1) */ - int fd = 0; + int32_t fd = 0; struct termios options; long BAUD; long DATABITS; @@ -341,14 +386,17 @@ void Rtcm_Printer::close_serial() bool Rtcm_Printer::Print_Message(const std::string& message) { //write to file - try + if (d_rtcm_file_dump) { - rtcm_file_descriptor << message << std::endl; - } - catch (const std::exception& ex) - { - DLOG(INFO) << "RTCM printer cannot write on the output file " << rtcm_filename.c_str(); - return false; + try + { + rtcm_file_descriptor << message << std::endl; + } + catch (const std::exception& ex) + { + DLOG(INFO) << "RTCM printer cannot write on the output file " << rtcm_filename.c_str(); + return false; + } } //write to serial device @@ -372,25 +420,25 @@ std::string Rtcm_Printer::print_MT1005_test() } -unsigned int Rtcm_Printer::lock_time(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +uint32_t Rtcm_Printer::lock_time(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { return rtcm->lock_time(eph, obs_time, gnss_synchro); } -unsigned int Rtcm_Printer::lock_time(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +uint32_t Rtcm_Printer::lock_time(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { return rtcm->lock_time(eph, obs_time, gnss_synchro); } -unsigned int Rtcm_Printer::lock_time(const Galileo_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +uint32_t Rtcm_Printer::lock_time(const Galileo_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { return rtcm->lock_time(eph, obs_time, gnss_synchro); } -unsigned int Rtcm_Printer::lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +uint32_t Rtcm_Printer::lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { return rtcm->lock_time(eph, obs_time, gnss_synchro); } diff --git a/src/algorithms/PVT/libs/rtcm_printer.h b/src/algorithms/PVT/libs/rtcm_printer.h index c0a926895..bb34f7ea6 100644 --- a/src/algorithms/PVT/libs/rtcm_printer.h +++ b/src/algorithms/PVT/libs/rtcm_printer.h @@ -48,17 +48,17 @@ public: /*! * \brief Default constructor. */ - Rtcm_Printer(std::string filename, bool flag_rtcm_server, bool flag_rtcm_tty_port, unsigned short rtcm_tcp_port, unsigned short rtcm_station_id, std::string rtcm_dump_filename, bool time_tag_name = true); + Rtcm_Printer(std::string filename, bool flag_rtcm_file_dump, bool flag_rtcm_server, bool flag_rtcm_tty_port, uint16_t rtcm_tcp_port, uint16_t rtcm_station_id, std::string rtcm_dump_filename, bool time_tag_name = true, const std::string& base_path = "."); /*! * \brief Default destructor. */ ~Rtcm_Printer(); - bool Print_Rtcm_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables); - bool Print_Rtcm_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables); - bool Print_Rtcm_MT1003(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map& observables); - bool Print_Rtcm_MT1004(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map& observables); + bool Print_Rtcm_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables); + bool Print_Rtcm_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables); + bool Print_Rtcm_MT1003(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map& observables); + bool Print_Rtcm_MT1004(const Gps_Ephemeris& gps_eph, const Gps_CNAV_Ephemeris& cnav_eph, double obs_time, const std::map& observables); /*! * \brief Prints L1-Only GLONASS RTK Observables * \details This GLONASS message type is not generally used or supported; type 1012 is to be preferred. @@ -68,7 +68,7 @@ public: * \param observables Set of observables as defined by the platform * \return true or false upon operation success */ - bool Print_Rtcm_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables); + bool Print_Rtcm_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables); /*! * \brief Prints Extended L1-Only GLONASS RTK Observables * \details This GLONASS message type is used when only L1 data is present and bandwidth is very tight, often 1012 is used in such cases. @@ -78,7 +78,7 @@ public: * \param observables Set of observables as defined by the platform * \return true or false upon operation success */ - bool Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables); + bool Print_Rtcm_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables); /*! * \brief Prints L1&L2 GLONASS RTK Observables * \details This GLONASS message type is not generally used or supported; type 1012 is to be preferred @@ -89,7 +89,7 @@ public: * \param observables Set of observables as defined by the platform * \return true or false upon operation success */ - bool Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables); + bool Print_Rtcm_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables); /*! * \brief Prints Extended L1&L2 GLONASS RTK Observables * \details This GLONASS message type is the most common observational message type, with L1/L2/SNR content. This is one of the most common messages found. @@ -100,7 +100,7 @@ public: * \param observables Set of observables as defined by the platform * \return true or false upon operation success */ - bool Print_Rtcm_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables); + bool Print_Rtcm_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables); bool Print_Rtcm_MT1019(const Gps_Ephemeris& gps_eph); //& observables, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages); std::string print_MT1005_test(); // rtcm; bool Print_Message(const std::string& message); + bool d_rtcm_file_dump; }; #endif diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index 7f3606051..1481dea0e 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -53,26 +53,33 @@ #include "rtklib_solver.h" #include "rtklib_conversions.h" +#include "rtklib_solution.h" #include "GPS_L1_CA.h" #include "Galileo_E1.h" #include "GLONASS_L1_L2_CA.h" +#include #include using google::LogMessage; -rtklib_solver::rtklib_solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, rtk_t& rtk) +rtklib_solver::rtklib_solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, bool flag_dump_to_mat, rtk_t &rtk) { // init empty ephemeris for all the available GNSS channels d_nchannels = nchannels; d_dump_filename = dump_filename; d_flag_dump_enabled = flag_dump_to_file; + d_flag_dump_mat_enabled = flag_dump_to_mat; count_valid_position = 0; this->set_averaging_flag(false); rtk_ = rtk; for (unsigned int i = 0; i < 4; i++) dop_[i] = 0.0; pvt_sol = {{0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, '0', '0', '0', 0, 0, 0}; - + ssat_t ssat0 = {0, 0, {0.0}, {0.0}, {0.0}, {'0'}, {'0'}, {'0'}, {'0'}, {'0'}, {}, {}, {}, {}, 0.0, 0.0, 0.0, 0.0, {{{0, 0}}, {{0, 0}}}, {{}, {}}}; + for (unsigned int i = 0; i < MAXSAT; i++) + { + pvt_ssat[i] = ssat0; + } // ############# ENABLE DATA FILE LOG ################# if (d_flag_dump_enabled == true) { @@ -84,14 +91,309 @@ rtklib_solver::rtklib_solver(int nchannels, std::string dump_filename, bool flag d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); LOG(INFO) << "PVT lib dump enabled Log file: " << d_dump_filename.c_str(); } - catch (const std::ifstream::failure& e) + catch (const std::ifstream::failure &e) { - LOG(WARNING) << "Exception opening PVT lib dump file " << e.what(); + LOG(WARNING) << "Exception opening RTKLIB dump file " << e.what(); } } } } +bool rtklib_solver::save_matfile() +{ + // READ DUMP FILE + std::string dump_filename = d_dump_filename; + std::ifstream::pos_type size; + int32_t number_of_double_vars = 21; + int32_t number_of_uint32_vars = 2; + int32_t number_of_uint8_vars = 3; + int32_t number_of_float_vars = 2; + int32_t epoch_size_bytes = sizeof(double) * number_of_double_vars + + sizeof(uint32_t) * number_of_uint32_vars + + sizeof(uint8_t) * number_of_uint8_vars + + sizeof(float) * number_of_float_vars; + std::ifstream dump_file; + std::cout << "Generating .mat file for " << dump_filename << std::endl; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return false; + } + // count number of epochs and rewind + int64_t num_epoch = 0LL; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return false; + } + + uint32_t *TOW_at_current_symbol_ms = new uint32_t[num_epoch]; + uint32_t *week = new uint32_t[num_epoch]; + double *RX_time = new double[num_epoch]; + double *user_clk_offset = new double[num_epoch]; + double *pos_x = new double[num_epoch]; + double *pos_y = new double[num_epoch]; + double *pos_z = new double[num_epoch]; + double *vel_x = new double[num_epoch]; + double *vel_y = new double[num_epoch]; + double *vel_z = new double[num_epoch]; + double *cov_xx = new double[num_epoch]; + double *cov_yy = new double[num_epoch]; + double *cov_zz = new double[num_epoch]; + double *cov_xy = new double[num_epoch]; + double *cov_yz = new double[num_epoch]; + double *cov_zx = new double[num_epoch]; + double *latitude = new double[num_epoch]; + double *longitude = new double[num_epoch]; + double *height = new double[num_epoch]; + uint8_t *valid_sats = new uint8_t[num_epoch]; + uint8_t *solution_status = new uint8_t[num_epoch]; + uint8_t *solution_type = new uint8_t[num_epoch]; + float *AR_ratio_factor = new float[num_epoch]; + float *AR_ratio_threshold = new float[num_epoch]; + double *gdop = new double[num_epoch]; + double *pdop = new double[num_epoch]; + double *hdop = new double[num_epoch]; + double *vdop = new double[num_epoch]; + + try + { + if (dump_file.is_open()) + { + for (int64_t i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&TOW_at_current_symbol_ms[i]), sizeof(uint32_t)); + dump_file.read(reinterpret_cast(&week[i]), sizeof(uint32_t)); + dump_file.read(reinterpret_cast(&RX_time[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&user_clk_offset[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&pos_x[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&pos_y[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&pos_z[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&vel_x[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&vel_y[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&vel_z[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_xx[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_yy[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_zz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_xy[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_yz[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&cov_zx[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&latitude[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&longitude[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&height[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&valid_sats[i]), sizeof(uint8_t)); + dump_file.read(reinterpret_cast(&solution_status[i]), sizeof(uint8_t)); + dump_file.read(reinterpret_cast(&solution_type[i]), sizeof(uint8_t)); + dump_file.read(reinterpret_cast(&AR_ratio_factor[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&AR_ratio_threshold[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&gdop[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&pdop[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&hdop[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&vdop[i]), sizeof(double)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] TOW_at_current_symbol_ms; + delete[] week; + delete[] RX_time; + delete[] user_clk_offset; + delete[] pos_x; + delete[] pos_y; + delete[] pos_z; + delete[] vel_x; + delete[] vel_y; + delete[] vel_z; + delete[] cov_xx; + delete[] cov_yy; + delete[] cov_zz; + delete[] cov_xy; + delete[] cov_yz; + delete[] cov_zx; + delete[] latitude; + delete[] longitude; + delete[] height; + delete[] valid_sats; + delete[] solution_status; + delete[] solution_type; + delete[] AR_ratio_factor; + delete[] AR_ratio_threshold; + delete[] gdop; + delete[] pdop; + delete[] hdop; + delete[] vdop; + + return false; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_UINT32, MAT_T_UINT32, 2, dims, TOW_at_current_symbol_ms, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("week", MAT_C_UINT32, MAT_T_UINT32, 2, dims, week, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("RX_time", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, RX_time, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("user_clk_offset", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, user_clk_offset, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("pos_x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_x, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("pos_y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_y, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("pos_z", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_z, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("vel_x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_x, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("vel_y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_y, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("vel_z", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_z, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_xx", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_xx, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_yy", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_yy, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_zz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_zz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_xy", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_xy, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_yz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_yz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("cov_zx", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_zx, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("latitude", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, latitude, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("longitude", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, longitude, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("height", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, height, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("valid_sats", MAT_C_UINT8, MAT_T_UINT8, 2, dims, valid_sats, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("solution_status", MAT_C_UINT8, MAT_T_UINT8, 2, dims, solution_status, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("solution_type", MAT_C_UINT8, MAT_T_UINT8, 2, dims, solution_type, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("AR_ratio_factor", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, AR_ratio_factor, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("AR_ratio_threshold", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, AR_ratio_threshold, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("gdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, gdop, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("pdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pdop, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("hdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, hdop, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("vdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vdop, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + + Mat_Close(matfp); + delete[] TOW_at_current_symbol_ms; + delete[] week; + delete[] RX_time; + delete[] user_clk_offset; + delete[] pos_x; + delete[] pos_y; + delete[] pos_z; + delete[] vel_x; + delete[] vel_y; + delete[] vel_z; + delete[] cov_xx; + delete[] cov_yy; + delete[] cov_zz; + delete[] cov_xy; + delete[] cov_yz; + delete[] cov_zx; + delete[] latitude; + delete[] longitude; + delete[] height; + delete[] valid_sats; + delete[] solution_status; + delete[] solution_type; + delete[] AR_ratio_factor; + delete[] AR_ratio_threshold; + delete[] gdop; + delete[] pdop; + delete[] hdop; + delete[] vdop; + + return true; +} rtklib_solver::~rtklib_solver() { @@ -101,11 +403,15 @@ rtklib_solver::~rtklib_solver() { d_dump_file.close(); } - catch (const std::exception& ex) + catch (const std::exception &ex) { - LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); + LOG(WARNING) << "Exception in destructor closing the RTKLIB dump file " << ex.what(); } } + if (d_flag_dump_mat_enabled) + { + save_matfile(); + } } @@ -133,7 +439,7 @@ double rtklib_solver::get_vdop() const } -bool rtklib_solver::get_PVT(const std::map& gnss_observables_map, bool flag_averaging) +bool rtklib_solver::get_PVT(const std::map &gnss_observables_map, bool flag_averaging) { std::map::const_iterator gnss_observables_iter; std::map::const_iterator galileo_ephemeris_iter; @@ -176,6 +482,7 @@ bool rtklib_solver::get_PVT(const std::map& gnss_observables_ band2 = true; } } + break; default: { } @@ -470,9 +777,9 @@ bool rtklib_solver::get_PVT(const std::map& gnss_observables_ for (int i = 0; i < MAXSAT; i++) { - nav_data.lam[i][0] = SPEED_OF_LIGHT / FREQ1; /* L1/E1 */ - nav_data.lam[i][1] = SPEED_OF_LIGHT / FREQ2; /* L2 */ - nav_data.lam[i][2] = SPEED_OF_LIGHT / FREQ5; /* L5/E5 */ + nav_data.lam[i][0] = SPEED_OF_LIGHT / FREQ1; // L1/E1 + nav_data.lam[i][1] = SPEED_OF_LIGHT / FREQ2; // L2 + nav_data.lam[i][2] = SPEED_OF_LIGHT / FREQ5; // L5/E5 } result = rtkpos(&rtk_, obs_data, valid_obs + glo_valid_obs, &nav_data); @@ -481,33 +788,38 @@ bool rtklib_solver::get_PVT(const std::map& gnss_observables_ { LOG(INFO) << "RTKLIB rtkpos error"; DLOG(INFO) << "RTKLIB rtkpos error message: " << rtk_.errbuf; - this->set_time_offset_s(0.0); //reset rx time estimation + this->set_time_offset_s(0.0); // reset rx time estimation this->set_num_valid_observations(0); } else { - this->set_num_valid_observations(rtk_.sol.ns); //record the number of valid satellites used by the PVT solver + this->set_num_valid_observations(rtk_.sol.ns); // record the number of valid satellites used by the PVT solver pvt_sol = rtk_.sol; // DOP computation unsigned int used_sats = 0; for (unsigned int i = 0; i < MAXSAT; i++) { - if (rtk_.ssat[i].vsat[0] == 1) used_sats++; + pvt_ssat[i] = rtk_.ssat[i]; + if (rtk_.ssat[i].vs == 1) + { + used_sats++; + } } - double azel[used_sats * 2]; + std::vector azel; + azel.reserve(used_sats * 2); unsigned int index_aux = 0; for (unsigned int i = 0; i < MAXSAT; i++) { - if (rtk_.ssat[i].vsat[0] == 1) + if (rtk_.ssat[i].vs == 1) { azel[2 * index_aux] = rtk_.ssat[i].azel[0]; azel[2 * index_aux + 1] = rtk_.ssat[i].azel[1]; index_aux++; } } - if (index_aux > 0) dops(index_aux, azel, 0.0, dop_); + if (index_aux > 0) dops(index_aux, azel.data(), 0.0, dop_); this->set_valid_position(true); arma::vec rx_position_and_time(4); rx_position_and_time(0) = pvt_sol.rr[0]; // [m] @@ -524,6 +836,22 @@ bool rtklib_solver::get_PVT(const std::map& gnss_observables_ rx_position_and_time(3) = pvt_sol.dtr[0] / GPS_C_m_s; // the receiver clock offset is expressed in [meters], so we convert it into [s] } this->set_rx_pos(rx_position_and_time.rows(0, 2)); // save ECEF position for the next iteration + + //compute Ground speed and COG + double ground_speed_ms = 0.0; + double pos[3]; + double enuv[3]; + ecef2pos(pvt_sol.rr, pos); + ecef2enu(pos, &pvt_sol.rr[3], enuv); + this->set_speed_over_ground(norm_rtk(enuv, 2)); + double new_cog; + if (ground_speed_ms >= 1.0) + { + new_cog = atan2(enuv[0], enuv[1]) * R2D; + if (new_cog < 0.0) new_cog += 360.0; + this->set_course_over_ground(new_cog); + } + //observable fix: //double offset_s = this->get_time_offset_s(); //this->set_time_offset_s(offset_s + (rx_position_and_time(3) / GPS_C_m_s)); // accumulate the rx time error for the next iteration [meters]->[seconds] @@ -554,34 +882,78 @@ bool rtklib_solver::get_PVT(const std::map& gnss_observables_ try { double tmp_double; + uint32_t tmp_uint32; + // TOW + tmp_uint32 = gnss_observables_map.begin()->second.TOW_at_current_symbol_ms; + d_dump_file.write(reinterpret_cast(&tmp_uint32), sizeof(uint32_t)); + // WEEK + tmp_uint32 = adjgpsweek(nav_data.eph[0].week); + d_dump_file.write(reinterpret_cast(&tmp_uint32), sizeof(uint32_t)); // PVT GPS time tmp_double = gnss_observables_map.begin()->second.RX_time; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - // ECEF User Position East [m] - tmp_double = rx_position_and_time(0); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - // ECEF User Position North [m] - tmp_double = rx_position_and_time(1); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - // ECEF User Position Up [m] - tmp_double = rx_position_and_time(2); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // User clock offset [s] tmp_double = rx_position_and_time(3); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + + // ECEF POS X,Y,X [m] + ECEF VEL X,Y,X [m/s] (6 x double) + tmp_double = pvt_sol.rr[0]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = pvt_sol.rr[1]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = pvt_sol.rr[2]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = pvt_sol.rr[3]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = pvt_sol.rr[4]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = pvt_sol.rr[5]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + + // position variance/covariance (m^2) {c_xx,c_yy,c_zz,c_xy,c_yz,c_zx} (6 x double) + tmp_double = pvt_sol.qr[0]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = pvt_sol.qr[1]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = pvt_sol.qr[2]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = pvt_sol.qr[3]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = pvt_sol.qr[4]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = pvt_sol.qr[5]; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + // GEO user position Latitude [deg] - tmp_double = this->get_latitude(); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = get_latitude(); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // GEO user position Longitude [deg] - tmp_double = this->get_longitude(); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = get_longitude(); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // GEO user position Height [m] - tmp_double = this->get_height(); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_double = get_height(); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + + // NUMBER OF VALID SATS + d_dump_file.write(reinterpret_cast(&pvt_sol.ns), sizeof(uint8_t)); + // RTKLIB solution status + d_dump_file.write(reinterpret_cast(&pvt_sol.stat), sizeof(uint8_t)); + // RTKLIB solution type (0:xyz-ecef,1:enu-baseline) + d_dump_file.write(reinterpret_cast(&pvt_sol.type), sizeof(uint8_t)); + // AR ratio factor for validation + d_dump_file.write(reinterpret_cast(&pvt_sol.ratio), sizeof(float)); + // AR ratio threshold for validation + d_dump_file.write(reinterpret_cast(&pvt_sol.thres), sizeof(float)); + + // GDOP / PDOP/ HDOP/ VDOP + d_dump_file.write(reinterpret_cast(&dop_[0]), sizeof(double)); + d_dump_file.write(reinterpret_cast(&dop_[1]), sizeof(double)); + d_dump_file.write(reinterpret_cast(&dop_[2]), sizeof(double)); + d_dump_file.write(reinterpret_cast(&dop_[3]), sizeof(double)); } - catch (const std::ifstream::failure& e) + catch (const std::ifstream::failure &e) { - LOG(WARNING) << "Exception writing PVT LS dump file " << e.what(); + LOG(WARNING) << "Exception writing RTKLIB dump file " << e.what(); } } } diff --git a/src/algorithms/PVT/libs/rtklib_solver.h b/src/algorithms/PVT/libs/rtklib_solver.h index aa5557606..293c0e06d 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.h +++ b/src/algorithms/PVT/libs/rtklib_solver.h @@ -60,6 +60,7 @@ #include "gps_navigation_message.h" #include "gps_cnav_navigation_message.h" #include "glonass_gnav_navigation_message.h" +#include "galileo_almanac.h" #include "gnss_synchro.h" #include "pvt_solution.h" #include @@ -76,13 +77,17 @@ private: rtk_t rtk_; std::string d_dump_filename; std::ofstream d_dump_file; - sol_t pvt_sol; + bool save_matfile(); + bool d_flag_dump_enabled; + bool d_flag_dump_mat_enabled; int d_nchannels; // Number of available channels for positioning double dop_[4]; public: - rtklib_solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, rtk_t& rtk); + sol_t pvt_sol; + ssat_t pvt_ssat[MAXSAT]; + rtklib_solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, bool flag_dump_to_mat, rtk_t& rtk); ~rtklib_solver(); bool get_PVT(const std::map& gnss_observables_map, bool flag_averaging); @@ -98,10 +103,11 @@ public: Galileo_Utc_Model galileo_utc_model; Galileo_Iono galileo_iono; - Galileo_Almanac galileo_almanac; + std::map galileo_almanac_map; Gps_Utc_Model gps_utc_model; Gps_Iono gps_iono; + std::map gps_almanac_map; Gps_CNAV_Iono gps_cnav_iono; Gps_CNAV_Utc_Model gps_cnav_utc_model; diff --git a/src/algorithms/acquisition/adapters/CMakeLists.txt b/src/algorithms/acquisition/adapters/CMakeLists.txt index 82b4b33c1..ee0046970 100644 --- a/src/algorithms/acquisition/adapters/CMakeLists.txt +++ b/src/algorithms/acquisition/adapters/CMakeLists.txt @@ -36,33 +36,79 @@ set(ACQ_ADAPTER_SOURCES glonass_l2_ca_pcps_acquisition.cc ) -if(ENABLE_FPGA) - set(ACQ_ADAPTER_SOURCES ${ACQ_ADAPTER_SOURCES} gps_l1_ca_pcps_acquisition_fpga.cc) -endif(ENABLE_FPGA) - -if(OPENCL_FOUND) - set(ACQ_ADAPTER_SOURCES ${ACQ_ADAPTER_SOURCES} gps_l1_ca_pcps_opencl_acquisition.cc) -endif(OPENCL_FOUND) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${Boost_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${ARMADILLO_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${GNURADIO_BLOCKS_INCLUDE_DIRS} - ${VOLK_GNSSSDR_INCLUDE_DIRS} +set(ACQ_ADAPTER_HEADERS + gps_l1_ca_pcps_acquisition.h + gps_l1_ca_pcps_assisted_acquisition.h + gps_l1_ca_pcps_acquisition_fine_doppler.h + gps_l1_ca_pcps_tong_acquisition.h + gps_l1_ca_pcps_quicksync_acquisition.h + gps_l2_m_pcps_acquisition.h + gps_l5i_pcps_acquisition.h + galileo_e1_pcps_ambiguous_acquisition.h + galileo_e1_pcps_cccwsr_ambiguous_acquisition.h + galileo_e1_pcps_quicksync_ambiguous_acquisition.h + galileo_e1_pcps_tong_ambiguous_acquisition.h + galileo_e1_pcps_8ms_ambiguous_acquisition.h + galileo_e5a_noncoherent_iq_acquisition_caf.h + galileo_e5a_pcps_acquisition.h + glonass_l1_ca_pcps_acquisition.h + glonass_l2_ca_pcps_acquisition.h +) + +if(ENABLE_FPGA) + set(ACQ_ADAPTER_SOURCES ${ACQ_ADAPTER_SOURCES} + gps_l1_ca_pcps_acquisition_fpga.cc + gps_l2_m_pcps_acquisition_fpga.cc + galileo_e1_pcps_ambiguous_acquisition_fpga.cc + galileo_e5a_pcps_acquisition_fpga.cc + gps_l5i_pcps_acquisition_fpga.cc + ) + set(ACQ_ADAPTER_HEADERS ${ACQ_ADAPTER_HEADERS} + gps_l1_ca_pcps_acquisition_fpga.h + gps_l2_m_pcps_acquisition_fpga.h + galileo_e1_pcps_ambiguous_acquisition_fpga.h + galileo_e5a_pcps_acquisition_fpga.h + gps_l5i_pcps_acquisition_fpga.h + ) +endif() + +if(OPENCL_FOUND) + set(ACQ_ADAPTER_SOURCES + ${ACQ_ADAPTER_SOURCES} + gps_l1_ca_pcps_opencl_acquisition.cc + ) + set(ACQ_ADAPTER_HEADERS ${ACQ_ADAPTER_HEADERS} + gps_l1_ca_pcps_opencl_acquisition.h + ) +endif() + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${Boost_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${ARMADILLO_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${GNURADIO_BLOCKS_INCLUDE_DIRS} + ${VOLK_GNSSSDR_INCLUDE_DIRS} ) -file(GLOB ACQ_ADAPTER_HEADERS "*.h") list(SORT ACQ_ADAPTER_HEADERS) +list(SORT ACQ_ADAPTER_SOURCES) add_library(acq_adapters ${ACQ_ADAPTER_SOURCES} ${ACQ_ADAPTER_HEADERS}) source_group(Headers FILES ${ACQ_ADAPTER_HEADERS}) -target_link_libraries(acq_adapters acquisition_lib gnss_sp_libs gnss_sdr_flags acq_gr_blocks ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES}) +target_link_libraries(acq_adapters + acquisition_lib + gnss_sp_libs + gnss_sdr_flags + acq_gr_blocks + ${Boost_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} +) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc index 60d19ad08..0c451be34 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc @@ -40,6 +40,9 @@ using google::LogMessage; +void GalileoE1Pcps8msAmbiguousAcquisition::stop_acquisition() +{ +} GalileoE1Pcps8msAmbiguousAcquisition::GalileoE1Pcps8msAmbiguousAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h index 5658aa06c..d64c0f28b 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h @@ -122,6 +122,12 @@ public: * \brief Restart acquisition algorithm */ void reset() override; + + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + void set_state(int state __attribute__((unused))) override{}; private: diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index f377a72c8..7efab9681 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -42,6 +42,10 @@ using google::LogMessage; +void GalileoE1PcpsAmbiguousAcquisition::stop_acquisition() +{ +} + GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -49,7 +53,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( Acq_Conf acq_parameters; configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "./data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; DLOG(INFO) << "role " << role; @@ -58,31 +62,38 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; - dump_ = configuration_->property(role + ".dump", false); - acq_parameters.dump = dump_; - acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); - blocking_ = configuration_->property(role + ".blocking", true); - acq_parameters.blocking = blocking_; + acq_parameters.samples_per_chip = static_cast(ceil((1.0 / Galileo_E1_CODE_CHIP_RATE_HZ) * static_cast(acq_parameters.fs_in))); doppler_max_ = configuration_->property(role + ".doppler_max", 5000); if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; acq_parameters.doppler_max = doppler_max_; - sampled_ms_ = 4; + acq_parameters.ms_per_code = 4; + sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters.ms_per_code); acq_parameters.sampled_ms = sampled_ms_; + if ((acq_parameters.sampled_ms % acq_parameters.ms_per_code) != 0) + { + LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 4. Setting it to 4"; + acq_parameters.sampled_ms = acq_parameters.ms_per_code; + } bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); acq_parameters.bit_transition_flag = bit_transition_flag_; use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions - max_dwells_ = configuration_->property(role + ".max_dwells", 1); acq_parameters.max_dwells = max_dwells_; + dump_ = configuration_->property(role + ".dump", false); + acq_parameters.dump = dump_; + acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); + blocking_ = configuration_->property(role + ".blocking", true); + acq_parameters.blocking = blocking_; dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); acq_parameters.dump_filename = dump_filename_; //--- Find number of samples per spreading code (4 ms) ----------------- - code_length_ = static_cast(std::round(static_cast(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); - acq_parameters.samples_per_code = code_length_; - int samples_per_ms = static_cast(std::round(static_cast(fs_in_) * 0.001)); + code_length_ = static_cast(std::floor(static_cast(fs_in_) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); + + float samples_per_ms = static_cast(fs_in_) * 0.001; acq_parameters.samples_per_ms = samples_per_ms; + acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast(Galileo_E1_CODE_PERIOD_MS); vector_length_ = sampled_ms_ * samples_per_ms; if (bit_transition_flag_) @@ -108,9 +119,6 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); - DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; - if (item_type_.compare("cbyte") == 0) { cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); @@ -271,18 +279,19 @@ void GalileoE1PcpsAmbiguousAcquisition::connect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cshort") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cbyte") == 0) { + // Since a byte-based acq implementation is not available, + // we just convert cshorts to gr_complex top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + top_block->connect(float_to_complex_, 0, acquisition_, 0); } else { @@ -295,20 +304,17 @@ void GalileoE1PcpsAmbiguousAcquisition::disconnect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cshort") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cbyte") == 0) { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + top_block->disconnect(float_to_complex_, 0, acquisition_, 0); } else { @@ -321,11 +327,11 @@ gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisition::get_left_block() { if (item_type_.compare("gr_complex") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cshort") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cbyte") == 0) { diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h index 56f79774d..657f03064 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.h @@ -36,7 +36,6 @@ #include "gnss_synchro.h" #include "pcps_acquisition.h" #include "complex_byte_to_float_x2.h" -#include #include #include #include @@ -132,10 +131,14 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; - gr::blocks::stream_to_vector::sptr stream_to_vector_; gr::blocks::float_to_complex::sptr float_to_complex_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_; size_t item_size_; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc new file mode 100644 index 000000000..041039147 --- /dev/null +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc @@ -0,0 +1,551 @@ +/*! + * \file galileo_e1_pcps_ambiguous_acquisition.cc + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Galileo E1 Signals + * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "galileo_e1_pcps_ambiguous_acquisition_fpga.h" +#include "configuration_interface.h" +#include "galileo_e1_signal_processing.h" +#include "Galileo_E1.h" +#include "gnss_sdr_flags.h" +#include +#include +#include + + +using google::LogMessage; + +void GalileoE1PcpsAmbiguousAcquisitionFpga::stop_acquisition() +{ +} + +GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( + ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + //printf("top acq constructor start\n"); + pcpsconf_fpga_t acq_parameters; + configuration_ = configuration; + std::string default_item_type = "gr_complex"; + std::string default_dump_filename = "./acquisition.mat"; + + DLOG(INFO) << "role " << role; + + // item_type_ = configuration_->property(role + ".item_type", default_item_type); + + long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); + long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + acq_parameters.fs_in = fs_in; + //if_ = configuration_->property(role + ".if", 0); + //acq_parameters.freq = if_; + + // dump_ = configuration_->property(role + ".dump", false); + // acq_parameters.dump = dump_; + // blocking_ = configuration_->property(role + ".blocking", true); + // acq_parameters.blocking = blocking_; + doppler_max_ = configuration_->property(role + ".doppler_max", 5000); + if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; + acq_parameters.doppler_max = doppler_max_; + //unsigned int sampled_ms = 4; + //acq_parameters.sampled_ms = sampled_ms; + unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 4); + acq_parameters.sampled_ms = sampled_ms; + + // bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); + // acq_parameters.bit_transition_flag = bit_transition_flag_; + // use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions + // acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; + acquire_pilot_ = configuration_->property(role + ".acquire_pilot", false); //will be true in future versions + + // max_dwells_ = configuration_->property(role + ".max_dwells", 1); + // acq_parameters.max_dwells = max_dwells_; + // dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); + // acq_parameters.dump_filename = dump_filename_; + //--- Find number of samples per spreading code (4 ms) ----------------- + unsigned int code_length = static_cast(std::round(static_cast(fs_in) / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS))); + //acq_parameters.samples_per_code = code_length_; + //int samples_per_ms = static_cast(std::round(static_cast(fs_in_) * 0.001)); + //acq_parameters.samples_per_ms = samples_per_ms; + //unsigned int vector_length = sampled_ms * samples_per_ms; + + // if (bit_transition_flag_) + // { + // vector_length_ *= 2; + // } + + //printf("fs_in = %d\n", fs_in); + //printf("Galileo_E1_B_CODE_LENGTH_CHIPS = %f\n", Galileo_E1_B_CODE_LENGTH_CHIPS); + //printf("Galileo_E1_CODE_CHIP_RATE_HZ = %f\n", Galileo_E1_CODE_CHIP_RATE_HZ); + //printf("acq adapter code_length = %d\n", code_length); + acq_parameters.code_length = code_length; + // The FPGA can only use FFT lengths that are a power of two. + float nbits = ceilf(log2f((float)code_length)); + unsigned int nsamples_total = pow(2, nbits); + unsigned int vector_length = nsamples_total; + //printf("acq adapter nsamples_total (= vector_length) = %d\n", vector_length); + unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0); + acq_parameters.select_queue_Fpga = select_queue_Fpga; + std::string default_device_name = "/dev/uio0"; + std::string device_name = configuration_->property(role + ".devicename", default_device_name); + acq_parameters.device_name = device_name; + acq_parameters.samples_per_ms = nsamples_total / sampled_ms; + acq_parameters.samples_per_code = nsamples_total; + + // compute all the GALILEO E1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time + // a channel is assigned) + gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT + std::complex* code = new std::complex[nsamples_total]; // buffer for the local code + gr_complex* fft_codes_padded = static_cast(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_all_fft_codes_ = new lv_16sc_t[nsamples_total * Galileo_E1_NUMBER_OF_CODES]; // memory containing all the possible fft codes for PRN 0 to 32 + float max; // temporary maxima search + + //int tmp_re, tmp_im; + + for (unsigned int PRN = 1; PRN <= Galileo_E1_NUMBER_OF_CODES; PRN++) + { + //code_ = new gr_complex[vector_length_]; + + bool cboc = false; // cboc is set to 0 when using the FPGA + + //std::complex* code = new std::complex[code_length_]; + + if (acquire_pilot_ == true) + { + //printf("yes acquiring pilot!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1\n"); + //set local signal generator to Galileo E1 pilot component (1C) + char pilot_signal[3] = "1C"; + galileo_e1_code_gen_complex_sampled(code, pilot_signal, + cboc, PRN, fs_in, 0, false); + } + else + { + char data_signal[3] = "1B"; + galileo_e1_code_gen_complex_sampled(code, data_signal, + cboc, PRN, fs_in, 0, false); + } + + // for (unsigned int i = 0; i < sampled_ms / 4; i++) + // { + // //memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_); + // memcpy(&(d_all_fft_codes_[i * code_length_]), code, sizeof(gr_complex) * code_length_); + // } + + + // // debug + // char filename[25]; + // FILE *fid; + // sprintf(filename,"gal_prn%d.txt", PRN); + // fid = fopen(filename, "w"); + // for (unsigned int kk=0;kk< nsamples_total; kk++) + // { + // fprintf(fid, "%f\n", code[kk].real()); + // fprintf(fid, "%f\n", code[kk].imag()); + // } + // fclose(fid); + + + // // fill in zero padding + for (int s = code_length; s < nsamples_total; s++) + { + code[s] = std::complex(static_cast(0, 0)); + //code[s] = 0; + } + + memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values + + // // debug + // char filename[25]; + // FILE *fid; + // sprintf(filename,"fft_gal_prn%d.txt", PRN); + // fid = fopen(filename, "w"); + // for (unsigned int kk=0;kk< nsamples_total; kk++) + // { + // fprintf(fid, "%f\n", fft_codes_padded[kk].real()); + // fprintf(fid, "%f\n", fft_codes_padded[kk].imag()); + // } + // fclose(fid); + + + // normalize the code + max = 0; // initialize maximum value + for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima + { + if (std::abs(fft_codes_padded[i].real()) > max) + { + max = std::abs(fft_codes_padded[i].real()); + } + if (std::abs(fft_codes_padded[i].imag()) > max) + { + max = std::abs(fft_codes_padded[i].imag()); + } + } + for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs + { + //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(4096*fft_codes_padded[i].real() * (pow(2, 3) - 1) / max)), + // static_cast(floor(4096*fft_codes_padded[i].imag() * (pow(2, 3) - 1) / max))); + // d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(1024*fft_codes_padded[i].real() * (pow(2, 5) - 1) / max)), + // static_cast(floor(1024*fft_codes_padded[i].imag() * (pow(2, 5) - 1) / max))); + // d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), + // static_cast(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); + // d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(16*fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)), + // static_cast(floor(16*fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max))); + d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), + static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); + + // tmp_re = static_cast(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)); + // tmp_im = static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max)); + + // if (tmp_re > 127) + // { + // tmp_re = 127; + // } + // if (tmp_re < -128) + // { + // tmp_re = -128; + // } + // if (tmp_im > 127) + // { + // tmp_im = 127; + // } + // if (tmp_im < -128) + // { + // tmp_im = -128; + // } + // d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(tmp_re), static_cast(tmp_im)); + // + } + + // // debug + // char filename2[25]; + // FILE *fid2; + // sprintf(filename2,"fft_gal_prn%d_norm.txt", PRN); + // fid2 = fopen(filename2, "w"); + // for (unsigned int kk=0;kk< nsamples_total; kk++) + // { + // fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real()); + // fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag()); + // } + // fclose(fid2); + } + + + // for (unsigned int PRN = 1; PRN <= Galileo_E1_NUMBER_OF_CODES; PRN++) + // { + // // debug + // char filename2[25]; + // FILE *fid2; + // sprintf(filename2,"fft_gal_prn%d_norm_last.txt", PRN); + // fid2 = fopen(filename2, "w"); + // for (unsigned int kk=0;kk< nsamples_total; kk++) + // { + // fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real()); + // fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag()); + // } + // fclose(fid2); + // } + + //acq_parameters + + acq_parameters.all_fft_codes = d_all_fft_codes_; + + // temporary buffers that we can delete + delete[] code; + delete fft_if; + delete[] fft_codes_padded; + + acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); + DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; + + // stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); + // DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; + + // if (item_type_.compare("cbyte") == 0) + // { + // cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); + // float_to_complex_ = gr::blocks::float_to_complex::make(); + // } + + channel_ = 0; + //threshold_ = 0.0; + doppler_step_ = 0; + gnss_synchro_ = 0; + //printf("top acq constructor end\n"); +} + + +GalileoE1PcpsAmbiguousAcquisitionFpga::~GalileoE1PcpsAmbiguousAcquisitionFpga() +{ + //printf("top acq destructor start\n"); + //delete[] code_; + delete[] d_all_fft_codes_; + //printf("top acq destructor end\n"); +} + + +void GalileoE1PcpsAmbiguousAcquisitionFpga::set_channel(unsigned int channel) +{ + //printf("top acq set channel start\n"); + channel_ = channel; + acquisition_fpga_->set_channel(channel_); + //printf("top acq set channel end\n"); +} + + +void GalileoE1PcpsAmbiguousAcquisitionFpga::set_threshold(float threshold) +{ + //printf("top acq set threshold start\n"); + // the .pfa parameter and the threshold calculation is only used for the CFAR algorithm. + // We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such. + + // float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); + // + // if (pfa == 0.0) pfa = configuration_->property(role_ + ".pfa", 0.0); + // + // if (pfa == 0.0) + // { + // threshold_ = threshold; + // } + // else + // { + // threshold_ = calculate_threshold(pfa); + // } + + DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; + acquisition_fpga_->set_threshold(threshold); + // acquisition_fpga_->set_threshold(threshold_); + //printf("top acq set threshold end\n"); +} + + +void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_max(unsigned int doppler_max) +{ + //printf("top acq set doppler max start\n"); + doppler_max_ = doppler_max; + + acquisition_fpga_->set_doppler_max(doppler_max_); + //printf("top acq set doppler max end\n"); +} + + +void GalileoE1PcpsAmbiguousAcquisitionFpga::set_doppler_step(unsigned int doppler_step) +{ + //printf("top acq set doppler step start\n"); + doppler_step_ = doppler_step; + + acquisition_fpga_->set_doppler_step(doppler_step_); + //printf("top acq set doppler step end\n"); +} + + +void GalileoE1PcpsAmbiguousAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) +{ + //printf("top acq set gnss synchro start\n"); + gnss_synchro_ = gnss_synchro; + + acquisition_fpga_->set_gnss_synchro(gnss_synchro_); + //printf("top acq set gnss synchro end\n"); +} + + +signed int GalileoE1PcpsAmbiguousAcquisitionFpga::mag() +{ + // printf("top acq mag start\n"); + return acquisition_fpga_->mag(); + //printf("top acq mag end\n"); +} + + +void GalileoE1PcpsAmbiguousAcquisitionFpga::init() +{ + // printf("top acq init start\n"); + acquisition_fpga_->init(); + // printf("top acq init end\n"); + //set_local_code(); +} + + +void GalileoE1PcpsAmbiguousAcquisitionFpga::set_local_code() +{ + // printf("top acq set local code start\n"); + // bool cboc = configuration_->property( + // "Acquisition" + boost::lexical_cast(channel_) + ".cboc", false); + // + // std::complex* code = new std::complex[code_length_]; + // + // if (acquire_pilot_ == true) + // { + // //set local signal generator to Galileo E1 pilot component (1C) + // char pilot_signal[3] = "1C"; + // galileo_e1_code_gen_complex_sampled(code, pilot_signal, + // cboc, gnss_synchro_->PRN, fs_in_, 0, false); + // } + // else + // { + // galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, + // cboc, gnss_synchro_->PRN, fs_in_, 0, false); + // } + // + // + // for (unsigned int i = 0; i < sampled_ms_ / 4; i++) + // { + // memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_); + // } + + //acquisition_fpga_->set_local_code(code_); + acquisition_fpga_->set_local_code(); + // delete[] code; + // printf("top acq set local code end\n"); +} + + +void GalileoE1PcpsAmbiguousAcquisitionFpga::reset() +{ + // printf("top acq reset start\n"); + acquisition_fpga_->set_active(true); + // printf("top acq reset end\n"); +} + + +void GalileoE1PcpsAmbiguousAcquisitionFpga::set_state(int state) +{ + // printf("top acq set state start\n"); + acquisition_fpga_->set_state(state); + // printf("top acq set state end\n"); +} + + +//float GalileoE1PcpsAmbiguousAcquisitionFpga::calculate_threshold(float pfa) +//{ +// unsigned int frequency_bins = 0; +// for (int doppler = static_cast(-doppler_max_); doppler <= static_cast(doppler_max_); doppler += doppler_step_) +// { +// frequency_bins++; +// } +// +// DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa; +// +// unsigned int ncells = vector_length_ * frequency_bins; +// double exponent = 1 / static_cast(ncells); +// double val = pow(1.0 - pfa, exponent); +// double lambda = double(vector_length_); +// boost::math::exponential_distribution mydist(lambda); +// float threshold = static_cast(quantile(mydist, val)); +// +// return threshold; +//} + + +void GalileoE1PcpsAmbiguousAcquisitionFpga::connect(gr::top_block_sptr top_block) +{ + // printf("top acq connect\n"); + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } + + // nothing to connect +} + + +void GalileoE1PcpsAmbiguousAcquisitionFpga::disconnect(gr::top_block_sptr top_block) +{ + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // // Since a byte-based acq implementation is not available, + // // we just convert cshorts to gr_complex + // top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } + + // nothing to disconnect + // printf("top acq disconnect\n"); +} + + +gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_left_block() +{ + // printf("top acq get left block start\n"); + // if (item_type_.compare("gr_complex") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cshort") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // return cbyte_to_float_x2_; + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + return nullptr; + // } + // printf("top acq get left block end\n"); +} + + +gr::basic_block_sptr GalileoE1PcpsAmbiguousAcquisitionFpga::get_right_block() +{ + // printf("top acq get right block start\n"); + return acquisition_fpga_; + // printf("top acq get right block end\n"); +} diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h new file mode 100644 index 000000000..ebb326337 --- /dev/null +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h @@ -0,0 +1,180 @@ +/*! + * \file galileo_e1_pcps_ambiguous_acquisition.h + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Galileo E1 Signals + * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ +#define GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ + +#include "acquisition_interface.h" +#include "gnss_synchro.h" +#include "pcps_acquisition_fpga.h" +#include "complex_byte_to_float_x2.h" +#include +#include +#include +#include + + +class ConfigurationInterface; + +/*! + * \brief This class adapts a PCPS acquisition block to an + * AcquisitionInterface for Galileo E1 Signals + */ +class GalileoE1PcpsAmbiguousAcquisitionFpga : public AcquisitionInterface +{ +public: + GalileoE1PcpsAmbiguousAcquisitionFpga(ConfigurationInterface* configuration, + std::string role, unsigned int in_streams, + unsigned int out_streams); + + virtual ~GalileoE1PcpsAmbiguousAcquisitionFpga(); + + inline std::string role() override + { + // printf("top acq role\n"); + return role_; + } + + /*! + * \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition" + */ + inline std::string implementation() override + { + // printf("top acq implementation\n"); + return "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga"; + } + + size_t item_size() override + { + // printf("top acq item size\n"); + size_t item_size = sizeof(lv_16sc_t); + 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; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and + * tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + /*! + * \brief Set acquisition channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set statistics threshold of PCPS algorithm + */ + void set_threshold(float threshold) override; + + /*! + * \brief Set maximum Doppler off grid search + */ + void set_doppler_max(unsigned int doppler_max) override; + + /*! + * \brief Set Doppler steps for the grid search + */ + void set_doppler_step(unsigned int doppler_step) override; + + /*! + * \brief Initializes acquisition algorithm. + */ + void init() override; + + /*! + * \brief Sets local code for Galileo E1 PCPS acquisition algorithm. + */ + void set_local_code() override; + + /*! + * \brief Returns the maximum peak of grid search + */ + signed int mag() override; + + /*! + * \brief Restart acquisition algorithm + */ + void reset() override; + + /*! + * \brief If state = 1, it forces the block to start acquiring from the first sample + */ + void set_state(int state) override; + + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + +private: + ConfigurationInterface* configuration_; + //pcps_acquisition_sptr acquisition_; + pcps_acquisition_fpga_sptr acquisition_fpga_; + gr::blocks::stream_to_vector::sptr stream_to_vector_; + gr::blocks::float_to_complex::sptr float_to_complex_; + complex_byte_to_float_x2_sptr cbyte_to_float_x2_; + // size_t item_size_; + // std::string item_type_; + //unsigned int vector_length_; + //unsigned int code_length_; + bool bit_transition_flag_; + bool use_CFAR_algorithm_flag_; + bool acquire_pilot_; + unsigned int channel_; + //float threshold_; + unsigned int doppler_max_; + unsigned int doppler_step_; + //unsigned int sampled_ms_; + unsigned int max_dwells_; + //long fs_in_; + //long if_; + bool dump_; + bool blocking_; + std::string dump_filename_; + //std::complex* code_; + Gnss_Synchro* gnss_synchro_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + //float calculate_threshold(float pfa); + + // extra for the FPGA + lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts +}; + +#endif /* GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ */ diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc index 625c92396..46a3b1974 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc @@ -40,6 +40,10 @@ using google::LogMessage; +void GalileoE1PcpsCccwsrAmbiguousAcquisition::stop_acquisition() +{ +} + GalileoE1PcpsCccwsrAmbiguousAcquisition::GalileoE1PcpsCccwsrAmbiguousAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h index 54b5ee54e..47c19becb 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h @@ -125,6 +125,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_cccwsr_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc index 34c56ddf9..36ed925df 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc @@ -40,6 +40,10 @@ using google::LogMessage; +void GalileoE1PcpsQuickSyncAmbiguousAcquisition::stop_acquisition() +{ +} + GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h index 5bfa06ca2..1d7b25880 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h @@ -129,6 +129,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_quicksync_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc index 2e5bd5684..4d7038364 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc @@ -40,6 +40,10 @@ using google::LogMessage; +void GalileoE1PcpsTongAmbiguousAcquisition::stop_acquisition() +{ +} + GalileoE1PcpsTongAmbiguousAcquisition::GalileoE1PcpsTongAmbiguousAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h index a47a22329..8524fc8d1 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h @@ -128,6 +128,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_tong_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc index 78d95d36e..e24970d63 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc @@ -46,6 +46,10 @@ using google::LogMessage; +void GalileoE5aNoncoherentIQAcquisitionCaf::stop_acquisition() +{ +} + GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h index 823bdc1ff..6beed3472 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h @@ -131,6 +131,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc index 85aaee1d3..2bd081e3e 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc @@ -42,13 +42,17 @@ using google::LogMessage; +void GalileoE5aPcpsAcquisition::stop_acquisition() +{ +} + GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "../data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; DLOG(INFO) << "Role " << role; @@ -57,6 +61,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil((1.0 / Galileo_E5a_CODE_CHIP_RATE_HZ) * static_cast(acq_parameters.fs_in))); acq_pilot_ = configuration_->property(role + ".acquire_pilot", false); acq_iq_ = configuration_->property(role + ".acquire_iq", false); if (acq_iq_) @@ -100,16 +105,16 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con LOG(WARNING) << item_type_ << " unknown acquisition item type"; } acq_parameters.it_size = item_size_; - acq_parameters.samples_per_code = code_length_; - acq_parameters.samples_per_ms = code_length_; + acq_parameters.samples_per_ms = static_cast(fs_in_) * 0.001; acq_parameters.sampled_ms = sampled_ms_; + acq_parameters.ms_per_code = 1; + acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast(GALILEO_E5a_CODE_PERIOD_MS); acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acquisition_ = pcps_make_acquisition(acq_parameters); - stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); channel_ = 0; threshold_ = 0.0; doppler_step_ = 0; @@ -257,15 +262,15 @@ void GalileoE5aPcpsAcquisition::set_state(int state) } -void GalileoE5aPcpsAcquisition::connect(gr::top_block_sptr top_block) +void GalileoE5aPcpsAcquisition::connect(gr::top_block_sptr top_block __attribute__((unused))) { if (item_type_.compare("gr_complex") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cshort") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else { @@ -274,15 +279,15 @@ void GalileoE5aPcpsAcquisition::connect(gr::top_block_sptr top_block) } -void GalileoE5aPcpsAcquisition::disconnect(gr::top_block_sptr top_block) +void GalileoE5aPcpsAcquisition::disconnect(gr::top_block_sptr top_block __attribute__((unused))) { if (item_type_.compare("gr_complex") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cshort") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else { @@ -293,7 +298,7 @@ void GalileoE5aPcpsAcquisition::disconnect(gr::top_block_sptr top_block) gr::basic_block_sptr GalileoE5aPcpsAcquisition::get_left_block() { - return stream_to_vector_; + return acquisition_; } diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h index ebea0a5e6..49099cd42 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.h @@ -35,7 +35,6 @@ #include "acquisition_interface.h" #include "gnss_synchro.h" #include "pcps_acquisition.h" -#include #include class ConfigurationInterface; @@ -123,13 +122,17 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: float calculate_threshold(float pfa); ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; - gr::blocks::stream_to_vector::sptr stream_to_vector_; size_t item_size_; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc new file mode 100644 index 000000000..30f2195b9 --- /dev/null +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc @@ -0,0 +1,405 @@ +/*! + * \file galileo_e5a_pcps_acquisition.cc + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Galileo E5a data and pilot Signals + * \author Antonio Ramos, 2018. antonio.ramos(at)cttc.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "galileo_e5a_pcps_acquisition_fpga.h" +#include "configuration_interface.h" +#include "galileo_e5_signal_processing.h" +#include "Galileo_E5a.h" +#include "gnss_sdr_flags.h" +#include +#include +#include +#include + + +using google::LogMessage; + +void GalileoE5aPcpsAcquisitionFpga::stop_acquisition() +{ +} + +GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterface* configuration, + std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + //printf("creating the E5A acquisition"); + pcpsconf_fpga_t acq_parameters; + configuration_ = configuration; + std::string default_item_type = "gr_complex"; + std::string default_dump_filename = "./acquisition.mat"; + + DLOG(INFO) << "Role " << role; + + //item_type_ = configuration_->property(role + ".item_type", default_item_type); + + long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000); + long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + acq_parameters.fs_in = fs_in; + //acq_parameters.freq = 0; + + + //dump_ = configuration_->property(role + ".dump", false); + //acq_parameters.dump = dump_; + doppler_max_ = configuration_->property(role + ".doppler_max", 5000); + if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; + acq_parameters.doppler_max = doppler_max_; + unsigned int sampled_ms = 1; + //max_dwells_ = configuration_->property(role + ".max_dwells", 1); + //acq_parameters.max_dwells = max_dwells_; + //dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); + //acq_parameters.dump_filename = dump_filename_; + //bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); + //acq_parameters.bit_transition_flag = bit_transition_flag_; + //use_CFAR_ = configuration_->property(role + ".use_CFAR_algorithm", false); + //acq_parameters.use_CFAR_algorithm_flag = use_CFAR_; + //blocking_ = configuration_->property(role + ".blocking", true); + //acq_parameters.blocking = blocking_; + //--- Find number of samples per spreading code (1ms)------------------------- + + acq_pilot_ = configuration_->property(role + ".acquire_pilot", false); + acq_iq_ = configuration_->property(role + ".acquire_iq", false); + if (acq_iq_) + { + acq_pilot_ = false; + } + + unsigned int code_length = static_cast(std::round(static_cast(fs_in) / Galileo_E5a_CODE_CHIP_RATE_HZ * static_cast(Galileo_E5a_CODE_LENGTH_CHIPS))); + acq_parameters.code_length = code_length; + // The FPGA can only use FFT lengths that are a power of two. + float nbits = ceilf(log2f((float)code_length)); + unsigned int nsamples_total = pow(2, nbits); + unsigned int vector_length = nsamples_total; + unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1); + //printf("select_queue_Fpga = %d\n", select_queue_Fpga); + acq_parameters.select_queue_Fpga = select_queue_Fpga; + std::string default_device_name = "/dev/uio0"; + std::string device_name = configuration_->property(role + ".devicename", default_device_name); + acq_parameters.device_name = device_name; + acq_parameters.samples_per_ms = nsamples_total / sampled_ms; + acq_parameters.samples_per_code = nsamples_total; + + //vector_length_ = code_length_ * sampled_ms_; + + // compute all the GALILEO E5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time + // a channel is assigned) + gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT + std::complex* code = new std::complex[nsamples_total]; // buffer for the local code + gr_complex* fft_codes_padded = static_cast(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_all_fft_codes_ = new lv_16sc_t[nsamples_total * Galileo_E5a_NUMBER_OF_CODES]; // memory containing all the possible fft codes for PRN 0 to 32 + float max; // temporary maxima search + + //printf("creating the E5A acquisition CONT"); + //printf("nsamples_total = %d\n", nsamples_total); + + for (unsigned int PRN = 1; PRN <= Galileo_E5a_NUMBER_OF_CODES; PRN++) + { + // gr_complex* code = new gr_complex[code_length_]; + char signal_[3]; + + if (acq_iq_) + { + strcpy(signal_, "5X"); + } + else if (acq_pilot_) + { + strcpy(signal_, "5Q"); + } + else + { + strcpy(signal_, "5I"); + } + + + galileo_e5_a_code_gen_complex_sampled(code, signal_, PRN, fs_in, 0); + + // fill in zero padding + for (int s = code_length; s < nsamples_total; s++) + { + code[s] = std::complex(static_cast(0, 0)); + //code[s] = 0; + } + + memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values + + max = 0; // initialize maximum value + for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima + { + if (std::abs(fft_codes_padded[i].real()) > max) + { + max = std::abs(fft_codes_padded[i].real()); + } + if (std::abs(fft_codes_padded[i].imag()) > max) + { + max = std::abs(fft_codes_padded[i].imag()); + } + } + for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs + { + d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), + static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); + } + } + + + acq_parameters.all_fft_codes = d_all_fft_codes_; + + // temporary buffers that we can delete + delete[] code; + delete fft_if; + delete[] fft_codes_padded; + + //code_ = new gr_complex[vector_length_]; + + // if (item_type_.compare("gr_complex") == 0) + // { + // item_size_ = sizeof(gr_complex); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // item_size_ = sizeof(lv_16sc_t); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } + //acq_parameters.it_size = item_size_; + //acq_parameters.samples_per_code = code_length_; + //acq_parameters.samples_per_ms = code_length_; + //acq_parameters.sampled_ms = sampled_ms_; + //acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); + //acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); + //acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); + //acquisition_ = pcps_make_acquisition(acq_parameters); + //acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); + //DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; + + acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); + DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; + + //stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); + channel_ = 0; + //threshold_ = 0.0; + doppler_step_ = 0; + gnss_synchro_ = 0; + //printf("creating the E5A acquisition end"); +} + + +GalileoE5aPcpsAcquisitionFpga::~GalileoE5aPcpsAcquisitionFpga() +{ + //delete[] code_; + delete[] d_all_fft_codes_; +} + + +void GalileoE5aPcpsAcquisitionFpga::set_channel(unsigned int channel) +{ + channel_ = channel; + //acquisition_->set_channel(channel_); + acquisition_fpga_->set_channel(channel_); +} + + +void GalileoE5aPcpsAcquisitionFpga::set_threshold(float threshold) +{ + // float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); + // + // if (pfa == 0.0) + // { + // pfa = configuration_->property(role_ + ".pfa", 0.0); + // } + // + // if (pfa == 0.0) + // { + // threshold_ = threshold; + // } + // + // else + // { + // threshold_ = calculate_threshold(pfa); + // } + + DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; + + //acquisition_->set_threshold(threshold_); + acquisition_fpga_->set_threshold(threshold); +} + + +void GalileoE5aPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) +{ + doppler_max_ = doppler_max; + //acquisition_->set_doppler_max(doppler_max_); + acquisition_fpga_->set_doppler_max(doppler_max_); +} + + +void GalileoE5aPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) +{ + doppler_step_ = doppler_step; + //acquisition_->set_doppler_step(doppler_step_); + acquisition_fpga_->set_doppler_step(doppler_step_); +} + + +void GalileoE5aPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) +{ + gnss_synchro_ = gnss_synchro; + //acquisition_->set_gnss_synchro(gnss_synchro_); + acquisition_fpga_->set_gnss_synchro(gnss_synchro_); +} + + +signed int GalileoE5aPcpsAcquisitionFpga::mag() +{ + //return acquisition_->mag(); + return acquisition_fpga_->mag(); +} + + +void GalileoE5aPcpsAcquisitionFpga::init() +{ + //acquisition_->init(); + acquisition_fpga_->init(); +} + + +void GalileoE5aPcpsAcquisitionFpga::set_local_code() +{ + // gr_complex* code = new gr_complex[code_length_]; + // char signal_[3]; + // + // if (acq_iq_) + // { + // strcpy(signal_, "5X"); + // } + // else if (acq_pilot_) + // { + // strcpy(signal_, "5Q"); + // } + // else + // { + // strcpy(signal_, "5I"); + // } + // + // galileo_e5_a_code_gen_complex_sampled(code, signal_, gnss_synchro_->PRN, fs_in_, 0); + // + // for (unsigned int i = 0; i < sampled_ms_; i++) + // { + // memcpy(code_ + (i * code_length_), code, sizeof(gr_complex) * code_length_); + // } + + //acquisition_->set_local_code(code_); + acquisition_fpga_->set_local_code(); + // delete[] code; +} + + +void GalileoE5aPcpsAcquisitionFpga::reset() +{ + //acquisition_->set_active(true); + acquisition_fpga_->set_active(true); +} + + +//float GalileoE5aPcpsAcquisitionFpga::calculate_threshold(float pfa) +//{ +// unsigned int frequency_bins = 0; +// for (int doppler = static_cast(-doppler_max_); doppler <= static_cast(doppler_max_); doppler += doppler_step_) +// { +// frequency_bins++; +// } +// DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa; +// unsigned int ncells = vector_length_ * frequency_bins; +// double exponent = 1 / static_cast(ncells); +// double val = pow(1.0 - pfa, exponent); +// double lambda = double(vector_length_); +// boost::math::exponential_distribution mydist(lambda); +// float threshold = static_cast(quantile(mydist, val)); +// +// return threshold; +//} + + +void GalileoE5aPcpsAcquisitionFpga::set_state(int state) +{ + //acquisition_->set_state(state); + acquisition_fpga_->set_state(state); +} + + +void GalileoE5aPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) +{ + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } +} + + +void GalileoE5aPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) +{ + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } +} + + +gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_left_block() +{ + //return stream_to_vector_; + return nullptr; +} + + +gr::basic_block_sptr GalileoE5aPcpsAcquisitionFpga::get_right_block() +{ + //return acquisition_; + return acquisition_fpga_; +} diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h new file mode 100644 index 000000000..94b768438 --- /dev/null +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h @@ -0,0 +1,180 @@ +/*! + * \file galileo_e5a_pcps_acquisition.h + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Galileo E5a data and pilot Signals + * \author Antonio Ramos, 2018. antonio.ramos(at)cttc.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ +#define GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ + + +#include "acquisition_interface.h" +#include "gnss_synchro.h" +#include "pcps_acquisition_fpga.h" +#include +#include +#include + +class ConfigurationInterface; + +class GalileoE5aPcpsAcquisitionFpga : public AcquisitionInterface +{ +public: + GalileoE5aPcpsAcquisitionFpga(ConfigurationInterface* configuration, + std::string role, unsigned int in_streams, + unsigned int out_streams); + + virtual ~GalileoE5aPcpsAcquisitionFpga(); + + inline std::string role() override + { + return role_; + } + + inline std::string implementation() override + { + return "Galileo_E5a_Pcps_Acquisition_Fpga"; + } + + 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; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and + * tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + /*! + * \brief Set acquisition channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set statistics threshold of PCPS algorithm + */ + void set_threshold(float threshold) override; + + /*! + * \brief Set maximum Doppler off grid search + */ + void set_doppler_max(unsigned int doppler_max) override; + + /*! + * \brief Set Doppler steps for the grid search + */ + void set_doppler_step(unsigned int doppler_step) override; + + /*! + * \brief Initializes acquisition algorithm. + */ + void init() override; + + /*! + * \brief Sets local Galileo E5a code for PCPS acquisition algorithm. + */ + void set_local_code() override; + + /*! + * \brief Returns the maximum peak of grid search + */ + signed int mag() override; + + /*! + * \brief Restart acquisition algorithm + */ + void reset() override; + + /*! + * \brief If set to 1, ensures that acquisition starts at the + * first available sample. + * \param state - int=1 forces start of acquisition + */ + void set_state(int state) override; + + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + +private: + //float calculate_threshold(float pfa); + + ConfigurationInterface* configuration_; + + pcps_acquisition_fpga_sptr acquisition_fpga_; + gr::blocks::stream_to_vector::sptr stream_to_vector_; + + size_t item_size_; + + std::string item_type_; + std::string dump_filename_; + std::string role_; + + bool bit_transition_flag_; + bool dump_; + bool acq_pilot_; + bool use_CFAR_; + bool blocking_; + bool acq_iq_; + + unsigned int vector_length_; + unsigned int code_length_; + unsigned int channel_; + unsigned int doppler_max_; + unsigned int doppler_step_; + unsigned int sampled_ms_; + unsigned int max_dwells_; + unsigned int in_streams_; + unsigned int out_streams_; + + long fs_in_; + + + float threshold_; + + /* + std::complex* codeI_; + std::complex* codeQ_; + */ + + gr_complex* code_; + + Gnss_Synchro* gnss_synchro_; + + // extra for the FPGA + lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts +}; +#endif /* GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ */ diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc index b654881d7..5b3d1c531 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc @@ -43,6 +43,10 @@ using google::LogMessage; +void GlonassL1CaPcpsAcquisition::stop_acquisition() +{ +} + GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -59,6 +63,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil(GLONASS_L1_CA_CHIP_PERIOD * static_cast(acq_parameters.fs_in))); dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); @@ -99,8 +104,9 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( } acq_parameters.it_size = item_size_; acq_parameters.sampled_ms = sampled_ms_; - acq_parameters.samples_per_ms = code_length_; - acq_parameters.samples_per_code = code_length_; + acq_parameters.samples_per_ms = static_cast(fs_in_) * 0.001; + acq_parameters.ms_per_code = 1; + acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast(GLONASS_L1_CA_CODE_PERIOD * 1000.0); acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); @@ -108,9 +114,6 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); - DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; - if (item_type_.compare("cbyte") == 0) { cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); @@ -260,18 +263,17 @@ void GlonassL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cshort") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cbyte") == 0) { top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + top_block->connect(float_to_complex_, 0, acquisition_, 0); } else { @@ -284,11 +286,11 @@ void GlonassL1CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cshort") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cbyte") == 0) { @@ -296,8 +298,7 @@ void GlonassL1CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block) // we just convert cshorts to gr_complex top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + top_block->disconnect(float_to_complex_, 0, acquisition_, 0); } else { @@ -310,11 +311,11 @@ gr::basic_block_sptr GlonassL1CaPcpsAcquisition::get_left_block() { if (item_type_.compare("gr_complex") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cshort") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cbyte") == 0) { diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h index 8a956e045..1b519f91e 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h @@ -38,7 +38,6 @@ #include "gnss_synchro.h" #include "pcps_acquisition.h" #include "complex_byte_to_float_x2.h" -#include #include #include @@ -132,10 +131,14 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; - gr::blocks::stream_to_vector::sptr stream_to_vector_; gr::blocks::float_to_complex::sptr float_to_complex_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_; size_t item_size_; diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc index 1f5d251fb..06ef7aae6 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc @@ -42,6 +42,10 @@ using google::LogMessage; +void GlonassL2CaPcpsAcquisition::stop_acquisition() +{ +} + GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -58,6 +62,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil(GLONASS_L2_CA_CHIP_PERIOD * static_cast(acq_parameters.fs_in))); dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); @@ -98,8 +103,9 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( } acq_parameters.it_size = item_size_; acq_parameters.sampled_ms = sampled_ms_; - acq_parameters.samples_per_ms = code_length_; - acq_parameters.samples_per_code = code_length_; + acq_parameters.samples_per_ms = static_cast(fs_in_) * 0.001; + acq_parameters.ms_per_code = 1; + acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast(GLONASS_L2_CA_CODE_PERIOD * 1000.0); acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); @@ -107,9 +113,6 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); - DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; - if (item_type_.compare("cbyte") == 0) { cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); @@ -259,18 +262,19 @@ void GlonassL2CaPcpsAcquisition::connect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cshort") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cbyte") == 0) { + // Since a byte-based acq implementation is not available, + // we just convert cshorts to gr_complex top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + top_block->connect(float_to_complex_, 0, acquisition_, 0); } else { @@ -283,20 +287,17 @@ void GlonassL2CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cshort") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cbyte") == 0) { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + top_block->disconnect(float_to_complex_, 0, acquisition_, 0); } else { @@ -309,11 +310,11 @@ gr::basic_block_sptr GlonassL2CaPcpsAcquisition::get_left_block() { if (item_type_.compare("gr_complex") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cshort") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cbyte") == 0) { diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h index 73162f6f3..b679f4c26 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h @@ -37,7 +37,6 @@ #include "gnss_synchro.h" #include "pcps_acquisition.h" #include "complex_byte_to_float_x2.h" -#include #include #include @@ -131,10 +130,14 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; - gr::blocks::stream_to_vector::sptr stream_to_vector_; gr::blocks::float_to_complex::sptr float_to_complex_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_; size_t item_size_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc index f5602b1b6..30d7aa42d 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GpsL1CaPcpsAcquisition::stop_acquisition() +{ +} + GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -52,7 +56,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "./data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; DLOG(INFO) << "role " << role; @@ -60,6 +64,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast(acq_parameters.fs_in))); dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); @@ -70,6 +75,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( acq_parameters.doppler_max = doppler_max_; sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1); acq_parameters.sampled_ms = sampled_ms_; + acq_parameters.ms_per_code = 1; bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); acq_parameters.bit_transition_flag = bit_transition_flag_; use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions @@ -82,15 +88,11 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); //--- Find number of samples per spreading code ------------------------- - code_length_ = static_cast(std::round(static_cast(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); - - vector_length_ = code_length_ * sampled_ms_; - - if (bit_transition_flag_) - { - vector_length_ *= 2; - } + code_length_ = static_cast(std::floor(static_cast(fs_in_) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); + acq_parameters.samples_per_ms = static_cast(fs_in_) * 0.001; + acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast(GPS_L1_CA_CODE_PERIOD * 1000.0); + vector_length_ = std::floor(acq_parameters.sampled_ms * acq_parameters.samples_per_ms) * (acq_parameters.bit_transition_flag ? 2 : 1); code_ = new gr_complex[vector_length_]; if (item_type_.compare("cshort") == 0) @@ -101,16 +103,12 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( { item_size_ = sizeof(gr_complex); } - acq_parameters.samples_per_ms = code_length_; - acq_parameters.samples_per_code = code_length_; + acq_parameters.it_size = item_size_; acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); - DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; - if (item_type_.compare("cbyte") == 0) { cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); @@ -197,7 +195,6 @@ signed int GpsL1CaPcpsAcquisition::mag() void GpsL1CaPcpsAcquisition::init() { acquisition_->init(); - //set_local_code(); } @@ -254,18 +251,19 @@ void GpsL1CaPcpsAcquisition::connect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cshort") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cbyte") == 0) { + // Since a byte-based acq implementation is not available, + // we just convert cshorts to gr_complex top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + top_block->connect(float_to_complex_, 0, acquisition_, 0); } else { @@ -278,20 +276,17 @@ void GpsL1CaPcpsAcquisition::disconnect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cshort") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cbyte") == 0) { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + top_block->disconnect(float_to_complex_, 0, acquisition_, 0); } else { @@ -304,11 +299,11 @@ gr::basic_block_sptr GpsL1CaPcpsAcquisition::get_left_block() { if (item_type_.compare("gr_complex") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cshort") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cbyte") == 0) { diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h index a5ad9ef67..011bb96bf 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.h @@ -40,7 +40,6 @@ #include "gnss_synchro.h" #include "pcps_acquisition.h" #include "complex_byte_to_float_x2.h" -#include #include #include #include @@ -136,10 +135,14 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; - gr::blocks::stream_to_vector::sptr stream_to_vector_; gr::blocks::float_to_complex::sptr float_to_complex_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_; size_t item_size_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc index 44dcfc0ee..dd69ed24f 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc @@ -42,12 +42,16 @@ using google::LogMessage; +void GpsL1CaPcpsAcquisitionFineDoppler::stop_acquisition() +{ +} + GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "./data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; DLOG(INFO) << "role " << role; Acq_Conf acq_parameters = Acq_Conf(); @@ -56,6 +60,7 @@ GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler( long fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast(acq_parameters.fs_in))); dump_ = configuration->property(role + ".dump", false); acq_parameters.dump = dump_; dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h index 5fac62916..338ea683a 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h @@ -126,6 +126,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: pcps_acquisition_fine_doppler_cc_sptr acquisition_cc_; size_t item_size_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc index 8480441f7..f9778bfb8 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc @@ -11,7 +11,7 @@ * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -29,24 +29,29 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ -#include "gps_l1_ca_pcps_acquisition_fpga.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" -#include "GPS_L1_CA.h" +#include "gps_l1_ca_pcps_acquisition_fpga.h" #include "gps_sdr_signal_processing.h" +#include "GPS_L1_CA.h" #include #include #include + #define NUM_PRNs 32 using google::LogMessage; +void GpsL1CaPcpsAcquisitionFpga::stop_acquisition() +{ +} + GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -59,50 +64,66 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + //fs_in = fs_in/2.0; // downampling filter + //printf("####### DEBUG Acq: fs_in = %d\n", fs_in); acq_parameters.fs_in = fs_in; + acq_parameters.samples_per_code = static_cast(ceil(GPS_L1_CA_CHIP_PERIOD * static_cast(acq_parameters.fs_in))); doppler_max_ = configuration_->property(role + ".doppler_max", 5000); if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; acq_parameters.doppler_max = doppler_max_; unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1); acq_parameters.sampled_ms = sampled_ms; unsigned int code_length = static_cast(std::round(static_cast(fs_in) / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS))); - + acq_parameters.code_length = code_length; // The FPGA can only use FFT lengths that are a power of two. float nbits = ceilf(log2f((float)code_length)); unsigned int nsamples_total = pow(2, nbits); - unsigned int vector_length = nsamples_total * sampled_ms; + unsigned int vector_length = nsamples_total; unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0); acq_parameters.select_queue_Fpga = select_queue_Fpga; std::string default_device_name = "/dev/uio0"; std::string device_name = configuration_->property(role + ".devicename", default_device_name); acq_parameters.device_name = device_name; - acq_parameters.samples_per_ms = nsamples_total; + acq_parameters.samples_per_ms = nsamples_total / sampled_ms; acq_parameters.samples_per_code = nsamples_total; // compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time // a channel is assigned) - gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT // allocate memory to compute all the PRNs and compute all the possible codes std::complex* code = new std::complex[nsamples_total]; // buffer for the local code gr_complex* fft_codes_padded = static_cast(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32 float max; // temporary maxima search - for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) { gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code // fill in zero padding - for (unsigned int s = code_length; s < nsamples_total; s++) + for (int s = code_length; s < nsamples_total; s++) { - code[s] = 0; + code[s] = std::complex(static_cast(0, 0)); + //code[s] = 0; } int offset = 0; memcpy(fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer fft_if->execute(); // Run the FFT of local code volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values - max = 0; // initialize maximum value - for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima + + + // // debug + // char filename[25]; + // FILE *fid; + // sprintf(filename,"fft_gps_prn%d.txt", PRN); + // fid = fopen(filename, "w"); + // for (unsigned int kk=0;kk< nsamples_total; kk++) + // { + // fprintf(fid, "%f\n", fft_codes_padded[kk].real()); + // fprintf(fid, "%f\n", fft_codes_padded[kk].imag()); + // } + // fclose(fid); + + max = 0; // initialize maximum value + for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima { if (std::abs(fft_codes_padded[i].real()) > max) { @@ -115,12 +136,31 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( } for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs { - d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), - static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); + //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), + // static_cast(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); + //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(16*floor(fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)), + // static_cast(16*floor(fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max))); + //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), + // static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); + d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), + static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); } + + + //// // debug + // char filename2[25]; + // FILE *fid2; + // sprintf(filename2,"fft_gps_prn%d_norm_new.txt", PRN); + // fid2 = fopen(filename2, "w"); + // for (unsigned int kk=0;kk< nsamples_total; kk++) + // { + // fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].real()); + // fprintf(fid2, "%d\n", d_all_fft_codes_[kk + nsamples_total * (PRN - 1)].imag()); + // } + // fclose(fid2); } - // acq_parameters + //acq_parameters acq_parameters.all_fft_codes = d_all_fft_codes_; // temporary buffers that we can delete @@ -134,14 +174,6 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( channel_ = 0; doppler_step_ = 0; gnss_synchro_ = 0; - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } @@ -160,6 +192,8 @@ void GpsL1CaPcpsAcquisitionFpga::set_channel(unsigned int channel) void GpsL1CaPcpsAcquisitionFpga::set_threshold(float threshold) { + // the .pfa parameter and the threshold calculation is only used for the CFAR algorithm. + // We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such. DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; acquisition_fpga_->set_threshold(threshold); } @@ -215,26 +249,21 @@ void GpsL1CaPcpsAcquisitionFpga::set_state(int state) acquisition_fpga_->set_state(state); } - void GpsL1CaPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) { - if (top_block) - { // nothing to disconnect - } + // nothing to connect } void GpsL1CaPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) { - if (top_block) - { // nothing to disconnect - } + // nothing to disconnect } gr::basic_block_sptr GpsL1CaPcpsAcquisitionFpga::get_left_block() { - return acquisition_fpga_; + return nullptr; } diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h index 9fac921d1..8f6d1f3ff 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h @@ -68,7 +68,7 @@ public: */ inline std::string implementation() override { - return "GPS_L1_CA_PCPS_Acquisition"; + return "GPS_L1_CA_PCPS_Acquisition_Fpga"; } inline size_t item_size() override @@ -134,6 +134,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_fpga_sptr acquisition_fpga_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc index 528a9a3f2..da1377ac2 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc @@ -42,6 +42,10 @@ using google::LogMessage; +void GpsL1CaPcpsAssistedAcquisition::stop_acquisition() +{ +} + GpsL1CaPcpsAssistedAcquisition::GpsL1CaPcpsAssistedAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h index 83218aac4..ca650bc77 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h @@ -122,6 +122,11 @@ public: void reset() override; void set_state(int state __attribute__((unused))) override{}; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: pcps_assisted_acquisition_cc_sptr acquisition_cc_; size_t item_size_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc index 7c5b84f63..1037a1778 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc @@ -40,6 +40,10 @@ using google::LogMessage; +void GpsL1CaPcpsOpenClAcquisition::stop_acquisition() +{ +} + GpsL1CaPcpsOpenClAcquisition::GpsL1CaPcpsOpenClAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h index 7d3e7b58e..0c6c21f49 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h @@ -124,6 +124,11 @@ public: void reset() override; void set_state(int state __attribute__((unused))) override{}; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_opencl_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc index b25be59e0..888d44586 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc @@ -41,6 +41,10 @@ using google::LogMessage; +void GpsL1CaPcpsQuickSyncAcquisition::stop_acquisition() +{ +} + GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h index f38ee7055..c35f97370 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h @@ -130,6 +130,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_quicksync_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc index e676d5d9c..5c55d802a 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc @@ -40,6 +40,10 @@ using google::LogMessage; +void GpsL1CaPcpsTongAcquisition::stop_acquisition() +{ +} + GpsL1CaPcpsTongAcquisition::GpsL1CaPcpsTongAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h index b09f6cde0..562d63e39 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h @@ -129,6 +129,11 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_tong_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc index 2fbb72252..32b426777 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc @@ -43,6 +43,10 @@ using google::LogMessage; +void GpsL2MPcpsAcquisition::stop_acquisition() +{ +} + GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -50,7 +54,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "./data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; LOG(INFO) << "role " << role; @@ -60,6 +64,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil((1.0 / GPS_L2_M_CODE_RATE_HZ) * static_cast(acq_parameters.fs_in))); dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); @@ -77,15 +82,19 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); acq_parameters.dump_filename = dump_filename_; //--- Find number of samples per spreading code ------------------------- - code_length_ = std::round(static_cast(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast(GPS_L2_M_CODE_LENGTH_CHIPS))); - - vector_length_ = code_length_; - - if (bit_transition_flag_) + acq_parameters.samples_per_ms = static_cast(fs_in_) * 0.001; + acq_parameters.ms_per_code = 20; + acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", acq_parameters.ms_per_code); + if ((acq_parameters.sampled_ms % acq_parameters.ms_per_code) != 0) { - vector_length_ *= 2; + LOG(WARNING) << "Parameter coherent_integration_time_ms should be a multiple of 20. Setting it to 20"; + acq_parameters.sampled_ms = acq_parameters.ms_per_code; } + code_length_ = acq_parameters.ms_per_code * acq_parameters.samples_per_ms; + + vector_length_ = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1); + code_ = new gr_complex[vector_length_]; if (item_type_.compare("cshort") == 0) @@ -96,20 +105,17 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( { item_size_ = sizeof(gr_complex); } - acq_parameters.samples_per_ms = static_cast(std::round(static_cast(fs_in_) * 0.001)); - acq_parameters.samples_per_code = code_length_; + + acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast(GPS_L2_M_PERIOD * 1000.0); acq_parameters.it_size = item_size_; - acq_parameters.sampled_ms = 20; + acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); - acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", true); + acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); acq_parameters.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false); acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); - DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; - if (item_type_.compare("cbyte") == 0) { cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); @@ -120,6 +126,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( threshold_ = 0.0; doppler_step_ = 0; gnss_synchro_ = 0; + num_codes_ = acq_parameters.sampled_ms / acq_parameters.ms_per_code; if (in_streams_ > 1) { LOG(ERROR) << "This implementation only supports one input stream"; @@ -208,9 +215,18 @@ void GpsL2MPcpsAcquisition::init() void GpsL2MPcpsAcquisition::set_local_code() { - gps_l2c_m_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_); + std::complex* code = new std::complex[code_length_]; + + gps_l2c_m_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_); + + for (unsigned int i = 0; i < num_codes_; i++) + { + memcpy(&(code_[i * code_length_]), code, + sizeof(gr_complex) * code_length_); + } acquisition_->set_local_code(code_); + delete[] code; } @@ -249,18 +265,19 @@ void GpsL2MPcpsAcquisition::connect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cshort") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cbyte") == 0) { + // Since a byte-based acq implementation is not available, + // we just convert cshorts to gr_complex top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + top_block->connect(float_to_complex_, 0, acquisition_, 0); } else { @@ -273,20 +290,17 @@ void GpsL2MPcpsAcquisition::disconnect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cshort") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cbyte") == 0) { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + top_block->disconnect(float_to_complex_, 0, acquisition_, 0); } else { @@ -299,11 +313,11 @@ gr::basic_block_sptr GpsL2MPcpsAcquisition::get_left_block() { if (item_type_.compare("gr_complex") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cshort") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cbyte") == 0) { diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h index ec4257aee..27c463cf3 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.h @@ -38,7 +38,6 @@ #include "gnss_synchro.h" #include "pcps_acquisition.h" #include "complex_byte_to_float_x2.h" -#include #include #include #include @@ -134,10 +133,14 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; - gr::blocks::stream_to_vector::sptr stream_to_vector_; gr::blocks::float_to_complex::sptr float_to_complex_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_; size_t item_size_; @@ -160,6 +163,7 @@ private: std::string role_; unsigned int in_streams_; unsigned int out_streams_; + unsigned int num_codes_; float calculate_threshold(float pfa); }; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc new file mode 100644 index 000000000..db53d3815 --- /dev/null +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc @@ -0,0 +1,398 @@ +/*! + * \file gps_l2_m_pcps_acquisition.cc + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * GPS L2 M signals + * \authors
    + *
  • Javier Arribas, 2015. jarribas(at)cttc.es + *
+ * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "gps_l2_m_pcps_acquisition_fpga.h" +#include "configuration_interface.h" +#include "gps_l2c_signal.h" +#include "GPS_L2C.h" +#include "gnss_sdr_flags.h" +#include +#include + +#define NUM_PRNs 32 + +using google::LogMessage; + +void GpsL2MPcpsAcquisitionFpga::stop_acquisition() +{ +} + +GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( + ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + //pcpsconf_t acq_parameters; + pcpsconf_fpga_t acq_parameters; + configuration_ = configuration; + std::string default_item_type = "gr_complex"; + std::string default_dump_filename = "./acquisition.mat"; + + LOG(INFO) << "role " << role; + + item_type_ = configuration_->property(role + ".item_type", default_item_type); + //float pfa = configuration_->property(role + ".pfa", 0.0); + + long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); + fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + acq_parameters.fs_in = fs_in_; + //if_ = configuration_->property(role + ".if", 0); + //acq_parameters.freq = if_; + //dump_ = configuration_->property(role + ".dump", false); + //acq_parameters.dump = dump_; + //blocking_ = configuration_->property(role + ".blocking", true); + //acq_parameters.blocking = blocking_; + doppler_max_ = configuration->property(role + ".doppler_max", 5000); + if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; + acq_parameters.doppler_max = doppler_max_; + //bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); + //acq_parameters.bit_transition_flag = bit_transition_flag_; + //use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions + //acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; + //max_dwells_ = configuration_->property(role + ".max_dwells", 1); + //acq_parameters.max_dwells = max_dwells_; + //dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); + //acq_parameters.dump_filename = dump_filename_; + //--- Find number of samples per spreading code ------------------------- + //code_length_ = std::round(static_cast(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast(GPS_L2_M_CODE_LENGTH_CHIPS))); + + acq_parameters.sampled_ms = 20; + unsigned code_length = std::round(static_cast(fs_in_) / (GPS_L2_M_CODE_RATE_HZ / static_cast(GPS_L2_M_CODE_LENGTH_CHIPS))); + acq_parameters.code_length = code_length; + // The FPGA can only use FFT lengths that are a power of two. + float nbits = ceilf(log2f((float)code_length)); + unsigned int nsamples_total = pow(2, nbits); + unsigned int vector_length = nsamples_total; + unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 0); + acq_parameters.select_queue_Fpga = select_queue_Fpga; + std::string default_device_name = "/dev/uio0"; + std::string device_name = configuration_->property(role + ".devicename", default_device_name); + acq_parameters.device_name = device_name; + acq_parameters.samples_per_ms = nsamples_total / acq_parameters.sampled_ms; + //acq_parameters.samples_per_ms = static_cast(std::round(static_cast(fs_in_) * 0.001)); + acq_parameters.samples_per_code = nsamples_total; + + // compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time + // a channel is assigned) + gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT + // allocate memory to compute all the PRNs and compute all the possible codes + std::complex* code = new std::complex[nsamples_total]; // buffer for the local code + gr_complex* fft_codes_padded = static_cast(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32 + float max; // temporary maxima search + for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) + { + gps_l2c_m_code_gen_complex_sampled(code, PRN, fs_in_); + // fill in zero padding + for (int s = code_length; s < nsamples_total; s++) + { + code[s] = std::complex(static_cast(0, 0)); + //code[s] = 0; + } + memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values + max = 0; // initialize maximum value + for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima + { + if (std::abs(fft_codes_padded[i].real()) > max) + { + max = std::abs(fft_codes_padded[i].real()); + } + if (std::abs(fft_codes_padded[i].imag()) > max) + { + max = std::abs(fft_codes_padded[i].imag()); + } + } + for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs + { + d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), + static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); + } + } + + //acq_parameters + acq_parameters.all_fft_codes = d_all_fft_codes_; + + // temporary buffers that we can delete + delete[] code; + delete fft_if; + delete[] fft_codes_padded; + + acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); + DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; + + channel_ = 0; + doppler_step_ = 0; + gnss_synchro_ = 0; + + + // vector_length_ = code_length_; + // + // if (bit_transition_flag_) + // { + // vector_length_ *= 2; + // } + + // code_ = new gr_complex[vector_length_]; + // + // if (item_type_.compare("cshort") == 0) + // { + // item_size_ = sizeof(lv_16sc_t); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // } + //acq_parameters.samples_per_ms = static_cast(std::round(static_cast(fs_in_) * 0.001)); + //acq_parameters.samples_per_code = code_length_; + //acq_parameters.it_size = item_size_; + //acq_parameters.sampled_ms = 20; + //acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); + //acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); + //acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", true); + //acquisition_ = pcps_make_acquisition(acq_parameters); + DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; + + // stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); + // DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; + // + // if (item_type_.compare("cbyte") == 0) + // { + // cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); + // float_to_complex_ = gr::blocks::float_to_complex::make(); + // } + + // channel_ = 0; + threshold_ = 0.0; + // doppler_step_ = 0; + // gnss_synchro_ = 0; +} + + +GpsL2MPcpsAcquisitionFpga::~GpsL2MPcpsAcquisitionFpga() +{ + //delete[] code_; + delete[] d_all_fft_codes_; +} + + +void GpsL2MPcpsAcquisitionFpga::set_channel(unsigned int channel) +{ + channel_ = channel; + acquisition_fpga_->set_channel(channel_); +} + + +void GpsL2MPcpsAcquisitionFpga::set_threshold(float threshold) +{ + // float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); + // + // if (pfa == 0.0) + // { + // pfa = configuration_->property(role_ + ".pfa", 0.0); + // } + // if (pfa == 0.0) + // { + // threshold_ = threshold; + // } + // else + // { + // threshold_ = calculate_threshold(pfa); + // } + + DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; + + acquisition_fpga_->set_threshold(threshold_); +} + + +void GpsL2MPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) +{ + doppler_max_ = doppler_max; + + acquisition_fpga_->set_doppler_max(doppler_max_); +} + + +// Be aware that Doppler step should be set to 2/(3T) Hz, where T is the coherent integration time (GPS L2 period is 0.02s) +// Doppler bin minimum size= 33 Hz +void GpsL2MPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) +{ + doppler_step_ = doppler_step; + + acquisition_fpga_->set_doppler_step(doppler_step_); +} + + +void GpsL2MPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) +{ + gnss_synchro_ = gnss_synchro; + + acquisition_fpga_->set_gnss_synchro(gnss_synchro_); +} + + +signed int GpsL2MPcpsAcquisitionFpga::mag() +{ + return acquisition_fpga_->mag(); +} + + +void GpsL2MPcpsAcquisitionFpga::init() +{ + acquisition_fpga_->init(); + //set_local_code(); +} + + +void GpsL2MPcpsAcquisitionFpga::set_local_code() +{ + //gps_l2c_m_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_); + + //acquisition_fpga_->set_local_code(code_); + acquisition_fpga_->set_local_code(); +} + + +void GpsL2MPcpsAcquisitionFpga::reset() +{ + acquisition_fpga_->set_active(true); +} + +void GpsL2MPcpsAcquisitionFpga::set_state(int state) +{ + acquisition_fpga_->set_state(state); +} + + +//float GpsL2MPcpsAcquisitionFpga::calculate_threshold(float pfa) +//{ +// //Calculate the threshold +// unsigned int frequency_bins = 0; +// for (int doppler = static_cast(-doppler_max_); doppler <= static_cast(doppler_max_); doppler += doppler_step_) +// { +// frequency_bins++; +// } +// DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa; +// unsigned int ncells = vector_length_ * frequency_bins; +// double exponent = 1.0 / static_cast(ncells); +// double val = pow(1.0 - pfa, exponent); +// double lambda = double(vector_length_); +// boost::math::exponential_distribution mydist(lambda); +// float threshold = static_cast(quantile(mydist, val)); +// +// return threshold; +//} + + +void GpsL2MPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) +{ + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } + + // nothing to connect +} + + +void GpsL2MPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) +{ + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // // Since a byte-based acq implementation is not available, + // // we just convert cshorts to gr_complex + // top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } + + // nothing to disconnect +} + + +gr::basic_block_sptr GpsL2MPcpsAcquisitionFpga::get_left_block() +{ + // if (item_type_.compare("gr_complex") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cshort") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // return cbyte_to_float_x2_; + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // return nullptr; + // } + return nullptr; +} + + +gr::basic_block_sptr GpsL2MPcpsAcquisitionFpga::get_right_block() +{ + return acquisition_fpga_; +} diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h new file mode 100644 index 000000000..b9aba8787 --- /dev/null +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h @@ -0,0 +1,176 @@ +/*! + * \file gps_l2_m_pcps_acquisition.h + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * GPS L2 M signals + * \authors
    + *
  • Javier Arribas, 2015. jarribas(at)cttc.es + *
+ * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H_ +#define GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H_ + +#include "acquisition_interface.h" +#include "gnss_synchro.h" +#include "pcps_acquisition_fpga.h" +#include "complex_byte_to_float_x2.h" +#include +#include +#include +#include + + +class ConfigurationInterface; + +/*! + * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface + * for GPS L2 M signals + */ +class GpsL2MPcpsAcquisitionFpga : public AcquisitionInterface +{ +public: + GpsL2MPcpsAcquisitionFpga(ConfigurationInterface* configuration, + std::string role, unsigned int in_streams, + unsigned int out_streams); + + virtual ~GpsL2MPcpsAcquisitionFpga(); + + inline std::string role() override + { + return role_; + } + + /*! + * \brief Returns "GPS_L2_M_PCPS_Acquisition" + */ + inline std::string implementation() override + { + return "GPS_L2_M_PCPS_Acquisition"; + } + + 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; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and + * tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + /*! + * \brief Set acquisition channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set statistics threshold of PCPS algorithm + */ + void set_threshold(float threshold) override; + + /*! + * \brief Set maximum Doppler off grid search + */ + void set_doppler_max(unsigned int doppler_max) override; + + /*! + * \brief Set Doppler steps for the grid search + */ + void set_doppler_step(unsigned int doppler_step) override; + + /*! + * \brief Initializes acquisition algorithm. + */ + void init() override; + + /*! + * \brief Sets local code for GPS L2/M PCPS acquisition algorithm. + */ + void set_local_code() override; + + /*! + * \brief Returns the maximum peak of grid search + */ + signed int mag() override; + + /*! + * \brief Restart acquisition algorithm + */ + void reset() override; + + /*! + * \brief If state = 1, it forces the block to start acquiring from the first sample + */ + void set_state(int state) override; + + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + +private: + ConfigurationInterface* configuration_; + //pcps_acquisition_sptr acquisition_; + pcps_acquisition_fpga_sptr acquisition_fpga_; + gr::blocks::stream_to_vector::sptr stream_to_vector_; + gr::blocks::float_to_complex::sptr float_to_complex_; + complex_byte_to_float_x2_sptr cbyte_to_float_x2_; + size_t item_size_; + std::string item_type_; + unsigned int vector_length_; + unsigned int code_length_; + bool bit_transition_flag_; + bool use_CFAR_algorithm_flag_; + unsigned int channel_; + float threshold_; + unsigned int doppler_max_; + unsigned int doppler_step_; + unsigned int max_dwells_; + long fs_in_; + //long if_; + bool dump_; + bool blocking_; + std::string dump_filename_; + std::complex* code_; + Gnss_Synchro* gnss_synchro_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + + lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts + + //float calculate_threshold(float pfa); +}; + +#endif /* GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H_ */ diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc index da30699fa..36d6e4f7a 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc @@ -1,5 +1,5 @@ /*! - * \file gps_l5i pcps_acquisition.cc + * \file gps_l5i_pcps_acquisition.cc * \brief Adapts a PCPS acquisition block to an Acquisition Interface for * GPS L5i signals * \authors
    @@ -43,6 +43,10 @@ using google::LogMessage; +void GpsL5iPcpsAcquisition::stop_acquisition() +{ +} + GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -50,7 +54,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( Acq_Conf acq_parameters = Acq_Conf(); configuration_ = configuration; std::string default_item_type = "gr_complex"; - std::string default_dump_filename = "./data/acquisition.dat"; + std::string default_dump_filename = "./acquisition.mat"; LOG(INFO) << "role " << role; @@ -59,6 +63,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); acq_parameters.fs_in = fs_in_; + acq_parameters.samples_per_chip = static_cast(ceil((1.0 / GPS_L5i_CODE_RATE_HZ) * static_cast(acq_parameters.fs_in))); dump_ = configuration_->property(role + ".dump", false); acq_parameters.dump = dump_; acq_parameters.dump_channel = configuration_->property(role + ".dump_channel", 0); @@ -75,16 +80,13 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( acq_parameters.max_dwells = max_dwells_; dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); acq_parameters.dump_filename = dump_filename_; + acq_parameters.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1); //--- Find number of samples per spreading code ------------------------- - code_length_ = static_cast(std::round(static_cast(fs_in_) / (GPS_L5i_CODE_RATE_HZ / static_cast(GPS_L5i_CODE_LENGTH_CHIPS)))); - - vector_length_ = code_length_; - - if (bit_transition_flag_) - { - vector_length_ *= 2; - } + code_length_ = static_cast(std::floor(static_cast(fs_in_) / (GPS_L5i_CODE_RATE_HZ / GPS_L5i_CODE_LENGTH_CHIPS))); + acq_parameters.samples_per_ms = static_cast(fs_in_) * 0.001; + acq_parameters.samples_per_code = acq_parameters.samples_per_ms * static_cast(GPS_L5i_PERIOD * 1000.0); + vector_length_ = std::floor(acq_parameters.sampled_ms * acq_parameters.samples_per_ms) * (acq_parameters.bit_transition_flag ? 2 : 1); code_ = new gr_complex[vector_length_]; if (item_type_.compare("cshort") == 0) @@ -95,10 +97,10 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( { item_size_ = sizeof(gr_complex); } - acq_parameters.samples_per_code = code_length_; - acq_parameters.samples_per_ms = code_length_; + + acq_parameters.ms_per_code = 1; acq_parameters.it_size = item_size_; - acq_parameters.sampled_ms = 1; + num_codes_ = acq_parameters.sampled_ms; acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); @@ -106,15 +108,11 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( acquisition_ = pcps_make_acquisition(acq_parameters); DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; - stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); - DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; - if (item_type_.compare("cbyte") == 0) { cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); float_to_complex_ = gr::blocks::float_to_complex::make(); } - channel_ = 0; threshold_ = 0.0; doppler_step_ = 0; @@ -205,9 +203,18 @@ void GpsL5iPcpsAcquisition::init() void GpsL5iPcpsAcquisition::set_local_code() { - gps_l5i_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_); + std::complex* code = new std::complex[code_length_]; + + gps_l5i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_); + + for (unsigned int i = 0; i < num_codes_; i++) + { + memcpy(&(code_[i * code_length_]), code, + sizeof(gr_complex) * code_length_); + } acquisition_->set_local_code(code_); + delete[] code; } @@ -246,18 +253,19 @@ void GpsL5iPcpsAcquisition::connect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cshort") == 0) { - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + // nothing to connect } else if (item_type_.compare("cbyte") == 0) { + // Since a byte-based acq implementation is not available, + // we just convert cshorts to gr_complex top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->connect(stream_to_vector_, 0, acquisition_, 0); + top_block->connect(float_to_complex_, 0, acquisition_, 0); } else { @@ -270,20 +278,17 @@ void GpsL5iPcpsAcquisition::disconnect(gr::top_block_sptr top_block) { if (item_type_.compare("gr_complex") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cshort") == 0) { - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + // nothing to disconnect } else if (item_type_.compare("cbyte") == 0) { - // Since a byte-based acq implementation is not available, - // we just convert cshorts to gr_complex top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); - top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); - top_block->disconnect(stream_to_vector_, 0, acquisition_, 0); + top_block->disconnect(float_to_complex_, 0, acquisition_, 0); } else { @@ -296,11 +301,11 @@ gr::basic_block_sptr GpsL5iPcpsAcquisition::get_left_block() { if (item_type_.compare("gr_complex") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cshort") == 0) { - return stream_to_vector_; + return acquisition_; } else if (item_type_.compare("cbyte") == 0) { diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h index 01d15def8..3c4d2ad46 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.h @@ -1,5 +1,5 @@ /*! - * \file GPS_L5i_PCPS_Acquisition.h + * \file gps_l5i_pcps_acquisition.h * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for * GPS L5i signals * \authors
      @@ -38,7 +38,6 @@ #include "gnss_synchro.h" #include "pcps_acquisition.h" #include "complex_byte_to_float_x2.h" -#include #include #include #include @@ -134,10 +133,14 @@ public: */ void set_state(int state) override; + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + private: ConfigurationInterface* configuration_; pcps_acquisition_sptr acquisition_; - gr::blocks::stream_to_vector::sptr stream_to_vector_; gr::blocks::float_to_complex::sptr float_to_complex_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_; size_t item_size_; @@ -158,6 +161,7 @@ private: std::complex* code_; Gnss_Synchro* gnss_synchro_; std::string role_; + unsigned int num_codes_; unsigned int in_streams_; unsigned int out_streams_; diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc new file mode 100644 index 000000000..124999dc9 --- /dev/null +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc @@ -0,0 +1,404 @@ +/*! + * \file gps_l5i pcps_acquisition.cc + * \brief Adapts a PCPS acquisition block to an Acquisition Interface for + * GPS L5i signals + * \authors
        + *
      • Javier Arribas, 2017. jarribas(at)cttc.es + *
      + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "gps_l5i_pcps_acquisition_fpga.h" +#include "configuration_interface.h" +#include "gps_l5_signal.h" +#include "GPS_L5.h" +#include "gnss_sdr_flags.h" +#include +#include + +#define NUM_PRNs 32 + +using google::LogMessage; + +void GpsL5iPcpsAcquisitionFpga::stop_acquisition() +{ +} + +GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( + ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + //printf("L5 ACQ CLASS CREATED\n"); + pcpsconf_fpga_t acq_parameters; + configuration_ = configuration; + std::string default_item_type = "gr_complex"; + std::string default_dump_filename = "./acquisition.mat"; + + LOG(INFO) << "role " << role; + + //item_type_ = configuration_->property(role + ".item_type", default_item_type); + + long fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); + long fs_in = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + acq_parameters.fs_in = fs_in; + //if_ = configuration_->property(role + ".if", 0); + //acq_parameters.freq = if_; + //dump_ = configuration_->property(role + ".dump", false); + //acq_parameters.dump = dump_; + //blocking_ = configuration_->property(role + ".blocking", true); + //acq_parameters.blocking = blocking_; + doppler_max_ = configuration->property(role + ".doppler_max", 5000); + if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; + acq_parameters.doppler_max = doppler_max_; + //acq_parameters.sampled_ms = 1; + unsigned int sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1); + acq_parameters.sampled_ms = sampled_ms; + + //printf("L5 ACQ CLASS MID 0\n"); + + //bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); + //acq_parameters.bit_transition_flag = bit_transition_flag_; + //use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions + //acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; + //max_dwells_ = configuration_->property(role + ".max_dwells", 1); + //acq_parameters.max_dwells = max_dwells_; + //dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); + //acq_parameters.dump_filename = dump_filename_; + //--- Find number of samples per spreading code ------------------------- + unsigned int code_length = static_cast(std::round(static_cast(fs_in) / (GPS_L5i_CODE_RATE_HZ / static_cast(GPS_L5i_CODE_LENGTH_CHIPS)))); + acq_parameters.code_length = code_length; + // The FPGA can only use FFT lengths that are a power of two. + float nbits = ceilf(log2f((float)code_length)); + unsigned int nsamples_total = pow(2, nbits); + unsigned int vector_length = nsamples_total; + unsigned int select_queue_Fpga = configuration_->property(role + ".select_queue_Fpga", 1); + acq_parameters.select_queue_Fpga = select_queue_Fpga; + std::string default_device_name = "/dev/uio0"; + std::string device_name = configuration_->property(role + ".devicename", default_device_name); + acq_parameters.device_name = device_name; + acq_parameters.samples_per_ms = nsamples_total; + acq_parameters.samples_per_code = nsamples_total; + //printf("L5 ACQ CLASS MID 01\n"); + // compute all the GPS L5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time + // a channel is assigned) + gr::fft::fft_complex* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT + //printf("L5 ACQ CLASS MID 02\n"); + std::complex* code = new gr_complex[vector_length]; + //printf("L5 ACQ CLASS MID 03\n"); + gr_complex* fft_codes_padded = static_cast(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + //printf("L5 ACQ CLASS MID 04\n"); + d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32 + + //printf("L5 ACQ CLASS MID 1 vector_length = %d\n", vector_length); + + float max; // temporary maxima search + for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) + { + //printf("L5 ACQ CLASS processing PRN = %d\n", PRN); + gps_l5i_code_gen_complex_sampled(code, PRN, fs_in); + //printf("L5 ACQ CLASS processing PRN = %d (cont) \n", PRN); + // fill in zero padding + for (int s = code_length; s < nsamples_total; s++) + { + code[s] = std::complex(static_cast(0, 0)); + //code[s] = 0; + } + memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values + + max = 0; // initialize maximum value + for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima + { + if (std::abs(fft_codes_padded[i].real()) > max) + { + max = std::abs(fft_codes_padded[i].real()); + } + if (std::abs(fft_codes_padded[i].imag()) > max) + { + max = std::abs(fft_codes_padded[i].imag()); + } + } + for (unsigned int i = 0; i < nsamples_total; i++) // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs + { + //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(256*fft_codes_padded[i].real() * (pow(2, 7) - 1) / max)), + // static_cast(floor(256*fft_codes_padded[i].imag() * (pow(2, 7) - 1) / max))); + //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(16*floor(fft_codes_padded[i].real() * (pow(2, 11) - 1) / max)), + // static_cast(16*floor(fft_codes_padded[i].imag() * (pow(2, 11) - 1) / max))); + //d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), + // static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); + d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, 15) - 1) / max)), + static_cast(floor(fft_codes_padded[i].imag() * (pow(2, 15) - 1) / max))); + } + } + + + //printf("L5 ACQ CLASS MID 2\n"); + + //acq_parameters + acq_parameters.all_fft_codes = d_all_fft_codes_; + + // temporary buffers that we can delete + delete[] code; + delete fft_if; + delete[] fft_codes_padded; + // vector_length_ = code_length_; + // + // if (bit_transition_flag_) + // { + // vector_length_ *= 2; + // } + // + // code_ = new gr_complex[vector_length_]; + // + // if (item_type_.compare("cshort") == 0) + // { + // item_size_ = sizeof(lv_16sc_t); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // } + // acq_parameters.samples_per_code = code_length_; + // acq_parameters.samples_per_ms = code_length_; + // acq_parameters.it_size = item_size_; + //acq_parameters.sampled_ms = 1; + // acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); + // acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0); + // acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false); + // acquisition_fpga_ = pcps_make_acquisition(acq_parameters); + // DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; + + acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); + DLOG(INFO) << "acquisition(" << acquisition_fpga_->unique_id() << ")"; + + // stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); + // DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; + // + // if (item_type_.compare("cbyte") == 0) + // { + // cbyte_to_float_x2_ = make_complex_byte_to_float_x2(); + // float_to_complex_ = gr::blocks::float_to_complex::make(); + // } + + channel_ = 0; + // threshold_ = 0.0; + doppler_step_ = 0; + gnss_synchro_ = 0; + //printf("L5 ACQ CLASS FINISHED\n"); +} + + +GpsL5iPcpsAcquisitionFpga::~GpsL5iPcpsAcquisitionFpga() +{ + //delete[] code_; + delete[] d_all_fft_codes_; +} + + +void GpsL5iPcpsAcquisitionFpga::set_channel(unsigned int channel) +{ + channel_ = channel; + acquisition_fpga_->set_channel(channel_); +} + + +void GpsL5iPcpsAcquisitionFpga::set_threshold(float threshold) +{ + // float pfa = configuration_->property(role_ + boost::lexical_cast(channel_) + ".pfa", 0.0); + // + // if (pfa == 0.0) + // { + // pfa = configuration_->property(role_ + ".pfa", 0.0); + // } + // if (pfa == 0.0) + // { + // threshold_ = threshold; + // } + // else + // { + // threshold_ = calculate_threshold(pfa); + // } + + // DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold_; + + // the .pfa parameter and the threshold calculation is only used for the CFAR algorithm. + // We don't use the CFAR algorithm in the FPGA. Therefore the threshold is set as such. + DLOG(INFO) << "Channel " << channel_ << " Threshold = " << threshold; + acquisition_fpga_->set_threshold(threshold); +} + + +void GpsL5iPcpsAcquisitionFpga::set_doppler_max(unsigned int doppler_max) +{ + doppler_max_ = doppler_max; + acquisition_fpga_->set_doppler_max(doppler_max_); +} + + +// Be aware that Doppler step should be set to 2/(3T) Hz, where T is the coherent integration time (GPS L2 period is 0.02s) +// Doppler bin minimum size= 33 Hz +void GpsL5iPcpsAcquisitionFpga::set_doppler_step(unsigned int doppler_step) +{ + doppler_step_ = doppler_step; + acquisition_fpga_->set_doppler_step(doppler_step_); +} + + +void GpsL5iPcpsAcquisitionFpga::set_gnss_synchro(Gnss_Synchro* gnss_synchro) +{ + gnss_synchro_ = gnss_synchro; + acquisition_fpga_->set_gnss_synchro(gnss_synchro_); +} + + +signed int GpsL5iPcpsAcquisitionFpga::mag() +{ + return acquisition_fpga_->mag(); +} + + +void GpsL5iPcpsAcquisitionFpga::init() +{ + acquisition_fpga_->init(); +} + +void GpsL5iPcpsAcquisitionFpga::set_local_code() +{ + acquisition_fpga_->set_local_code(); +} + + +void GpsL5iPcpsAcquisitionFpga::reset() +{ + acquisition_fpga_->set_active(true); +} + +void GpsL5iPcpsAcquisitionFpga::set_state(int state) +{ + acquisition_fpga_->set_state(state); +} + + +//float GpsL5iPcpsAcquisitionFpga::calculate_threshold(float pfa) +//{ +// //Calculate the threshold +// unsigned int frequency_bins = 0; +// for (int doppler = static_cast(-doppler_max_); doppler <= static_cast(doppler_max_); doppler += doppler_step_) +// { +// frequency_bins++; +// } +// DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa; +// unsigned int ncells = vector_length_ * frequency_bins; +// double exponent = 1.0 / static_cast(ncells); +// double val = pow(1.0 - pfa, exponent); +// double lambda = double(vector_length_); +// boost::math::exponential_distribution mydist(lambda); +// float threshold = static_cast(quantile(mydist, val)); +// +// return threshold; +//} + + +void GpsL5iPcpsAcquisitionFpga::connect(gr::top_block_sptr top_block) +{ + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->connect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } + // nothing to connect +} + + +void GpsL5iPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) +{ + // if (item_type_.compare("gr_complex") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cshort") == 0) + // { + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // // Since a byte-based acq implementation is not available, + // // we just convert cshorts to gr_complex + // top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); + // top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); + // top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); + // top_block->disconnect(stream_to_vector_, 0, acquisition_fpga_, 0); + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // } + // nothing to disconnect +} + + +gr::basic_block_sptr GpsL5iPcpsAcquisitionFpga::get_left_block() +{ + // if (item_type_.compare("gr_complex") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cshort") == 0) + // { + // return stream_to_vector_; + // } + // else if (item_type_.compare("cbyte") == 0) + // { + // return cbyte_to_float_x2_; + // } + // else + // { + // LOG(WARNING) << item_type_ << " unknown acquisition item type"; + // return nullptr; + // } + return nullptr; +} + + +gr::basic_block_sptr GpsL5iPcpsAcquisitionFpga::get_right_block() +{ + return acquisition_fpga_; +} diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h new file mode 100644 index 000000000..af916d3d5 --- /dev/null +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h @@ -0,0 +1,176 @@ +/*! + * \file GPS_L5i_PCPS_Acquisition.h + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * GPS L5i signals + * \authors
        + *
      • Javier Arribas, 2017. jarribas(at)cttc.es + *
      + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_FPGA_H_ +#define GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_FPGA_H_ + +#include "acquisition_interface.h" +#include "gnss_synchro.h" +#include "pcps_acquisition_fpga.h" +#include "complex_byte_to_float_x2.h" +#include +#include +#include +#include + + +class ConfigurationInterface; + +/*! + * \brief This class adapts a PCPS acquisition block to an AcquisitionInterface + * for GPS L5i signals + */ +class GpsL5iPcpsAcquisitionFpga : public AcquisitionInterface +{ +public: + GpsL5iPcpsAcquisitionFpga(ConfigurationInterface* configuration, + std::string role, unsigned int in_streams, + unsigned int out_streams); + + virtual ~GpsL5iPcpsAcquisitionFpga(); + + inline std::string role() override + { + return role_; + } + + /*! + * \brief Returns "GPS_L5i_PCPS_Acquisition" + */ + inline std::string implementation() override + { + return "GPS_L5i_PCPS_Acquisition"; + } + + 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; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and + * tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + /*! + * \brief Set acquisition channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set statistics threshold of PCPS algorithm + */ + void set_threshold(float threshold) override; + + /*! + * \brief Set maximum Doppler off grid search + */ + void set_doppler_max(unsigned int doppler_max) override; + + /*! + * \brief Set Doppler steps for the grid search + */ + void set_doppler_step(unsigned int doppler_step) override; + + /*! + * \brief Initializes acquisition algorithm. + */ + void init() override; + + /*! + * \brief Sets local code for GPS L2/M PCPS acquisition algorithm. + */ + void set_local_code() override; + + /*! + * \brief Returns the maximum peak of grid search + */ + signed int mag() override; + + /*! + * \brief Restart acquisition algorithm + */ + void reset() override; + + /*! + * \brief If state = 1, it forces the block to start acquiring from the first sample + */ + void set_state(int state) override; + + /*! + * \brief Stop running acquisition + */ + void stop_acquisition() override; + +private: + ConfigurationInterface* configuration_; + //pcps_acquisition_sptr acquisition_; + pcps_acquisition_fpga_sptr acquisition_fpga_; + gr::blocks::stream_to_vector::sptr stream_to_vector_; + gr::blocks::float_to_complex::sptr float_to_complex_; + complex_byte_to_float_x2_sptr cbyte_to_float_x2_; + size_t item_size_; + std::string item_type_; + unsigned int vector_length_; + unsigned int code_length_; + bool bit_transition_flag_; + bool use_CFAR_algorithm_flag_; + unsigned int channel_; + float threshold_; + unsigned int doppler_max_; + unsigned int doppler_step_; + unsigned int max_dwells_; + long fs_in_; + //long if_; + bool dump_; + bool blocking_; + std::string dump_filename_; + std::complex* code_; + Gnss_Synchro* gnss_synchro_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + + lv_16sc_t* d_all_fft_codes_; // memory that contains all the code ffts + + float calculate_threshold(float pfa); +}; + +#endif /* GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_FPGA_H_ */ diff --git a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt index 50fc61ae9..60825d6f0 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt @@ -28,50 +28,83 @@ set(ACQ_GR_BLOCKS_SOURCES galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc ) +set(ACQ_GR_BLOCKS_HEADERS + pcps_acquisition.h + pcps_assisted_acquisition_cc.h + pcps_acquisition_fine_doppler_cc.h + pcps_tong_acquisition_cc.h + pcps_cccwsr_acquisition_cc.h + pcps_quicksync_acquisition_cc.h + galileo_pcps_8ms_acquisition_cc.h + galileo_e5a_noncoherent_iq_acquisition_caf_cc.h +) + if(ENABLE_FPGA) set(ACQ_GR_BLOCKS_SOURCES ${ACQ_GR_BLOCKS_SOURCES} pcps_acquisition_fpga.cc) -endif(ENABLE_FPGA) + set(ACQ_GR_BLOCKS_HEADERS ${ACQ_GR_BLOCKS_HEADERS} pcps_acquisition_fpga.h) +endif() if(OPENCL_FOUND) set(ACQ_GR_BLOCKS_SOURCES ${ACQ_GR_BLOCKS_SOURCES} pcps_opencl_acquisition_cc.cc) -endif(OPENCL_FOUND) + set(ACQ_GR_BLOCKS_HEADERS ${ACQ_GR_BLOCKS_HEADERS} pcps_opencl_acquisition_cc.h) +endif() include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${ARMADILLO_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${VOLK_GNSSSDR_INCLUDE_DIRS} - ${MATIO_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${Boost_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${ARMADILLO_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_GNSSSDR_INCLUDE_DIRS} + ${MATIO_INCLUDE_DIRS} ) - if(OPENCL_FOUND) - include_directories( ${OPENCL_INCLUDE_DIRS} ) + include_directories(${OPENCL_INCLUDE_DIRS}) if(OS_IS_MACOSX) - set(OPT_LIBRARIES ${OPT_LIBRARIES} "-framework OpenCL") - else(OS_IS_MACOSX) - set(OPT_LIBRARIES ${OPT_LIBRARIES} ${OPENCL_LIBRARIES}) - endif(OS_IS_MACOSX) -endif(OPENCL_FOUND) + set(OPT_LIBRARIES ${OPT_LIBRARIES} "-framework OpenCL") + else() + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${OPENCL_LIBRARIES}) + endif() +endif() -file(GLOB ACQ_GR_BLOCKS_HEADERS "*.h") list(SORT ACQ_GR_BLOCKS_HEADERS) +list(SORT ACQ_GR_BLOCKS_SOURCES) add_library(acq_gr_blocks ${ACQ_GR_BLOCKS_SOURCES} ${ACQ_GR_BLOCKS_HEADERS}) source_group(Headers FILES ${ACQ_GR_BLOCKS_HEADERS}) if(ENABLE_FPGA) - target_link_libraries(acq_gr_blocks acquisition_lib gnss_sp_libs gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_FFT_LIBRARIES} ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${OPT_LIBRARIES} ${OPT_ACQUISITION_LIBRARIES}) -else(ENABLE_FPGA) - target_link_libraries(acq_gr_blocks gnss_sp_libs gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_FFT_LIBRARIES} ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${OPT_LIBRARIES} ${OPT_ACQUISITION_LIBRARIES} ${MATIO_LIBRARIES}) -endif(ENABLE_FPGA) + target_link_libraries(acq_gr_blocks + acquisition_lib + gnss_sp_libs + gnss_system_parameters + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_FFT_LIBRARIES} + ${VOLK_LIBRARIES} + ${VOLK_GNSSSDR_LIBRARIES} + ${OPT_LIBRARIES} + ${OPT_ACQUISITION_LIBRARIES} + ) +else() + target_link_libraries(acq_gr_blocks + gnss_sp_libs + gnss_system_parameters + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_FFT_LIBRARIES} + ${VOLK_LIBRARIES} + ${VOLK_GNSSSDR_LIBRARIES} + ${OPT_LIBRARIES} + ${MATIO_LIBRARIES} + ${OPT_ACQUISITION_LIBRARIES} + ) +endif() -if(NOT VOLK_GNSSSDR_FOUND) +if(NOT VOLKGNSSSDR_FOUND) add_dependencies(acq_gr_blocks volk_gnsssdr_module) -endif(NOT VOLK_GNSSSDR_FOUND) +endif() diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc index 64b64b193..fe7b70878 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc @@ -48,7 +48,7 @@ using google::LogMessage; galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr galileo_e5a_noncoherentIQ_make_acquisition_caf_cc( unsigned int sampled_ms, unsigned int max_dwells, - unsigned int doppler_max, long fs_in, + unsigned int doppler_max, int64_t fs_in, int samples_per_ms, int samples_per_code, bool bit_transition_flag, bool dump, @@ -67,7 +67,7 @@ galileo_e5a_noncoherentIQ_acquisition_caf_cc::galileo_e5a_noncoherentIQ_acquisit unsigned int sampled_ms, unsigned int max_dwells, unsigned int doppler_max, - long fs_in, + int64_t fs_in, int samples_per_ms, int samples_per_code, bool bit_transition_flag, @@ -80,7 +80,7 @@ galileo_e5a_noncoherentIQ_acquisition_caf_cc::galileo_e5a_noncoherentIQ_acquisit gr::io_signature::make(0, 0, sizeof(gr_complex))) { this->message_port_register_out(pmt::mp("events")); - d_sample_counter = 0; // SAMPLE COUNTER + d_sample_counter = 0ULL; // SAMPLE COUNTER d_active = false; d_state = 0; d_fs_in = fs_in; @@ -280,7 +280,8 @@ void galileo_e5a_noncoherentIQ_acquisition_caf_cc::init() d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_doppler_step = 0U; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; d_mag = 0.0; d_input_power = 0.0; const double GALILEO_TWO_PI = 6.283185307179600; @@ -328,7 +329,8 @@ void galileo_e5a_noncoherentIQ_acquisition_caf_cc::set_state(int state) { d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; @@ -376,14 +378,15 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items //restart acquisition variables d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; d_test_statistics = 0.0; d_state = 1; } - d_sample_counter += ninput_items[0]; // sample counter + d_sample_counter += static_cast(ninput_items[0]); // sample counter consume_each(ninput_items[0]); break; @@ -407,7 +410,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items d_state = 2; } d_buffer_count += buff_increment; - d_sample_counter += buff_increment; // sample counter + d_sample_counter += static_cast(buff_increment); // sample counter consume_each(buff_increment); break; } @@ -419,7 +422,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items { memcpy(&d_inbuffer[d_buffer_count], in, sizeof(gr_complex) * (d_fft_size - d_buffer_count)); } - d_sample_counter += (d_fft_size - d_buffer_count); // sample counter + d_sample_counter += static_cast(d_fft_size - d_buffer_count); // sample counter // initialize acquisition algorithm int doppler; @@ -633,7 +636,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items d_gnss_synchro->Acq_delay_samples = static_cast(indext % d_samples_per_code); d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; - + d_gnss_synchro->Acq_doppler_step = d_doppler_step; // 5- Compute the test statistics and compare to the threshold d_test_statistics = d_mag / d_input_power; } @@ -806,7 +809,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items acquisition_message = 1; this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message)); - d_sample_counter += ninput_items[0]; // sample counter + d_sample_counter += static_cast(ninput_items[0]); // sample counter consume_each(ninput_items[0]); break; } @@ -826,7 +829,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items d_active = false; d_state = 0; - d_sample_counter += ninput_items[0]; // sample counter + d_sample_counter += static_cast(ninput_items[0]); // sample counter consume_each(ninput_items[0]); acquisition_message = 2; this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message)); diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.h b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.h index c60b2ac82..2ebe9a8e5 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.h @@ -52,7 +52,7 @@ typedef boost::shared_ptr galileo_ galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(unsigned int sampled_ms, unsigned int max_dwells, - unsigned int doppler_max, long fs_in, + unsigned int doppler_max, int64_t fs_in, int samples_per_ms, int samples_per_code, bool bit_transition_flag, bool dump, @@ -74,7 +74,7 @@ private: galileo_e5a_noncoherentIQ_make_acquisition_caf_cc( unsigned int sampled_ms, unsigned int max_dwells, - unsigned int doppler_max, long fs_in, + unsigned int doppler_max, int64_t fs_in, int samples_per_ms, int samples_per_code, bool bit_transition_flag, bool dump, @@ -86,7 +86,7 @@ private: galileo_e5a_noncoherentIQ_acquisition_caf_cc( unsigned int sampled_ms, unsigned int max_dwells, - unsigned int doppler_max, long fs_in, + unsigned int doppler_max, int64_t fs_in, int samples_per_ms, int samples_per_code, bool bit_transition_flag, bool dump, @@ -99,7 +99,7 @@ private: int doppler_offset); float estimate_input_power(gr_complex* in); - long d_fs_in; + int64_t d_fs_in; int d_samples_per_ms; int d_sampled_ms; int d_samples_per_code; @@ -111,7 +111,7 @@ private: unsigned int d_max_dwells; unsigned int d_well_count; unsigned int d_fft_size; - unsigned long int d_sample_counter; + uint64_t d_sample_counter; gr_complex** d_grid_doppler_wipeoffs; unsigned int d_num_doppler_bins; gr_complex* d_fft_code_I_A; diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc index 44c809961..318f6ad46 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc @@ -60,7 +60,7 @@ galileo_pcps_8ms_acquisition_cc::galileo_pcps_8ms_acquisition_cc( gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms)) { this->message_port_register_out(pmt::mp("events")); - d_sample_counter = 0; // SAMPLE COUNTER + d_sample_counter = 0ULL; // SAMPLE COUNTER d_active = false; d_state = 0; d_fs_in = fs_in; @@ -151,10 +151,10 @@ void galileo_pcps_8ms_acquisition_cc::init() d_gnss_synchro->Flag_valid_symbol_output = false; d_gnss_synchro->Flag_valid_pseudorange = false; d_gnss_synchro->Flag_valid_word = false; - + d_gnss_synchro->Acq_doppler_step = 0U; d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; d_mag = 0.0; d_input_power = 0.0; const double GALILEO_TWO_PI = 6.283185307179600; @@ -188,7 +188,8 @@ void galileo_pcps_8ms_acquisition_cc::set_state(int state) { d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; @@ -219,7 +220,8 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items, //restart acquisition variables d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; @@ -228,7 +230,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items, d_state = 1; } - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter consume_each(ninput_items[0]); break; @@ -249,7 +251,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items, d_input_power = 0.0; d_mag = 0.0; - d_sample_counter += d_fft_size; // sample counter + d_sample_counter += static_cast(d_fft_size); // sample counter d_well_count++; @@ -328,6 +330,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items, d_gnss_synchro->Acq_delay_samples = static_cast(indext % d_samples_per_code); d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; + d_gnss_synchro->Acq_doppler_step = d_doppler_step; } // Record results to file if required @@ -404,7 +407,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter consume_each(ninput_items[0]); acquisition_message = 2; diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.h index c104c3814..dc00681a3 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.h @@ -83,7 +83,7 @@ private: unsigned int d_max_dwells; unsigned int d_well_count; unsigned int d_fft_size; - unsigned long int d_sample_counter; + uint64_t d_sample_counter; gr_complex** d_grid_doppler_wipeoffs; unsigned int d_num_doppler_bins; gr_complex* d_fft_code_A; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index a9d6f8c53..1bb4b39a7 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -36,6 +36,8 @@ #include "pcps_acquisition.h" #include "GPS_L1_CA.h" // for GPS_TWO_PI #include "GLONASS_L1_L2_CA.h" // for GLONASS_TWO_PI" +#include "gnss_sdr_create_directory.h" +#include #include #include #include @@ -52,27 +54,36 @@ pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_) pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acquisition", - gr::io_signature::make(1, 1, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1)), - gr::io_signature::make(0, 0, conf_.it_size * conf_.sampled_ms * conf_.samples_per_ms * (conf_.bit_transition_flag ? 2 : 1))) + gr::io_signature::make(1, 1, conf_.it_size), + gr::io_signature::make(0, 0, conf_.it_size)) { this->message_port_register_out(pmt::mp("events")); acq_parameters = conf_; - d_sample_counter = 0; // SAMPLE COUNTER + d_sample_counter = 0ULL; // SAMPLE COUNTER d_active = false; d_positive_acq = 0; d_state = 0; - d_old_freq = 0; - d_well_count = 0; - d_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms; + d_old_freq = 0LL; + d_num_noncoherent_integrations_counter = 0U; + d_consumed_samples = acq_parameters.sampled_ms * acq_parameters.samples_per_ms * (acq_parameters.bit_transition_flag ? 2 : 1); + if (acq_parameters.sampled_ms == acq_parameters.ms_per_code) + { + d_fft_size = d_consumed_samples; + } + else + { + d_fft_size = d_consumed_samples * 2; + } + // d_fft_size = next power of two? //// d_mag = 0; d_input_power = 0.0; - d_num_doppler_bins = 0; + d_num_doppler_bins = 0U; d_threshold = 0.0; - d_doppler_step = 0; + d_doppler_step = 0U; d_doppler_center_step_two = 0.0; d_test_statistics = 0.0; - d_channel = 0; + d_channel = 0U; if (conf_.it_size == sizeof(gr_complex)) { d_cshort = false; @@ -94,12 +105,14 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu // size of the input buffer and padding the code with zeros. if (acq_parameters.bit_transition_flag) { - d_fft_size *= 2; - acq_parameters.max_dwells = 1; //Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells + d_fft_size = d_consumed_samples * 2; + acq_parameters.max_dwells = 1; // Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells } + d_tmp_buffer = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); d_fft_codes = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_magnitude = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); + d_input_signal = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); // Direct FFT d_fft_if = new gr::fft::fft_complex(d_fft_size, true); @@ -110,36 +123,85 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu d_gnss_synchro = 0; d_grid_doppler_wipeoffs = nullptr; d_grid_doppler_wipeoffs_step_two = nullptr; + d_magnitude_grid = nullptr; d_worker_active = false; - d_data_buffer = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_data_buffer = static_cast(volk_gnsssdr_malloc(d_consumed_samples * sizeof(gr_complex), volk_gnsssdr_get_alignment())); if (d_cshort) { - d_data_buffer_sc = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); + d_data_buffer_sc = static_cast(volk_gnsssdr_malloc(d_consumed_samples * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); } else { d_data_buffer_sc = nullptr; } grid_ = arma::fmat(); + narrow_grid_ = arma::fmat(); d_step_two = false; - d_dump_number = 0; - d_dump_channel = acq_parameters.dump_channel; -} + d_num_doppler_bins_step2 = acq_parameters.num_doppler_bins_step2; + d_samplesPerChip = acq_parameters.samples_per_chip; + d_buffer_count = 0U; + // todo: CFAR statistic not available for non-coherent integration + if (acq_parameters.max_dwells == 1) + { + d_use_CFAR_algorithm_flag = acq_parameters.use_CFAR_algorithm_flag; + } + else + { + d_use_CFAR_algorithm_flag = false; + } + d_dump_number = 0LL; + d_dump_channel = acq_parameters.dump_channel; + d_dump = acq_parameters.dump; + d_dump_filename = acq_parameters.dump_filename; + if (d_dump) + { + std::string dump_path; + // Get path + if (d_dump_filename.find_last_of("/") != std::string::npos) + { + std::string dump_filename_ = d_dump_filename.substr(d_dump_filename.find_last_of("/") + 1); + dump_path = d_dump_filename.substr(0, d_dump_filename.find_last_of("/")); + d_dump_filename = dump_filename_; + } + else + { + dump_path = std::string("."); + } + if (d_dump_filename.empty()) + { + d_dump_filename = "acquisition"; + } + // remove extension if any + if (d_dump_filename.substr(1).find_last_of(".") != std::string::npos) + { + d_dump_filename = d_dump_filename.substr(0, d_dump_filename.find_last_of(".")); + } + d_dump_filename = dump_path + boost::filesystem::path::preferred_separator + d_dump_filename; + // create directory + if (!gnss_sdr_create_directory(dump_path)) + { + std::cerr << "GNSS-SDR cannot create dump file for the Acquisition block. Wrong permissions?" << std::endl; + d_dump = false; + } + } +} pcps_acquisition::~pcps_acquisition() { if (d_num_doppler_bins > 0) { - for (unsigned int i = 0; i < d_num_doppler_bins; i++) + for (uint32_t i = 0; i < d_num_doppler_bins; i++) { volk_gnsssdr_free(d_grid_doppler_wipeoffs[i]); + volk_gnsssdr_free(d_magnitude_grid[i]); } delete[] d_grid_doppler_wipeoffs; + delete[] d_magnitude_grid; } if (acq_parameters.make_2_steps) { - for (unsigned int i = 0; i < acq_parameters.num_doppler_bins_step2; i++) + for (uint32_t i = 0; i < d_num_doppler_bins_step2; i++) { volk_gnsssdr_free(d_grid_doppler_wipeoffs_step_two[i]); } @@ -147,6 +209,8 @@ pcps_acquisition::~pcps_acquisition() } volk_gnsssdr_free(d_fft_codes); volk_gnsssdr_free(d_magnitude); + volk_gnsssdr_free(d_tmp_buffer); + volk_gnsssdr_free(d_input_signal); delete d_ifft; delete d_fft_if; volk_gnsssdr_free(d_data_buffer); @@ -160,7 +224,7 @@ pcps_acquisition::~pcps_acquisition() void pcps_acquisition::set_local_code(std::complex* code) { // reset the intermediate frequency - d_old_freq = 0; + d_old_freq = 0LL; // This will check if it's fdma, if yes will update the intermediate frequency and the doppler grid if (is_fdma()) { @@ -173,13 +237,21 @@ void pcps_acquisition::set_local_code(std::complex* code) gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler if (acq_parameters.bit_transition_flag) { - int offset = d_fft_size / 2; + int32_t offset = d_fft_size / 2; std::fill_n(d_fft_if->get_inbuf(), offset, gr_complex(0.0, 0.0)); memcpy(d_fft_if->get_inbuf() + offset, code, sizeof(gr_complex) * offset); } else { - memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_fft_size); + if (acq_parameters.sampled_ms == acq_parameters.ms_per_code) + { + memcpy(d_fft_if->get_inbuf(), code, sizeof(gr_complex) * d_consumed_samples); + } + else + { + std::fill_n(d_fft_if->get_inbuf(), d_fft_size - d_consumed_samples, gr_complex(0.0, 0.0)); + memcpy(d_fft_if->get_inbuf() + d_consumed_samples, code, sizeof(gr_complex) * d_consumed_samples); + } } d_fft_if->execute(); // We need the FFT of local code @@ -209,11 +281,11 @@ bool pcps_acquisition::is_fdma() } -void pcps_acquisition::update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq) +void pcps_acquisition::update_local_carrier(gr_complex* carrier_vector, int32_t correlator_length_samples, float freq) { float phase_step_rad = GPS_TWO_PI * freq / static_cast(acq_parameters.fs_in); float _phase[1]; - _phase[0] = 0; + _phase[0] = 0.0; volk_gnsssdr_s32f_sincos_32fc(carrier_vector, -phase_step_rad, _phase, correlator_length_samples); } @@ -224,60 +296,78 @@ void pcps_acquisition::init() d_gnss_synchro->Flag_valid_symbol_output = false; d_gnss_synchro->Flag_valid_pseudorange = false; d_gnss_synchro->Flag_valid_word = false; - + d_gnss_synchro->Acq_doppler_step = 0U; d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; d_mag = 0.0; d_input_power = 0.0; - d_num_doppler_bins = static_cast(std::ceil(static_cast(static_cast(acq_parameters.doppler_max) - static_cast(-acq_parameters.doppler_max)) / static_cast(d_doppler_step))); + d_num_doppler_bins = static_cast(std::ceil(static_cast(static_cast(acq_parameters.doppler_max) - static_cast(-acq_parameters.doppler_max)) / static_cast(d_doppler_step))); // Create the carrier Doppler wipeoff signals - d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins]; - if (acq_parameters.make_2_steps) + if (d_grid_doppler_wipeoffs == nullptr) d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins]; + if (acq_parameters.make_2_steps && (d_grid_doppler_wipeoffs_step_two == nullptr)) { - d_grid_doppler_wipeoffs_step_two = new gr_complex*[acq_parameters.num_doppler_bins_step2]; - for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++) + d_grid_doppler_wipeoffs_step_two = new gr_complex*[d_num_doppler_bins_step2]; + for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++) { d_grid_doppler_wipeoffs_step_two[doppler_index] = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); } } - for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) + + if (d_magnitude_grid == nullptr) { - d_grid_doppler_wipeoffs[doppler_index] = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - int doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * doppler_index; + d_magnitude_grid = new float*[d_num_doppler_bins]; + for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) + { + d_grid_doppler_wipeoffs[doppler_index] = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_magnitude_grid[doppler_index] = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); + } + } + + for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) + { + for (uint32_t k = 0; k < d_fft_size; k++) + { + d_magnitude_grid[doppler_index][k] = 0.0; + } + int32_t doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * doppler_index; update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler); } + d_worker_active = false; - if (acq_parameters.dump) + if (d_dump) { - unsigned int effective_fft_size = (acq_parameters.bit_transition_flag ? (d_fft_size / 2) : d_fft_size); + uint32_t effective_fft_size = (acq_parameters.bit_transition_flag ? (d_fft_size / 2) : d_fft_size); grid_ = arma::fmat(effective_fft_size, d_num_doppler_bins, arma::fill::zeros); + narrow_grid_ = arma::fmat(effective_fft_size, d_num_doppler_bins_step2, arma::fill::zeros); } } void pcps_acquisition::update_grid_doppler_wipeoffs() { - for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) + for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) { - int doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * doppler_index; + int32_t doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * doppler_index; update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler); } } + void pcps_acquisition::update_grid_doppler_wipeoffs_step2() { - for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++) + for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++) { - float doppler = (static_cast(doppler_index) - static_cast(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2; + float doppler = (static_cast(doppler_index) - static_cast(floor(d_num_doppler_bins_step2 / 2.0))) * acq_parameters.doppler_step2; update_local_carrier(d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size, d_doppler_center_step_two + doppler); } } -void pcps_acquisition::set_state(int state) + +void pcps_acquisition::set_state(int32_t state) { gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler d_state = state; @@ -285,8 +375,8 @@ void pcps_acquisition::set_state(int state) { d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; - d_well_count = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_mag = 0.0; d_input_power = 0.0; d_test_statistics = 0.0; @@ -304,8 +394,8 @@ void pcps_acquisition::set_state(int state) void pcps_acquisition::send_positive_acquisition() { - // 6.1- Declare positive acquisition using a message port - //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL + // Declare positive acquisition using a message port + // 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL DLOG(INFO) << "positive acquisition" << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN << ", sample_stamp " << d_sample_counter @@ -322,8 +412,8 @@ void pcps_acquisition::send_positive_acquisition() void pcps_acquisition::send_negative_acquisition() { - // 6.2- Declare negative acquisition using a message port - //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL + // Declare negative acquisition using a message port + // 0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL DLOG(INFO) << "negative acquisition" << ", satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN << ", sample_stamp " << d_sample_counter @@ -338,10 +428,10 @@ void pcps_acquisition::send_negative_acquisition() } -void pcps_acquisition::dump_results(int effective_fft_size) +void pcps_acquisition::dump_results(int32_t effective_fft_size) { d_dump_number++; - std::string filename = acq_parameters.dump_filename; + std::string filename = d_dump_filename; filename.append("_"); filename.append(1, d_gnss_synchro->System); filename.append("_"); @@ -359,7 +449,7 @@ void pcps_acquisition::dump_results(int effective_fft_size) if (matfp == NULL) { std::cout << "Unable to create or open Acquisition dump file" << std::endl; - acq_parameters.dump = false; + //acq_parameters.dump = false; } else { @@ -412,125 +502,234 @@ void pcps_acquisition::dump_results(int effective_fft_size) Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarFree(matvar); + matvar = Mat_VarCreate("num_dwells", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_num_noncoherent_integrations_counter, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + if (acq_parameters.make_2_steps) + { + dims[0] = static_cast(effective_fft_size); + dims[1] = static_cast(d_num_doppler_bins_step2); + matvar = Mat_VarCreate("acq_grid_narrow", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, narrow_grid_.memptr(), 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + dims[0] = static_cast(1); + dims[1] = static_cast(1); + matvar = Mat_VarCreate("doppler_step_narrow", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &acq_parameters.doppler_step2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + aux = d_doppler_center_step_two - static_cast(floor(d_num_doppler_bins_step2 / 2.0)) * acq_parameters.doppler_step2; + matvar = Mat_VarCreate("doppler_grid_narrow_min", MAT_C_SINGLE, MAT_T_SINGLE, 1, dims, &aux, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); } } -void pcps_acquisition::acquisition_core(unsigned long int samp_count) +float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, float input_power, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step) +{ + float grid_maximum = 0.0; + uint32_t index_doppler = 0U; + uint32_t tmp_intex_t = 0U; + uint32_t index_time = 0U; + float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); + + // Find the correlation peak and the carrier frequency + for (uint32_t i = 0; i < num_doppler_bins; i++) + { + volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); + if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum) + { + grid_maximum = d_magnitude_grid[i][tmp_intex_t]; + index_doppler = i; + index_time = tmp_intex_t; + } + } + indext = index_time; + if (!d_step_two) + { + doppler = -static_cast(doppler_max) + doppler_step * static_cast(index_doppler); + } + else + { + doppler = static_cast(d_doppler_center_step_two + (static_cast(index_doppler) - static_cast(floor(d_num_doppler_bins_step2 / 2.0))) * acq_parameters.doppler_step2); + } + + float magt = grid_maximum / (fft_normalization_factor * fft_normalization_factor); + return magt / input_power; +} + + +float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step) +{ + // Look for correlation peaks in the results + // Find the highest peak and compare it to the second highest peak + // The second peak is chosen not closer than 1 chip to the highest peak + + float firstPeak = 0.0; + uint32_t index_doppler = 0U; + uint32_t tmp_intex_t = 0U; + uint32_t index_time = 0U; + + // Find the correlation peak and the carrier frequency + for (uint32_t i = 0; i < num_doppler_bins; i++) + { + volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); + if (d_magnitude_grid[i][tmp_intex_t] > firstPeak) + { + firstPeak = d_magnitude_grid[i][tmp_intex_t]; + index_doppler = i; + index_time = tmp_intex_t; + } + } + indext = index_time; + + if (!d_step_two) + { + doppler = -static_cast(doppler_max) + doppler_step * static_cast(index_doppler); + } + else + { + doppler = static_cast(d_doppler_center_step_two + (static_cast(index_doppler) - static_cast(floor(d_num_doppler_bins_step2 / 2.0))) * acq_parameters.doppler_step2); + } + + // Find 1 chip wide code phase exclude range around the peak + int32_t excludeRangeIndex1 = index_time - d_samplesPerChip; + int32_t excludeRangeIndex2 = index_time + d_samplesPerChip; + + // Correct code phase exclude range if the range includes array boundaries + if (excludeRangeIndex1 < 0) + { + excludeRangeIndex1 = d_fft_size + excludeRangeIndex1; + } + else if (excludeRangeIndex2 >= static_cast(d_fft_size)) + { + excludeRangeIndex2 = excludeRangeIndex2 - d_fft_size; + } + + int32_t idx = excludeRangeIndex1; + memcpy(d_tmp_buffer, d_magnitude_grid[index_doppler], d_fft_size); + do + { + d_tmp_buffer[idx] = 0.0; + idx++; + if (idx == static_cast(d_fft_size)) idx = 0; + } + while (idx != excludeRangeIndex2); + + // Find the second highest correlation peak in the same freq. bin --- + volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_tmp_buffer, d_fft_size); + float secondPeak = d_tmp_buffer[tmp_intex_t]; + + // Compute the test statistics and compare to the threshold + return firstPeak / secondPeak; +} + + +void pcps_acquisition::acquisition_core(uint64_t samp_count) { gr::thread::scoped_lock lk(d_setlock); - // initialize acquisition algorithm - uint32_t indext = 0; - float magt = 0.0; - const gr_complex* in = d_data_buffer; // Get the input samples pointer - int effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size); + // Initialize acquisition algorithm + int32_t doppler = 0; + uint32_t indext = 0U; + int32_t effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size); if (d_cshort) { - volk_gnsssdr_16ic_convert_32fc(d_data_buffer, d_data_buffer_sc, d_fft_size); + volk_gnsssdr_16ic_convert_32fc(d_data_buffer, d_data_buffer_sc, d_consumed_samples); } - float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); + memcpy(d_input_signal, d_data_buffer, d_consumed_samples * sizeof(gr_complex)); + if (d_fft_size > d_consumed_samples) + { + for (uint32_t i = d_consumed_samples; i < d_fft_size; i++) + { + d_input_signal[i] = gr_complex(0.0, 0.0); + } + } + const gr_complex* in = d_input_signal; // Get the input samples pointer d_input_power = 0.0; d_mag = 0.0; - d_well_count++; + d_num_noncoherent_integrations_counter++; DLOG(INFO) << "Channel: " << d_channel << " , doing acquisition of satellite: " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN << " ,sample stamp: " << samp_count << ", threshold: " << d_threshold << ", doppler_max: " << acq_parameters.doppler_max << ", doppler_step: " << d_doppler_step - << ", use_CFAR_algorithm_flag: " << (acq_parameters.use_CFAR_algorithm_flag ? "true" : "false"); + << ", use_CFAR_algorithm_flag: " << (d_use_CFAR_algorithm_flag ? "true" : "false"); lk.unlock(); - if (acq_parameters.use_CFAR_algorithm_flag) + + if (d_use_CFAR_algorithm_flag or acq_parameters.bit_transition_flag) { - // 1- (optional) Compute the input signal power estimation - volk_32fc_magnitude_squared_32f(d_magnitude, in, d_fft_size); - volk_32f_accumulator_s32f(&d_input_power, d_magnitude, d_fft_size); + // Compute the input signal power estimation + volk_32fc_magnitude_squared_32f(d_tmp_buffer, in, d_fft_size); + volk_32f_accumulator_s32f(&d_input_power, d_tmp_buffer, d_fft_size); d_input_power /= static_cast(d_fft_size); } - // 2- Doppler frequency search loop + + // Doppler frequency grid loop if (!d_step_two) { - for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) + for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) { - // doppler search steps - int doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * doppler_index; - + // Remove Doppler volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size); - // 3- Perform the FFT-based convolution (parallel time search) + // Perform the FFT-based convolution (parallel time search) // Compute the FFT of the carrier wiped--off incoming signal d_fft_if->execute(); - // Multiply carrier wiped--off, Fourier transformed incoming signal - // with the local FFT'd code reference using SIMD operations with VOLK library + // Multiply carrier wiped--off, Fourier transformed incoming signal with the local FFT'd code reference volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size); - // compute the inverse FFT + // Compute the inverse FFT d_ifft->execute(); - // Search maximum + // Compute squared magnitude (and accumulate in case of non-coherent integration) size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0); - volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size); - volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size); - magt = d_magnitude[indext]; - - if (acq_parameters.use_CFAR_algorithm_flag) + if (d_num_noncoherent_integrations_counter == 1) { - // Normalize the maximum value to correct the scale factor introduced by FFTW - magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor); + volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index], d_ifft->get_outbuf() + offset, effective_fft_size); } - // 4- record the maximum peak and the associated synchronization parameters - if (d_mag < magt) + else { - d_mag = magt; - - if (!acq_parameters.use_CFAR_algorithm_flag) - { - // Search grid noise floor approximation for this doppler line - volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size); - d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1); - } - - // In case that acq_parameters.bit_transition_flag = true, we compare the potentially - // new maximum test statistics (d_mag/d_input_power) with the value in - // d_test_statistics. When the second dwell is being processed, the value - // of d_mag/d_input_power could be lower than d_test_statistics (i.e, - // the maximum test statistics in the previous dwell is greater than - // current d_mag/d_input_power). Note that d_test_statistics is not - // restarted between consecutive dwells in multidwell operation. - - if (d_test_statistics < (d_mag / d_input_power) or !acq_parameters.bit_transition_flag) - { - d_gnss_synchro->Acq_delay_samples = static_cast(indext % acq_parameters.samples_per_code); - d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); - d_gnss_synchro->Acq_samplestamp_samples = samp_count; - - // 5- Compute the test statistics and compare to the threshold - //d_test_statistics = 2 * d_fft_size * d_mag / d_input_power; - d_test_statistics = d_mag / d_input_power; - } + volk_32fc_magnitude_squared_32f(d_tmp_buffer, d_ifft->get_outbuf() + offset, effective_fft_size); + volk_32f_x2_add_32f(d_magnitude_grid[doppler_index], d_magnitude_grid[doppler_index], d_tmp_buffer, effective_fft_size); } // Record results to file if required - if (acq_parameters.dump and d_channel == d_dump_channel) + if (d_dump and d_channel == d_dump_channel) { - memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); + memcpy(grid_.colptr(doppler_index), d_magnitude_grid[doppler_index], sizeof(float) * effective_fft_size); } } + + // Compute the test statistic + if (d_use_CFAR_algorithm_flag) + { + d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step); + } + else + { + d_test_statistics = first_vs_second_peak_statistic(indext, doppler, d_num_doppler_bins, acq_parameters.doppler_max, d_doppler_step); + } + d_gnss_synchro->Acq_delay_samples = static_cast(std::fmod(static_cast(indext), acq_parameters.samples_per_code)); + d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); + d_gnss_synchro->Acq_samplestamp_samples = samp_count; } else { - for (unsigned int doppler_index = 0; doppler_index < acq_parameters.num_doppler_bins_step2; doppler_index++) + for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++) { - // doppler search steps - float doppler = d_doppler_center_step_two + (static_cast(doppler_index) - static_cast(acq_parameters.num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2; - volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size); - // 3- Perform the FFT-based convolution (parallel time search) + // Perform the FFT-based convolution (parallel time search) // Compute the FFT of the carrier wiped--off incoming signal d_fft_if->execute(); @@ -541,55 +740,37 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) // compute the inverse FFT d_ifft->execute(); - // Search maximum size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0); - volk_32fc_magnitude_squared_32f(d_magnitude, d_ifft->get_outbuf() + offset, effective_fft_size); - volk_gnsssdr_32f_index_max_32u(&indext, d_magnitude, effective_fft_size); - magt = d_magnitude[indext]; - - if (acq_parameters.use_CFAR_algorithm_flag) + if (d_num_noncoherent_integrations_counter == 1) { - // Normalize the maximum value to correct the scale factor introduced by FFTW - magt = d_magnitude[indext] / (fft_normalization_factor * fft_normalization_factor); + volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index], d_ifft->get_outbuf() + offset, effective_fft_size); } - // 4- record the maximum peak and the associated synchronization parameters - if (d_mag < magt) + else { - d_mag = magt; - - if (!acq_parameters.use_CFAR_algorithm_flag) - { - // Search grid noise floor approximation for this doppler line - volk_32f_accumulator_s32f(&d_input_power, d_magnitude, effective_fft_size); - d_input_power = (d_input_power - d_mag) / (effective_fft_size - 1); - } - - // In case that acq_parameters.bit_transition_flag = true, we compare the potentially - // new maximum test statistics (d_mag/d_input_power) with the value in - // d_test_statistics. When the second dwell is being processed, the value - // of d_mag/d_input_power could be lower than d_test_statistics (i.e, - // the maximum test statistics in the previous dwell is greater than - // current d_mag/d_input_power). Note that d_test_statistics is not - // restarted between consecutive dwells in multidwell operation. - - if (d_test_statistics < (d_mag / d_input_power) or !acq_parameters.bit_transition_flag) - { - d_gnss_synchro->Acq_delay_samples = static_cast(indext % acq_parameters.samples_per_code); - d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); - d_gnss_synchro->Acq_samplestamp_samples = samp_count; - - // 5- Compute the test statistics and compare to the threshold - //d_test_statistics = 2 * d_fft_size * d_mag / d_input_power; - d_test_statistics = d_mag / d_input_power; - } + volk_32fc_magnitude_squared_32f(d_tmp_buffer, d_ifft->get_outbuf() + offset, effective_fft_size); + volk_32f_x2_add_32f(d_magnitude_grid[doppler_index], d_magnitude_grid[doppler_index], d_tmp_buffer, effective_fft_size); } // Record results to file if required - if (acq_parameters.dump and d_channel == d_dump_channel) + if (d_dump and d_channel == d_dump_channel) { - memcpy(grid_.colptr(doppler_index), d_magnitude, sizeof(float) * effective_fft_size); + memcpy(narrow_grid_.colptr(doppler_index), d_magnitude_grid[doppler_index], sizeof(float) * effective_fft_size); } } + // Compute the test statistic + if (d_use_CFAR_algorithm_flag) + { + d_test_statistics = max_to_input_power_statistic(indext, doppler, d_input_power, d_num_doppler_bins_step2, static_cast(d_doppler_center_step_two - (static_cast(d_num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2), acq_parameters.doppler_step2); + } + else + { + d_test_statistics = first_vs_second_peak_statistic(indext, doppler, d_num_doppler_bins_step2, static_cast(d_doppler_center_step_two - (static_cast(d_num_doppler_bins_step2) / 2.0) * acq_parameters.doppler_step2), acq_parameters.doppler_step2); + } + d_gnss_synchro->Acq_delay_samples = static_cast(std::fmod(static_cast(indext), acq_parameters.samples_per_code)); + d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); + d_gnss_synchro->Acq_samplestamp_samples = samp_count; + d_gnss_synchro->Acq_doppler_step = acq_parameters.doppler_step2; } + lk.lock(); if (!acq_parameters.bit_transition_flag) { @@ -607,6 +788,8 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) else { d_step_two = true; // Clear input buffer and make small grid acquisition + d_num_noncoherent_integrations_counter = 0; + d_positive_acq = 0; d_state = 0; } } @@ -616,12 +799,18 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) d_state = 0; // Positive acquisition } } - else if (d_well_count == acq_parameters.max_dwells) + else { + d_buffer_count = 0; + d_state = 1; + } + + if (d_num_noncoherent_integrations_counter == acq_parameters.max_dwells) + { + if (d_state != 0) send_negative_acquisition(); d_state = 0; d_active = false; d_step_two = false; - send_negative_acquisition(); } } else @@ -640,6 +829,7 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) else { d_step_two = true; // Clear input buffer and make small grid acquisition + d_num_noncoherent_integrations_counter = 0U; d_state = 0; } } @@ -657,10 +847,24 @@ void pcps_acquisition::acquisition_core(unsigned long int samp_count) } } d_worker_active = false; - // Record results to file if required - if (acq_parameters.dump and d_channel == d_dump_channel) + + if ((d_num_noncoherent_integrations_counter == acq_parameters.max_dwells) or (d_positive_acq == 1)) { - pcps_acquisition::dump_results(effective_fft_size); + // Record results to file if required + if (d_dump and d_channel == d_dump_channel) + { + pcps_acquisition::dump_results(effective_fft_size); + } + d_num_noncoherent_integrations_counter = 0U; + d_positive_acq = 0; + // Reset grid + for (uint32_t i = 0; i < d_num_doppler_bins; i++) + { + for (uint32_t k = 0; k < d_fft_size; k++) + { + d_magnitude_grid[i][k] = 0.0; + } + } } } @@ -679,13 +883,12 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), * 5. Compute the test statistics and compare to the threshold * 6. Declare positive or negative acquisition using a message port */ - gr::thread::scoped_lock lk(d_setlock); if (!d_active or d_worker_active) { if (!acq_parameters.blocking_on_standby) { - d_sample_counter += d_fft_size * ninput_items[0]; + d_sample_counter += static_cast(ninput_items[0]); consume_each(ninput_items[0]); } if (d_step_two) @@ -702,34 +905,66 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), { case 0: { - //restart acquisition variables + // Restart acquisition variables d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; - d_well_count = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_mag = 0.0; d_input_power = 0.0; d_test_statistics = 0.0; d_state = 1; + d_buffer_count = 0U; if (!acq_parameters.blocking_on_standby) { - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(ninput_items[0]); // sample counter consume_each(ninput_items[0]); } break; } - case 1: { - // Copy the data to the core and let it know that new data is available + uint32_t buff_increment; if (d_cshort) { - memcpy(d_data_buffer_sc, input_items[0], d_fft_size * sizeof(lv_16sc_t)); + const lv_16sc_t* in = reinterpret_cast(input_items[0]); // Get the input samples pointer + if ((ninput_items[0] + d_buffer_count) <= d_consumed_samples) + { + buff_increment = ninput_items[0]; + } + else + { + buff_increment = d_consumed_samples - d_buffer_count; + } + memcpy(&d_data_buffer_sc[d_buffer_count], in, sizeof(lv_16sc_t) * buff_increment); } else { - memcpy(d_data_buffer, input_items[0], d_fft_size * sizeof(gr_complex)); + const gr_complex* in = reinterpret_cast(input_items[0]); // Get the input samples pointer + if ((ninput_items[0] + d_buffer_count) <= d_consumed_samples) + { + buff_increment = ninput_items[0]; + } + else + { + buff_increment = d_consumed_samples - d_buffer_count; + } + memcpy(&d_data_buffer[d_buffer_count], in, sizeof(gr_complex) * buff_increment); } + + // If buffer will be full in next iteration + if (d_buffer_count >= d_consumed_samples) + { + d_state = 2; + } + d_buffer_count += buff_increment; + d_sample_counter += static_cast(buff_increment); + consume_each(buff_increment); + break; + } + case 2: + { + // Copy the data to the core and let it know that new data is available if (acq_parameters.blocking) { lk.unlock(); @@ -740,8 +975,8 @@ int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), gr::thread::thread d_worker(&pcps_acquisition::acquisition_core, this, d_sample_counter); d_worker_active = true; } - d_sample_counter += d_fft_size; - consume_each(1); + consume_each(0); + d_buffer_count = 0U; break; } } diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index 91bfaf112..4e46d049b 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -82,39 +82,48 @@ private: pcps_acquisition(const Acq_Conf& conf_); - void update_local_carrier(gr_complex* carrier_vector, int correlator_length_samples, float freq); + void update_local_carrier(gr_complex* carrier_vector, int32_t correlator_length_samples, float freq); void update_grid_doppler_wipeoffs(); void update_grid_doppler_wipeoffs_step2(); bool is_fdma(); - void acquisition_core(unsigned long int samp_count); + void acquisition_core(uint64_t samp_count); void send_negative_acquisition(); void send_positive_acquisition(); - void dump_results(int effective_fft_size); + void dump_results(int32_t effective_fft_size); + + float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step); + float max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, float input_power, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step); Acq_Conf acq_parameters; bool d_active; bool d_worker_active; bool d_cshort; bool d_step_two; - int d_positive_acq; + bool d_use_CFAR_algorithm_flag; + int32_t d_positive_acq; float d_threshold; float d_mag; float d_input_power; float d_test_statistics; float* d_magnitude; - long d_old_freq; - int d_state; - unsigned int d_channel; - unsigned int d_doppler_step; + float** d_magnitude_grid; + float* d_tmp_buffer; + gr_complex* d_input_signal; + uint32_t d_samplesPerChip; + int64_t d_old_freq; + int32_t d_state; + uint32_t d_channel; + uint32_t d_doppler_step; float d_doppler_center_step_two; - unsigned int d_well_count; - unsigned int d_fft_size; - unsigned int d_num_doppler_bins; - unsigned long int d_sample_counter; + uint32_t d_num_noncoherent_integrations_counter; + uint32_t d_fft_size; + uint32_t d_consumed_samples; + uint32_t d_num_doppler_bins; + uint64_t d_sample_counter; gr_complex** d_grid_doppler_wipeoffs; gr_complex** d_grid_doppler_wipeoffs_step_two; gr_complex* d_fft_codes; @@ -124,8 +133,13 @@ private: gr::fft::fft_complex* d_ifft; Gnss_Synchro* d_gnss_synchro; arma::fmat grid_; - long int d_dump_number; - unsigned int d_dump_channel; + arma::fmat narrow_grid_; + uint32_t d_num_doppler_bins_step2; + int64_t d_dump_number; + uint32_t d_dump_channel; + uint32_t d_buffer_count; + bool d_dump; + std::string d_dump_filename; public: ~pcps_acquisition(); @@ -144,13 +158,13 @@ public: /*! * \brief Returns the maximum peak of grid search. */ - inline unsigned int mag() const + inline uint32_t mag() const { return d_mag; } /*! - * \brief Initializes acquisition algorithm. + * \brief Initializes acquisition algorithm and reserves memory. */ void init(); @@ -176,13 +190,13 @@ public: * first available sample. * \param state - int=1 forces start of acquisition */ - void set_state(int state); + void set_state(int32_t state); /*! * \brief Set acquisition channel unique ID * \param channel - receiver channel. */ - inline void set_channel(unsigned int channel) + inline void set_channel(uint32_t channel) { gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler d_channel = channel; @@ -203,7 +217,7 @@ public: * \brief Set maximum Doppler grid search * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz]. */ - inline void set_doppler_max(unsigned int doppler_max) + inline void set_doppler_max(uint32_t doppler_max) { gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler acq_parameters.doppler_max = doppler_max; @@ -213,7 +227,7 @@ public: * \brief Set Doppler steps for the grid search * \param doppler_step - Frequency bin of the search grid [Hz]. */ - inline void set_doppler_step(unsigned int doppler_step) + inline void set_doppler_step(uint32_t doppler_step) { gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler d_doppler_step = doppler_step; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc index 629f53c75..894b6ef20 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc @@ -34,6 +34,8 @@ #include "gps_sdr_signal_processing.h" #include "control_message_factory.h" #include "GPS_L1_CA.h" +#include "gnss_sdr_create_directory.h" +#include #include #include #include @@ -59,14 +61,12 @@ pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(const Acq_Con { this->message_port_register_out(pmt::mp("events")); acq_parameters = conf_; - d_sample_counter = 0; // SAMPLE COUNTER + d_sample_counter = 0ULL; // SAMPLE COUNTER d_active = false; d_fs_in = conf_.fs_in; d_samples_per_ms = conf_.samples_per_ms; - d_sampled_ms = conf_.sampled_ms; d_config_doppler_max = conf_.doppler_max; - d_config_doppler_min = -conf_.doppler_max; - d_fft_size = d_sampled_ms * d_samples_per_ms; + d_fft_size = d_samples_per_ms; // HS Acquisition d_max_dwells = conf_.max_dwells; d_gnuradio_forecast_samples = d_fft_size; @@ -75,7 +75,7 @@ pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(const Acq_Con d_fft_codes = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_magnitude = static_cast(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); - d_10_ms_buffer = static_cast(volk_gnsssdr_malloc(10 * d_samples_per_ms * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_10_ms_buffer = static_cast(volk_gnsssdr_malloc(50 * d_samples_per_ms * sizeof(gr_complex), volk_gnsssdr_get_alignment())); // Direct FFT d_fft_if = new gr::fft::fft_complex(d_fft_size, true); @@ -87,6 +87,38 @@ pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(const Acq_Con d_dump = conf_.dump; d_dump_filename = conf_.dump_filename; + if (d_dump) + { + std::string dump_path; + // Get path + if (d_dump_filename.find_last_of("/") != std::string::npos) + { + std::string dump_filename_ = d_dump_filename.substr(d_dump_filename.find_last_of("/") + 1); + dump_path = d_dump_filename.substr(0, d_dump_filename.find_last_of("/")); + d_dump_filename = dump_filename_; + } + else + { + dump_path = std::string("."); + } + if (d_dump_filename.empty()) + { + d_dump_filename = "acquisition"; + } + // remove extension if any + if (d_dump_filename.substr(1).find_last_of(".") != std::string::npos) + { + d_dump_filename = d_dump_filename.substr(0, d_dump_filename.find_last_of(".")); + } + d_dump_filename = dump_path + boost::filesystem::path::preferred_separator + d_dump_filename; + // create directory + if (!gnss_sdr_create_directory(dump_path)) + { + std::cerr << "GNSS-SDR cannot create dump file for the Acquisition block. Wrong permissions?" << std::endl; + d_dump = false; + } + } + d_n_samples_in_buffer = 0; d_threshold = 0; d_num_doppler_points = 0; @@ -126,7 +158,7 @@ void pcps_acquisition_fine_doppler_cc::set_doppler_step(unsigned int doppler_ste d_doppler_step = doppler_step; // Create the search grid array - d_num_doppler_points = floor(std::abs(d_config_doppler_max - d_config_doppler_min) / d_doppler_step); + d_num_doppler_points = floor(std::abs(2 * d_config_doppler_max) / d_doppler_step); d_grid_data = new float *[d_num_doppler_points]; for (int i = 0; i < d_num_doppler_points; i++) @@ -182,10 +214,10 @@ void pcps_acquisition_fine_doppler_cc::init() d_gnss_synchro->Flag_valid_symbol_output = false; d_gnss_synchro->Flag_valid_pseudorange = false; d_gnss_synchro->Flag_valid_word = false; - + d_gnss_synchro->Acq_doppler_step = 0U; d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; d_state = 0; } @@ -222,7 +254,7 @@ void pcps_acquisition_fine_doppler_cc::update_carrier_wipeoff() d_grid_doppler_wipeoffs = new gr_complex *[d_num_doppler_points]; for (int doppler_index = 0; doppler_index < d_num_doppler_points; doppler_index++) { - doppler_hz = d_config_doppler_min + d_doppler_step * doppler_index; + doppler_hz = d_doppler_step * doppler_index - d_config_doppler_max; // doppler search steps // compute the carrier doppler wipe-off signal and store it phase_step_rad = static_cast(GPS_TWO_PI) * doppler_hz / static_cast(d_fs_in); @@ -295,8 +327,9 @@ double pcps_acquisition_fine_doppler_cc::compute_CAF() // 4- record the maximum peak and the associated synchronization parameters d_gnss_synchro->Acq_delay_samples = static_cast(index_time); - d_gnss_synchro->Acq_doppler_hz = static_cast(index_doppler * d_doppler_step + d_config_doppler_min); + d_gnss_synchro->Acq_doppler_hz = static_cast(index_doppler * d_doppler_step - d_config_doppler_max); d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; + d_gnss_synchro->Acq_doppler_step = d_doppler_step; return d_test_statistics; } @@ -333,6 +366,7 @@ int pcps_acquisition_fine_doppler_cc::compute_and_accumulate_grid(gr_vector_cons // doppler search steps // Perform the carrier wipe-off volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size); + // 3- Perform the FFT-based convolution (parallel time search) // Compute the FFT of the carrier wiped--off incoming signal d_fft_if->execute(); @@ -352,6 +386,14 @@ int pcps_acquisition_fine_doppler_cc::compute_and_accumulate_grid(gr_vector_cons volk_gnsssdr_free(p_tmp_vector); return d_fft_size; + //debug + // std::cout << "iff=["; + // for (int n = 0; n < d_fft_size; n++) + // { + // std::cout << std::real(d_ifft->get_outbuf()[n]) << "+" << std::imag(d_ifft->get_outbuf()[n]) << "i,"; + // } + // std::cout << "]\n"; + // getchar(); } @@ -440,7 +482,7 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler() // Called by gnuradio to enable drivers, etc for i/o devices. bool pcps_acquisition_fine_doppler_cc::start() { - d_sample_counter = 0; + d_sample_counter = 0ULL; return true; } @@ -454,7 +496,8 @@ void pcps_acquisition_fine_doppler_cc::set_state(int state) { d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_well_count = 0; d_test_statistics = 0.0; d_active = true; @@ -495,22 +538,25 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items, if (d_active == true) { reset_grid(); + d_n_samples_in_buffer = 0; d_state = 1; } if (!acq_parameters.blocking_on_standby) { - d_sample_counter += d_fft_size; // sample counter + d_sample_counter += static_cast(d_fft_size); // sample counter consume_each(d_fft_size); } break; case 1: // S1. ComputeGrid compute_and_accumulate_grid(input_items); + memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast(input_items[0]), d_fft_size * sizeof(gr_complex)); + d_n_samples_in_buffer += d_fft_size; d_well_count++; if (d_well_count >= d_max_dwells) { d_state = 2; } - d_sample_counter += d_fft_size; // sample counter + d_sample_counter += static_cast(d_fft_size); // sample counter consume_each(d_fft_size); break; case 2: // Compute test statistics and decide @@ -522,10 +568,9 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items, else { d_state = 5; //negative acquisition + d_n_samples_in_buffer = 0; } - d_n_samples_in_buffer = 0; - d_sample_counter += d_fft_size; // sample counter - consume_each(d_fft_size); + break; case 3: // Fine doppler estimation samples_remaining = 10 * d_samples_per_ms - d_n_samples_in_buffer; @@ -534,15 +579,19 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items, { memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast(input_items[0]), noutput_items * sizeof(gr_complex)); d_n_samples_in_buffer += noutput_items; - d_sample_counter += noutput_items; // sample counter + d_sample_counter += static_cast(noutput_items); // sample counter consume_each(noutput_items); } else { - memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast(input_items[0]), samples_remaining * sizeof(gr_complex)); - estimate_Doppler(); //disabled in repo - d_sample_counter += samples_remaining; // sample counter - consume_each(samples_remaining); + if (samples_remaining > 0) + { + memcpy(&d_10_ms_buffer[d_n_samples_in_buffer], reinterpret_cast(input_items[0]), samples_remaining * sizeof(gr_complex)); + d_sample_counter += static_cast(samples_remaining); // sample counter + consume_each(samples_remaining); + } + estimate_Doppler(); //disabled in repo + d_n_samples_in_buffer = 0; d_state = 4; } break; @@ -566,7 +615,7 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items, d_state = 0; if (!acq_parameters.blocking_on_standby) { - d_sample_counter += noutput_items; // sample counter + d_sample_counter += static_cast(noutput_items); // sample counter consume_each(noutput_items); } break; @@ -590,7 +639,7 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items, d_state = 0; if (!acq_parameters.blocking_on_standby) { - d_sample_counter += noutput_items; // sample counter + d_sample_counter += static_cast(noutput_items); // sample counter consume_each(noutput_items); } break; @@ -598,7 +647,7 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items, d_state = 0; if (!acq_parameters.blocking_on_standby) { - d_sample_counter += noutput_items; // sample counter + d_sample_counter += static_cast(noutput_items); // sample counter consume_each(noutput_items); } break; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.h index 69a5ff2cc..6c34ad565 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.h @@ -94,13 +94,11 @@ private: float d_threshold; std::string d_satellite_str; int d_config_doppler_max; - int d_config_doppler_min; int d_num_doppler_points; int d_doppler_step; - unsigned int d_sampled_ms; unsigned int d_fft_size; - unsigned long int d_sample_counter; + uint64_t d_sample_counter; gr_complex* d_carrier; gr_complex* d_fft_codes; gr_complex* d_10_ms_buffer; @@ -126,8 +124,8 @@ private: std::string d_dump_filename; - arma::fmat grid_; - long int d_dump_number; + arma ::fmat grid_; + int64_t d_dump_number; unsigned int d_dump_channel; public: diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc index 9f916c7d7..5e97a8ed5 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc @@ -15,7 +15,7 @@ * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -33,16 +33,19 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ -#include "pcps_acquisition_fpga.h" + #include #include +#include "pcps_acquisition_fpga.h" +#define AQ_DOWNSAMPLING_DELAY 40 // delay due to the downsampling filter in the acquisition + using google::LogMessage; pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_) @@ -55,41 +58,67 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_) : gr::block( gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) { + // printf("acq constructor start\n"); this->message_port_register_out(pmt::mp("events")); acq_parameters = conf_; - d_sample_counter = 0; // SAMPLE COUNTER + d_sample_counter = 0ULL; // SAMPLE COUNTER d_active = false; d_state = 0; - d_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms; + //d_fft_size = acq_parameters.sampled_ms * acq_parameters.samples_per_ms; + d_fft_size = acq_parameters.samples_per_code; d_mag = 0; d_input_power = 0.0; - d_num_doppler_bins = 0; + d_num_doppler_bins = 0U; d_threshold = 0.0; - d_doppler_step = 0; + d_doppler_step = 0U; d_test_statistics = 0.0; - d_channel = 0; + d_channel = 0U; d_gnss_synchro = 0; - acquisition_fpga = std::make_shared(acq_parameters.device_name, d_fft_size, acq_parameters.doppler_max, acq_parameters.samples_per_ms, + //printf("zzzz acq_parameters.code_length = %d\n", acq_parameters.code_length); + //printf("zzzz acq_parameters.samples_per_ms = %d\n", acq_parameters.samples_per_ms); + //printf("zzzz d_fft_size = %d\n", d_fft_size); + + // this one works we don't know why + // acquisition_fpga = std::make_shared + // (acq_parameters.device_name, acq_parameters.code_length, acq_parameters.doppler_max, acq_parameters.samples_per_ms, + // acq_parameters.fs_in, acq_parameters.freq, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes); + + // this one is the one it should be but it doesn't work + acquisition_fpga = std::make_shared(acq_parameters.device_name, acq_parameters.code_length, acq_parameters.doppler_max, d_fft_size, acq_parameters.fs_in, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes); + + // acquisition_fpga = std::make_shared + // (acq_parameters.device_name, acq_parameters.samples_per_code, acq_parameters.doppler_max, acq_parameters.samples_per_code, + // acq_parameters.fs_in, acq_parameters.freq, acq_parameters.sampled_ms, acq_parameters.select_queue_Fpga, acq_parameters.all_fft_codes); + + // debug + //debug_d_max_absolute = 0.0; + //debug_d_input_power_absolute = 0.0; + // printf("acq constructor end\n"); } pcps_acquisition_fpga::~pcps_acquisition_fpga() { + // printf("acq destructor start\n"); acquisition_fpga->free(); + // printf("acq destructor end\n"); } void pcps_acquisition_fpga::set_local_code() { + // printf("acq set local code start\n"); acquisition_fpga->set_local_code(d_gnss_synchro->PRN); + // printf("acq set local code end\n"); } void pcps_acquisition_fpga::init() { + // printf("acq init start\n"); d_gnss_synchro->Flag_valid_acquisition = false; d_gnss_synchro->Flag_valid_symbol_output = false; d_gnss_synchro->Flag_valid_pseudorange = false; @@ -99,14 +128,16 @@ void pcps_acquisition_fpga::init() d_gnss_synchro->Acq_samplestamp_samples = 0; d_mag = 0.0; d_input_power = 0.0; - d_num_doppler_bins = static_cast(std::ceil(static_cast(static_cast(acq_parameters.doppler_max) - static_cast(-acq_parameters.doppler_max)) / static_cast(d_doppler_step))); + d_num_doppler_bins = static_cast(std::ceil(static_cast(static_cast(acq_parameters.doppler_max) - static_cast(-acq_parameters.doppler_max)) / static_cast(d_doppler_step))); acquisition_fpga->init(); + // printf("acq init end\n"); } -void pcps_acquisition_fpga::set_state(int state) +void pcps_acquisition_fpga::set_state(int32_t state) { + // printf("acq set state start\n"); d_state = state; if (d_state == 1) { @@ -126,11 +157,13 @@ void pcps_acquisition_fpga::set_state(int state) { LOG(ERROR) << "State can only be set to 0 or 1"; } + // printf("acq set state end\n"); } void pcps_acquisition_fpga::send_positive_acquisition() { + // printf("acq send positive acquisition start\n"); // 6.1- Declare positive acquisition using a message port //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL DLOG(INFO) << "positive acquisition" @@ -144,11 +177,13 @@ void pcps_acquisition_fpga::send_positive_acquisition() << ", input signal power " << d_input_power; this->message_port_pub(pmt::mp("events"), pmt::from_long(1)); + // printf("acq send positive acquisition end\n"); } void pcps_acquisition_fpga::send_negative_acquisition() { + // printf("acq send negative acquisition start\n"); // 6.2- Declare negative acquisition using a message port //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL DLOG(INFO) << "negative acquisition" @@ -162,16 +197,19 @@ void pcps_acquisition_fpga::send_negative_acquisition() << ", input signal power " << d_input_power; this->message_port_pub(pmt::mp("events"), pmt::from_long(2)); + // printf("acq send negative acquisition end\n"); } void pcps_acquisition_fpga::set_active(bool active) { + // printf("acq set active start\n"); d_active = active; // initialize acquisition algorithm - uint32_t indext = 0; + uint32_t indext = 0U; float magt = 0.0; + float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); d_input_power = 0.0; d_mag = 0.0; @@ -184,24 +222,32 @@ void pcps_acquisition_fpga::set_active(bool active) // no CFAR algorithm in the FPGA << ", use_CFAR_algorithm_flag: false"; - unsigned int initial_sample; + uint64_t initial_sample; float input_power_all = 0.0; float input_power_computed = 0.0; + + float temp_d_input_power; + + // loop through acquisition + /* for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) { // doppler search steps - int doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * doppler_index; + int32_t doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * doppler_index; - acquisition_fpga->set_phase_step(doppler_index); - acquisition_fpga->run_acquisition(); // runs acquisition and waits until it is finished + //acquisition_fpga->set_phase_step(doppler_index); + acquisition_fpga->set_doppler_sweep_debug(1, doppler_index); + acquisition_fpga->run_acquisition(); // runs acquisition and waits until it is finished acquisition_fpga->read_acquisition_results(&indext, &magt, - &initial_sample, &d_input_power); + &initial_sample, &d_input_power, &d_doppler_index); d_sample_counter = initial_sample; if (d_mag < magt) { d_mag = magt; + temp_d_input_power = d_input_power; + input_power_all = d_input_power / (d_fft_size - 1); input_power_computed = (d_input_power - d_mag) / (d_fft_size - 1); d_input_power = (d_input_power - d_mag) / (d_fft_size - 1); @@ -210,16 +256,79 @@ void pcps_acquisition_fpga::set_active(bool active) d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; - d_test_statistics = (d_mag / d_input_power); //* correction_factor; + d_test_statistics = (d_mag / d_input_power); //* correction_factor; } // In the case of the FPGA the option of dumping the results of the acquisition to a file is not available // because the IFFT vector is not available } +*/ + + // debug + //acquisition_fpga->block_samples(); + + // run loop in hw + //printf("LAUNCH ACQ\n"); + acquisition_fpga->set_doppler_sweep(d_num_doppler_bins); + acquisition_fpga->run_acquisition(); + acquisition_fpga->read_acquisition_results(&indext, &magt, + &initial_sample, &d_input_power, &d_doppler_index); + //printf("READ ACQ RESULTS\n"); + + // debug + //acquisition_fpga->unblock_samples(); + + d_mag = magt; + + + // debug + debug_d_max_absolute = magt; + debug_d_input_power_absolute = d_input_power; + debug_indext = indext; + debug_doppler_index = d_doppler_index; + + // temp_d_input_power = d_input_power; + + d_input_power = (d_input_power - d_mag) / (d_fft_size - 1); + int32_t doppler = -static_cast(acq_parameters.doppler_max) + d_doppler_step * d_doppler_index; + //d_gnss_synchro->Acq_delay_samples = static_cast(2*(indext % (2*acq_parameters.samples_per_code))); + d_gnss_synchro->Acq_delay_samples = static_cast(indext % acq_parameters.samples_per_code); + d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); + d_sample_counter = initial_sample; + //d_gnss_synchro->Acq_samplestamp_samples = 2*d_sample_counter - 81; // delay due to the downsampling filter in the acquisition + //d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter - 40; // delay due to the downsampling filter in the acquisition + d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; // delay due to the downsampling filter in the acquisition + d_test_statistics = (d_mag / d_input_power); //* correction_factor; + + // debug + // if (d_gnss_synchro->Acq_delay_samples > acq_parameters.code_length) + // { + // printf("d_gnss_synchro->Acq_samplestamp_samples = %d\n", d_gnss_synchro->Acq_samplestamp_samples); + // printf("d_gnss_synchro->Acq_delay_samples = %f\n", d_gnss_synchro->Acq_delay_samples); + // } + + // if (temp_d_input_power > debug_d_input_power_absolute) + // { + // debug_d_max_absolute = d_mag; + // debug_d_input_power_absolute = temp_d_input_power; + // } + // printf ("max debug_d_max_absolute = %f\n", debug_d_max_absolute); + // printf ("debug_d_input_power_absolute = %f\n", debug_d_input_power_absolute); + + // printf("&&&&& d_test_statistics = %f\n", d_test_statistics); + // printf("&&&&& debug_d_max_absolute =%f\n",debug_d_max_absolute); + // printf("&&&&& debug_d_input_power_absolute =%f\n",debug_d_input_power_absolute); + // printf("&&&&& debug_indext = %d\n",debug_indext); + // printf("&&&&& debug_doppler_index = %d\n",debug_doppler_index); if (d_test_statistics > d_threshold) { d_active = false; + // printf("##### d_test_statistics = %f\n", d_test_statistics); + // printf("##### debug_d_max_absolute =%f\n",debug_d_max_absolute); + // printf("##### debug_d_input_power_absolute =%f\n",debug_d_input_power_absolute); + // printf("##### initial_sample = %llu\n",initial_sample); + // printf("##### debug_doppler_index = %d\n",debug_doppler_index); send_positive_acquisition(); d_state = 0; // Positive acquisition } @@ -229,12 +338,13 @@ void pcps_acquisition_fpga::set_active(bool active) d_active = false; send_negative_acquisition(); } + + // printf("acq set active end\n"); } int pcps_acquisition_fpga::general_work(int noutput_items __attribute__((unused)), - gr_vector_int& ninput_items __attribute__((unused)), - gr_vector_const_void_star& input_items __attribute__((unused)), + gr_vector_int& ninput_items, gr_vector_const_void_star& input_items, gr_vector_void_star& output_items __attribute__((unused))) { // the general work is not used with the acquisition that uses the FPGA diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h index 1ee9a773a..abf8f6b06 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h @@ -64,13 +64,13 @@ typedef struct { /* pcps acquisition configuration */ - unsigned int sampled_ms; - unsigned int doppler_max; - long freq; - long fs_in; - int samples_per_ms; - int samples_per_code; - unsigned int select_queue_Fpga; + uint32_t sampled_ms; + uint32_t doppler_max; + int64_t fs_in; + int32_t samples_per_ms; + int32_t samples_per_code; + int32_t code_length; + uint32_t select_queue_Fpga; std::string device_name; lv_16sc_t* all_fft_codes; // memory that contains all the code ffts @@ -107,16 +107,23 @@ private: float d_threshold; float d_mag; float d_input_power; + uint32_t d_doppler_index; float d_test_statistics; - int d_state; - unsigned int d_channel; - unsigned int d_doppler_step; - unsigned int d_fft_size; - unsigned int d_num_doppler_bins; - unsigned long int d_sample_counter; + int32_t d_state; + uint32_t d_channel; + uint32_t d_doppler_step; + uint32_t d_fft_size; + uint32_t d_num_doppler_bins; + uint64_t d_sample_counter; Gnss_Synchro* d_gnss_synchro; std::shared_ptr acquisition_fpga; + // debug + float debug_d_max_absolute; + float debug_d_input_power_absolute; + int32_t debug_indext; + int32_t debug_doppler_index; + public: ~pcps_acquisition_fpga(); @@ -127,15 +134,19 @@ public: */ inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) { + // printf("acq set gnss synchro start\n"); d_gnss_synchro = p_gnss_synchro; + // printf("acq set gnss synchro end\n"); } /*! * \brief Returns the maximum peak of grid search. */ - inline unsigned int mag() const + inline uint32_t mag() const { + // printf("acq dmag start\n"); return d_mag; + // printf("acq dmag end\n"); } /*! @@ -154,7 +165,7 @@ public: * first available sample. * \param state - int=1 forces start of acquisition */ - void set_state(int state); + void set_state(int32_t state); /*! * \brief Starts acquisition algorithm, turning from standby mode to @@ -167,7 +178,7 @@ public: * \brief Set acquisition channel unique ID * \param channel - receiver channel. */ - inline void set_channel(unsigned int channel) + inline void set_channel(uint32_t channel) { d_channel = channel; } @@ -179,27 +190,33 @@ public: */ inline void set_threshold(float threshold) { + // printf("acq set threshold start\n"); d_threshold = threshold; + // printf("acq set threshold end\n"); } /*! * \brief Set maximum Doppler grid search * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz]. */ - inline void set_doppler_max(unsigned int doppler_max) + inline void set_doppler_max(uint32_t doppler_max) { + // printf("acq set doppler max start\n"); acq_parameters.doppler_max = doppler_max; acquisition_fpga->set_doppler_max(doppler_max); + // printf("acq set doppler max end\n"); } /*! * \brief Set Doppler steps for the grid search * \param doppler_step - Frequency bin of the search grid [Hz]. */ - inline void set_doppler_step(unsigned int doppler_step) + inline void set_doppler_step(uint32_t doppler_step) { + // printf("acq set doppler step start\n"); d_doppler_step = doppler_step; acquisition_fpga->set_doppler_step(doppler_step); + // printf("acq set doppler step end\n"); } /*! diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.cc index 002d18138..31c28c319 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.cc @@ -64,7 +64,7 @@ pcps_assisted_acquisition_cc::pcps_assisted_acquisition_cc( gr::io_signature::make(0, 0, sizeof(gr_complex))) { this->message_port_register_out(pmt::mp("events")); - d_sample_counter = 0; // SAMPLE COUNTER + d_sample_counter = 0ULL; // SAMPLE COUNTER d_active = false; d_fs_in = fs_in; d_samples_per_ms = samples_per_ms; @@ -150,10 +150,10 @@ void pcps_assisted_acquisition_cc::init() d_gnss_synchro->Flag_valid_symbol_output = false; d_gnss_synchro->Flag_valid_pseudorange = false; d_gnss_synchro->Flag_valid_word = false; - + d_gnss_synchro->Acq_doppler_step = 0U; d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; d_input_power = 0.0; d_state = 0; @@ -279,6 +279,7 @@ double pcps_assisted_acquisition_cc::search_maximum() d_gnss_synchro->Acq_delay_samples = static_cast(index_time); d_gnss_synchro->Acq_doppler_hz = static_cast(index_doppler * d_doppler_step + d_doppler_min); d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; + d_gnss_synchro->Acq_doppler_step = d_doppler_step; // Record results to file if required if (d_dump) @@ -380,14 +381,14 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items, { case 0: // S0. StandBy if (d_active == true) d_state = 1; - d_sample_counter += ninput_items[0]; // sample counter + d_sample_counter += static_cast(ninput_items[0]); // sample counter consume_each(ninput_items[0]); break; case 1: // S1. GetAssist get_assistance(); redefine_grid(); reset_grid(); - d_sample_counter += ninput_items[0]; // sample counter + d_sample_counter += static_cast(ninput_items[0]); // sample counter consume_each(ninput_items[0]); d_state = 2; break; @@ -399,7 +400,7 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items, { d_state = 3; } - d_sample_counter += consumed_samples; + d_sample_counter += static_cast(consumed_samples); consume_each(consumed_samples); break; case 3: // Compute test statistics and decide @@ -422,14 +423,14 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items, d_state = 6; } } - d_sample_counter += ninput_items[0]; // sample counter + d_sample_counter += static_cast(ninput_items[0]); // sample counter consume_each(ninput_items[0]); break; case 4: // RedefineGrid free_grid_memory(); redefine_grid(); reset_grid(); - d_sample_counter += ninput_items[0]; // sample counter + d_sample_counter += static_cast(ninput_items[0]); // sample counter consume_each(ninput_items[0]); d_state = 2; break; @@ -447,7 +448,7 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items, this->message_port_pub(pmt::mp("events"), pmt::from_long(1)); free_grid_memory(); // consume samples to not block the GNU Radio flowgraph - d_sample_counter += ninput_items[0]; // sample counter + d_sample_counter += static_cast(ninput_items[0]); // sample counter consume_each(ninput_items[0]); d_state = 0; break; @@ -465,7 +466,7 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items, this->message_port_pub(pmt::mp("events"), pmt::from_long(2)); free_grid_memory(); // consume samples to not block the GNU Radio flowgraph - d_sample_counter += ninput_items[0]; // sample counter + d_sample_counter += static_cast(ninput_items[0]); // sample counter consume_each(ninput_items[0]); d_state = 0; break; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.h index 932cd05e0..70b73f715 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.h @@ -112,7 +112,7 @@ private: int d_doppler_step; unsigned int d_sampled_ms; unsigned int d_fft_size; - unsigned long int d_sample_counter; + uint64_t d_sample_counter; gr_complex* d_carrier; gr_complex* d_fft_codes; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc index d5f9df83b..34228b89b 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc @@ -67,7 +67,7 @@ pcps_cccwsr_acquisition_cc::pcps_cccwsr_acquisition_cc( gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms)) { this->message_port_register_out(pmt::mp("events")); - d_sample_counter = 0; // SAMPLE COUNTER + d_sample_counter = 0ULL; // SAMPLE COUNTER d_active = false; d_state = 0; d_fs_in = fs_in; @@ -165,10 +165,10 @@ void pcps_cccwsr_acquisition_cc::init() d_gnss_synchro->Flag_valid_symbol_output = false; d_gnss_synchro->Flag_valid_pseudorange = false; d_gnss_synchro->Flag_valid_word = false; - + d_gnss_synchro->Acq_doppler_step = 0U; d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; d_mag = 0.0; d_input_power = 0.0; @@ -203,7 +203,8 @@ void pcps_cccwsr_acquisition_cc::set_state(int state) { d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; @@ -234,7 +235,8 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items, //restart acquisition variables d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; @@ -243,7 +245,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items, d_state = 1; } - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter consume_each(ninput_items[0]); break; @@ -262,7 +264,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items, const gr_complex *in = reinterpret_cast(input_items[0]); //Get the input samples pointer float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); - d_sample_counter += d_fft_size; // sample counter + d_sample_counter += static_cast(d_fft_size); // sample counter d_well_count++; @@ -354,6 +356,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items, d_gnss_synchro->Acq_delay_samples = static_cast(indext % d_samples_per_code); d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; + d_gnss_synchro->Acq_doppler_step = d_doppler_step; } // Record results to file if required @@ -406,7 +409,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter consume_each(ninput_items[0]); acquisition_message = 1; @@ -431,7 +434,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter consume_each(ninput_items[0]); acquisition_message = 2; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.h index 56a5f6050..00348daa9 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.h @@ -88,7 +88,7 @@ private: unsigned int d_max_dwells; unsigned int d_well_count; unsigned int d_fft_size; - unsigned long int d_sample_counter; + uint64_t d_sample_counter; gr_complex** d_grid_doppler_wipeoffs; unsigned int d_num_doppler_bins; gr_complex* d_fft_code_data; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc index 0f90c2c38..aa8bceffb 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc @@ -93,7 +93,7 @@ pcps_opencl_acquisition_cc::pcps_opencl_acquisition_cc( gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms)) { this->message_port_register_out(pmt::mp("events")); - d_sample_counter = 0; // SAMPLE COUNTER + d_sample_counter = 0ULL; // SAMPLE COUNTER d_active = false; d_state = 0; d_core_working = false; @@ -290,10 +290,10 @@ void pcps_opencl_acquisition_cc::init() d_gnss_synchro->Flag_valid_symbol_output = false; d_gnss_synchro->Flag_valid_pseudorange = false; d_gnss_synchro->Flag_valid_word = false; - + d_gnss_synchro->Acq_doppler_step = 0U; d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; d_mag = 0.0; d_input_power = 0.0; @@ -387,7 +387,7 @@ void pcps_opencl_acquisition_cc::acquisition_core_volk() float magt = 0.0; float fft_normalization_factor = static_cast(d_fft_size) * static_cast(d_fft_size); gr_complex *in = d_in_buffer[d_well_count]; - unsigned long int samplestamp = d_sample_counter_buffer[d_well_count]; + uint64_t samplestamp = d_sample_counter_buffer[d_well_count]; d_input_power = 0.0; d_mag = 0.0; @@ -450,6 +450,7 @@ void pcps_opencl_acquisition_cc::acquisition_core_volk() d_gnss_synchro->Acq_delay_samples = static_cast(indext % d_samples_per_code); d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = samplestamp; + d_gnss_synchro->Acq_doppler_step = d_doppler_step; // 5- Compute the test statistics and compare to the threshold //d_test_statistics = 2 * d_fft_size * d_mag / d_input_power; @@ -510,7 +511,7 @@ void pcps_opencl_acquisition_cc::acquisition_core_opencl() float magt = 0.0; float fft_normalization_factor = (static_cast(d_fft_size_pow2) * static_cast(d_fft_size)); //This works, but I am not sure why. gr_complex *in = d_in_buffer[d_well_count]; - unsigned long int samplestamp = d_sample_counter_buffer[d_well_count]; + uint64_t samplestamp = d_sample_counter_buffer[d_well_count]; d_input_power = 0.0; d_mag = 0.0; @@ -613,6 +614,7 @@ void pcps_opencl_acquisition_cc::acquisition_core_opencl() d_gnss_synchro->Acq_delay_samples = static_cast(indext % d_samples_per_code); d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = samplestamp; + d_gnss_synchro->Acq_doppler_step = d_doppler_step; // 5- Compute the test statistics and compare to the threshold //d_test_statistics = 2 * d_fft_size * d_mag / d_input_power; @@ -676,7 +678,8 @@ void pcps_opencl_acquisition_cc::set_state(int state) { d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; @@ -708,7 +711,8 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items, //restart acquisition variables d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; @@ -719,7 +723,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items, d_state = 1; } - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter break; } @@ -736,20 +740,20 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items, { memcpy(d_in_buffer[d_in_dwell_count++], static_cast(input_items[i]), sizeof(gr_complex) * d_fft_size); - d_sample_counter += d_fft_size; + d_sample_counter += static_cast(d_fft_size); d_sample_counter_buffer.push_back(d_sample_counter); } if (ninput_items[0] > static_cast(num_dwells)) { - d_sample_counter += d_fft_size * (ninput_items[0] - num_dwells); + d_sample_counter += static_cast(d_fft_size * (ninput_items[0] - num_dwells)); } } else { // We already have d_max_dwells consecutive blocks in the internal buffer, // just skip input blocks. - d_sample_counter += d_fft_size * ninput_items[0]; + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); } // We create a new thread to process next block if the following @@ -793,7 +797,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter acquisition_message = 1; this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message)); @@ -817,7 +821,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter acquisition_message = 2; this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message)); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.h index e70a8d342..df6947f47 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.h @@ -121,7 +121,7 @@ private: unsigned int d_fft_size; unsigned int d_fft_size_pow2; int* d_max_doppler_indexs; - unsigned long int d_sample_counter; + uint64_t d_sample_counter; gr_complex** d_grid_doppler_wipeoffs; unsigned int d_num_doppler_bins; gr_complex* d_fft_codes; @@ -144,7 +144,7 @@ private: std::string d_dump_filename; gr_complex* d_zero_vector; gr_complex** d_in_buffer; - std::vector d_sample_counter_buffer; + std::vector d_sample_counter_buffer; unsigned int d_in_dwell_count; cl::Platform d_cl_platform; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc index d3b22d41e..06a91dccb 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc @@ -73,7 +73,7 @@ pcps_quicksync_acquisition_cc::pcps_quicksync_acquisition_cc( gr::io_signature::make(0, 0, (sizeof(gr_complex) * sampled_ms * samples_per_ms))) { this->message_port_register_out(pmt::mp("events")); - d_sample_counter = 0; // SAMPLE COUNTER + d_sample_counter = 0ULL; // SAMPLE COUNTER d_active = false; d_state = 0; d_fs_in = fs_in; @@ -199,7 +199,8 @@ void pcps_quicksync_acquisition_cc::init() //DLOG(INFO) << "START init"; d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_mag = 0.0; d_input_power = 0.0; @@ -236,7 +237,8 @@ void pcps_quicksync_acquisition_cc::set_state(int state) { d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; @@ -279,7 +281,8 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, //restart acquisition variables d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_well_count = 0; d_mag = 0.0; d_input_power = 0.0; @@ -288,7 +291,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, d_state = 1; } - d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter consume_each(ninput_items[0]); //DLOG(INFO) << "END CASE 0"; break; @@ -324,7 +327,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, d_test_statistics = 0.0; d_noise_floor_power = 0.0; - d_sample_counter += d_sampled_ms * d_samples_per_ms; // sample counter + d_sample_counter += static_cast(d_sampled_ms * d_samples_per_ms); // sample counter d_well_count++; @@ -456,6 +459,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, d_gnss_synchro->Acq_delay_samples = static_cast(d_possible_delay[indext]); d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; + d_gnss_synchro->Acq_doppler_step = d_doppler_step; /* 5- Compute the test statistics and compare to the threshold d_test_statistics = 2 * d_fft_size * d_mag / d_input_power;*/ d_test_statistics = d_mag / d_input_power; @@ -536,7 +540,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter consume_each(ninput_items[0]); acquisition_message = 1; @@ -565,7 +569,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter consume_each(ninput_items[0]); acquisition_message = 2; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.h index 8310b90ad..56f363dbf 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.h @@ -127,7 +127,7 @@ private: unsigned int d_max_dwells; unsigned int d_well_count; unsigned int d_fft_size; - unsigned long int d_sample_counter; + uint64_t d_sample_counter; gr_complex** d_grid_doppler_wipeoffs; unsigned int d_num_doppler_bins; gr_complex* d_fft_codes; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc index 9627b2733..77a714de4 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc @@ -82,7 +82,7 @@ pcps_tong_acquisition_cc::pcps_tong_acquisition_cc( gr::io_signature::make(0, 0, sizeof(gr_complex) * sampled_ms * samples_per_ms)) { this->message_port_register_out(pmt::mp("events")); - d_sample_counter = 0; // SAMPLE COUNTER + d_sample_counter = 0ULL; // SAMPLE COUNTER d_active = false; d_state = 0; d_fs_in = fs_in; @@ -166,10 +166,10 @@ void pcps_tong_acquisition_cc::init() d_gnss_synchro->Flag_valid_symbol_output = false; d_gnss_synchro->Flag_valid_pseudorange = false; d_gnss_synchro->Flag_valid_word = false; - + d_gnss_synchro->Acq_doppler_step = 0U; d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; d_mag = 0.0; d_input_power = 0.0; @@ -211,7 +211,8 @@ void pcps_tong_acquisition_cc::set_state(int state) { d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_dwell_count = 0; d_tong_count = d_tong_init_val; d_mag = 0.0; @@ -250,7 +251,8 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items, //restart acquisition variables d_gnss_synchro->Acq_delay_samples = 0.0; d_gnss_synchro->Acq_doppler_hz = 0.0; - d_gnss_synchro->Acq_samplestamp_samples = 0; + d_gnss_synchro->Acq_samplestamp_samples = 0ULL; + d_gnss_synchro->Acq_doppler_step = 0U; d_dwell_count = 0; d_tong_count = d_tong_init_val; d_mag = 0.0; @@ -268,7 +270,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items, d_state = 1; } - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter consume_each(ninput_items[0]); break; @@ -285,7 +287,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items, d_input_power = 0.0; d_mag = 0.0; - d_sample_counter += d_fft_size; // sample counter + d_sample_counter += static_cast(d_fft_size); // sample counter d_dwell_count++; @@ -345,6 +347,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items, d_gnss_synchro->Acq_delay_samples = static_cast(indext % d_samples_per_code); d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; + d_gnss_synchro->Acq_doppler_step = d_doppler_step; } // Record results to file if required @@ -407,7 +410,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter consume_each(ninput_items[0]); acquisition_message = 1; @@ -432,7 +435,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter consume_each(ninput_items[0]); acquisition_message = 2; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.h index dc231fac0..7508fb42c 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.h @@ -108,7 +108,7 @@ private: unsigned int d_tong_max_val; unsigned int d_tong_max_dwells; unsigned int d_fft_size; - unsigned long int d_sample_counter; + uint64_t d_sample_counter; gr_complex** d_grid_doppler_wipeoffs; unsigned int d_num_doppler_bins; gr_complex* d_fft_codes; diff --git a/src/algorithms/acquisition/libs/CMakeLists.txt b/src/algorithms/acquisition/libs/CMakeLists.txt index 05a116e0f..c3f368be6 100644 --- a/src/algorithms/acquisition/libs/CMakeLists.txt +++ b/src/algorithms/acquisition/libs/CMakeLists.txt @@ -17,32 +17,42 @@ # if(ENABLE_FPGA) - set(ACQUISITION_LIB_SOURCES fpga_acquisition.cc ) - include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${VOLK_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${VOLK_GNSSSDR_INCLUDE_DIRS} - ) - - file(GLOB ACQUISITION_LIB_HEADERS "*.h") -endif(ENABLE_FPGA) + set(ACQUISITION_LIB_SOURCES fpga_acquisition.cc) + set(ACQUISITION_LIB_HEADERS fpga_acquisition.h) + include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${VOLK_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${VOLK_GNSSSDR_INCLUDE_DIRS} + ) +endif() set(ACQUISITION_LIB_HEADERS ${ACQUISITION_LIB_HEADERS} acq_conf.h) -list(SORT ACQUISITION_LIB_HEADERS) - set(ACQUISITION_LIB_SOURCES ${ACQUISITION_LIB_SOURCES} acq_conf.cc) -add_library(acquisition_lib ${ACQUISITION_LIB_SOURCES} ${ACQUISITION_LIB_HEADERS}) +list(SORT ACQUISITION_LIB_HEADERS) +list(SORT ACQUISITION_LIB_SOURCES) + +add_library(acquisition_lib + ${ACQUISITION_LIB_SOURCES} + ${ACQUISITION_LIB_HEADERS} +) + source_group(Headers FILES ${ACQUISITION_LIB_HEADERS}) -target_link_libraries(acquisition_lib ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES}) -if(VOLK_GNSSSDR_FOUND) + +target_link_libraries(acquisition_lib + ${VOLK_LIBRARIES} + ${VOLK_GNSSSDR_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} +) + +if(VOLKGNSSSDR_FOUND) add_dependencies(acquisition_lib glog-${glog_RELEASE}) -else(VOLK_GNSSSDR_FOUND) +else() add_dependencies(acquisition_lib glog-${glog_RELEASE} volk_gnsssdr_module) endif() diff --git a/src/algorithms/acquisition/libs/acq_conf.cc b/src/algorithms/acquisition/libs/acq_conf.cc index ed79db2fa..e98bf3bdf 100644 --- a/src/algorithms/acquisition/libs/acq_conf.cc +++ b/src/algorithms/acquisition/libs/acq_conf.cc @@ -34,21 +34,23 @@ Acq_Conf::Acq_Conf() { /* PCPS acquisition configuration */ - sampled_ms = 0; - max_dwells = 0; - doppler_max = 0; - num_doppler_bins_step2 = 0; + sampled_ms = 0U; + ms_per_code = 0U; + max_dwells = 0U; + samples_per_chip = 0U; + doppler_max = 0U; + num_doppler_bins_step2 = 0U; doppler_step2 = 0.0; - fs_in = 0; - samples_per_ms = 0; - samples_per_code = 0; + fs_in = 0LL; + samples_per_ms = 0.0; + samples_per_code = 0.0; bit_transition_flag = false; use_CFAR_algorithm_flag = false; dump = false; blocking = false; make_2_steps = false; dump_filename = ""; - dump_channel = 0; + dump_channel = 0U; it_size = sizeof(char); blocking_on_standby = false; } diff --git a/src/algorithms/acquisition/libs/acq_conf.h b/src/algorithms/acquisition/libs/acq_conf.h index 4707aeba7..445fab878 100644 --- a/src/algorithms/acquisition/libs/acq_conf.h +++ b/src/algorithms/acquisition/libs/acq_conf.h @@ -33,20 +33,23 @@ #define GNSS_SDR_ACQ_CONF_H_ #include +#include #include class Acq_Conf { public: /* PCPS Acquisition configuration */ - unsigned int sampled_ms; - unsigned int max_dwells; - unsigned int doppler_max; - unsigned int num_doppler_bins_step2; + uint32_t sampled_ms; + uint32_t ms_per_code; + uint32_t samples_per_chip; + uint32_t max_dwells; + uint32_t doppler_max; + uint32_t num_doppler_bins_step2; float doppler_step2; - long fs_in; - int samples_per_ms; - int samples_per_code; + int64_t fs_in; + float samples_per_ms; + float samples_per_code; bool bit_transition_flag; bool use_CFAR_algorithm_flag; bool dump; @@ -54,7 +57,7 @@ public: bool blocking_on_standby; // enable it only for unit testing to avoid sample consume on idle status bool make_2_steps; std::string dump_filename; - unsigned int dump_channel; + uint32_t dump_channel; size_t it_size; Acq_Conf(); diff --git a/src/algorithms/acquisition/libs/fpga_acquisition.cc b/src/algorithms/acquisition/libs/fpga_acquisition.cc index bf2f91c24..57e2a6ba2 100644 --- a/src/algorithms/acquisition/libs/fpga_acquisition.cc +++ b/src/algorithms/acquisition/libs/fpga_acquisition.cc @@ -37,6 +37,7 @@ #include "GPS_L1_CA.h" #include "gps_sdr_signal_processing.h" #include +#include #include // libraries used by the GIPO #include // libraries used by the GIPO @@ -55,6 +56,17 @@ #define SELECT_16_BITS 0xFFFF // value to select 16 bits #define SHL_8_BITS 256 // value used to shift a value 8 bits to the left +// 12-bits +//#define SELECT_LSBits 0x0FFF +//#define SELECT_MSBbits 0x00FFF000 +//#define SELECT_24_BITS 0x00FFFFFF +//#define SHL_12_BITS 4096 +// 16-bits +#define SELECT_LSBits 0x0FFFF +#define SELECT_MSBbits 0xFFFF0000 +#define SELECT_32_BITS 0xFFFFFFFF +#define SHL_16_BITS 65536 + bool fpga_acquisition::init() { @@ -64,25 +76,34 @@ bool fpga_acquisition::init() } -bool fpga_acquisition::set_local_code(unsigned int PRN) +bool fpga_acquisition::set_local_code(uint32_t PRN) { // select the code with the chosen PRN fpga_acquisition::fpga_configure_acquisition_local_code( &d_all_fft_codes[d_nsamples_total * (PRN - 1)]); + + //fpga_acquisition::fpga_configure_acquisition_local_code( + // &d_all_fft_codes[0]); + return true; } fpga_acquisition::fpga_acquisition(std::string device_name, - unsigned int nsamples, - unsigned int doppler_max, - unsigned int nsamples_total, long fs_in, - unsigned int sampled_ms, unsigned select_queue, + uint32_t nsamples, + uint32_t doppler_max, + uint32_t nsamples_total, int64_t fs_in, + uint32_t sampled_ms, uint32_t select_queue, lv_16sc_t *all_fft_codes) { - unsigned int vector_length = nsamples_total * sampled_ms; + //printf("AAA- sampled_ms = %d\n ", sampled_ms); + + uint32_t vector_length = nsamples_total; // * sampled_ms; + + //printf("AAA- vector_length = %d\n ", vector_length); // initial values d_device_name = device_name; + //d_freq = freq; d_fs_in = fs_in; d_vector_length = vector_length; d_nsamples = nsamples; // number of samples not including padding @@ -98,18 +119,20 @@ fpga_acquisition::fpga_acquisition(std::string device_name, if ((d_fd = open(d_device_name.c_str(), O_RDWR | O_SYNC)) == -1) { LOG(WARNING) << "Cannot open deviceio" << d_device_name; + std::cout << "Acq: cannot open deviceio" << d_device_name << std::endl; } - d_map_base = reinterpret_cast(mmap(NULL, PAGE_SIZE, + d_map_base = reinterpret_cast(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, d_fd, 0)); if (d_map_base == reinterpret_cast(-1)) { LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory"; + std::cout << "Acq: cannot map deviceio" << d_device_name << std::endl; } // sanity check : check test register - unsigned writeval = TEST_REG_SANITY_CHECK; - unsigned readval; + uint32_t writeval = TEST_REG_SANITY_CHECK; + uint32_t readval; readval = fpga_acquisition::fpga_acquisition_test_register(writeval); if (writeval != readval) { @@ -118,6 +141,7 @@ fpga_acquisition::fpga_acquisition(std::string device_name, else { LOG(INFO) << "Acquisition test register sanity check success!"; + //std::cout << "Acquisition test register sanity check success!" << std::endl; } fpga_acquisition::reset_acquisition(); DLOG(INFO) << "Acquisition FPGA class created"; @@ -136,9 +160,9 @@ bool fpga_acquisition::free() } -unsigned fpga_acquisition::fpga_acquisition_test_register(unsigned writeval) +uint32_t fpga_acquisition::fpga_acquisition_test_register(uint32_t writeval) { - unsigned readval; + uint32_t readval; // write value to test register d_map_base[15] = writeval; // read value from test register @@ -150,35 +174,52 @@ unsigned fpga_acquisition::fpga_acquisition_test_register(unsigned writeval) void fpga_acquisition::fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]) { - unsigned short local_code; - unsigned int k, tmp, tmp2; - unsigned int fft_data; + uint32_t local_code; + uint32_t k, tmp, tmp2; + uint32_t fft_data; + // clear memory address counter - d_map_base[4] = LOCAL_CODE_CLEAR_MEM; + //d_map_base[6] = LOCAL_CODE_CLEAR_MEM; + d_map_base[9] = LOCAL_CODE_CLEAR_MEM; // write local code for (k = 0; k < d_vector_length; k++) { tmp = fft_local_code[k].real(); tmp2 = fft_local_code[k].imag(); - local_code = (tmp & SELECT_LSB) | ((tmp2 * SHL_8_BITS) & SELECT_MSB); // put together the real part and the imaginary part - fft_data = MEM_LOCAL_CODE_WR_ENABLE | (local_code & SELECT_16_BITS); - d_map_base[4] = fft_data; + //tmp = k; + //tmp2 = k; + + //local_code = (tmp & SELECT_LSB) | ((tmp2 * SHL_8_BITS) & SELECT_MSB); // put together the real part and the imaginary part + //fft_data = MEM_LOCAL_CODE_WR_ENABLE | (local_code & SELECT_16_BITS); + //local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_12_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part + local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_16_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part + //fft_data = MEM_LOCAL_CODE_WR_ENABLE | (local_code & SELECT_24_BITS); + fft_data = local_code & SELECT_32_BITS; + d_map_base[6] = fft_data; + + + //printf("debug local code %d real = %d imag = %d local_code = %d fft_data = %d\n", k, tmp, tmp2, local_code, fft_data); + //printf("debug local code %d real = 0x%08X imag = 0x%08X local_code = 0x%08X fft_data = 0x%08X\n", k, tmp, tmp2, local_code, fft_data); } + //printf("d_vector_length = %d\n", d_vector_length); + //while(1); } void fpga_acquisition::run_acquisition(void) { // enable interrupts - int reenable = 1; - write(d_fd, reinterpret_cast(&reenable), sizeof(int)); + int32_t reenable = 1; + write(d_fd, reinterpret_cast(&reenable), sizeof(int32_t)); // launch the acquisition process - d_map_base[6] = LAUNCH_ACQUISITION; // writing anything to reg 6 launches the acquisition process + //printf("launchin acquisition ...\n"); + d_map_base[8] = LAUNCH_ACQUISITION; // writing a 1 to reg 8 launches the acquisition process - int irq_count; + int32_t irq_count; ssize_t nb; // wait for interrupt nb = read(d_fd, &irq_count, sizeof(irq_count)); + //printf("interrupt received\n"); if (nb != sizeof(irq_count)) { printf("acquisition module Read failed to retrieve 4 bytes!\n"); @@ -187,22 +228,15 @@ void fpga_acquisition::run_acquisition(void) } -void fpga_acquisition::configure_acquisition() -{ - d_map_base[0] = d_select_queue; - d_map_base[1] = d_vector_length; - d_map_base[2] = d_nsamples; - d_map_base[5] = (int)log2((float)d_vector_length); // log2 FFTlength -} - - -void fpga_acquisition::set_phase_step(unsigned int doppler_index) +void fpga_acquisition::set_doppler_sweep(uint32_t num_sweeps) { float phase_step_rad_real; float phase_step_rad_int_temp; int32_t phase_step_rad_int; - int doppler = static_cast(-d_doppler_max) + d_doppler_step * doppler_index; - float phase_step_rad = GPS_TWO_PI * doppler / static_cast(d_fs_in); + //int32_t doppler = static_cast(-d_doppler_max) + d_doppler_step * doppler_index; + int32_t doppler = static_cast(-d_doppler_max); + //float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast(d_fs_in); + float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast(d_fs_in); // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) // The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x) @@ -210,28 +244,153 @@ void fpga_acquisition::set_phase_step(unsigned int doppler_index) phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); // avoid saturation of the fixed point representation in the fpga // (only the positive value can saturate due to the 2's complement representation) + + //printf("AAA phase_step_rad_real for initial doppler = %f\n", phase_step_rad_real); if (phase_step_rad_real >= 1.0) { phase_step_rad_real = MAX_PHASE_STEP_RAD; } - phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 - phase_step_rad_int = (int32_t)(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings + //printf("AAA phase_step_rad_real for initial doppler after checking = %f\n", phase_step_rad_real); + phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 + phase_step_rad_int = static_cast(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings + //printf("AAA writing phase_step_rad_int for initial doppler = %d to d map base 3\n", phase_step_rad_int); + d_map_base[3] = phase_step_rad_int; + + // repeat the calculation with the doppler step + doppler = static_cast(d_doppler_step); + phase_step_rad = GPS_TWO_PI * (doppler) / static_cast(d_fs_in); + phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); + //printf("AAA phase_step_rad_real for doppler step = %f\n", phase_step_rad_real); + if (phase_step_rad_real >= 1.0) + { + phase_step_rad_real = MAX_PHASE_STEP_RAD; + } + //printf("AAA phase_step_rad_real for doppler step after checking = %f\n", phase_step_rad_real); + phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 + phase_step_rad_int = static_cast(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings + //printf("AAA writing phase_step_rad_int for doppler step = %d to d map base 4\n", phase_step_rad_int); + d_map_base[4] = phase_step_rad_int; + //printf("AAA writing num sweeps to d map base 5 = %d\n", num_sweeps); + d_map_base[5] = num_sweeps; +} + +void fpga_acquisition::set_doppler_sweep_debug(uint32_t num_sweeps, uint32_t doppler_index) +{ + float phase_step_rad_real; + float phase_step_rad_int_temp; + int32_t phase_step_rad_int; + int32_t doppler = -static_cast(d_doppler_max) + d_doppler_step * doppler_index; + //int32_t doppler = static_cast(-d_doppler_max); + //float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast(d_fs_in); + float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast(d_fs_in); + // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing + // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) + // The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x) + // while the gnss-sdr software (volk_gnsssdr_s32f_sincos_32fc) generates cos(x) + j*sin(x) + phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); + // avoid saturation of the fixed point representation in the fpga + // (only the positive value can saturate due to the 2's complement representation) + + //printf("AAAh phase_step_rad_real for initial doppler = %f\n", phase_step_rad_real); + if (phase_step_rad_real >= 1.0) + { + phase_step_rad_real = MAX_PHASE_STEP_RAD; + } + //printf("AAAh phase_step_rad_real for initial doppler after checking = %f\n", phase_step_rad_real); + phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 + phase_step_rad_int = static_cast(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings + //printf("AAAh writing phase_step_rad_int for initial doppler = %d to d map base 3\n", phase_step_rad_int); + d_map_base[3] = phase_step_rad_int; + + // repeat the calculation with the doppler step + doppler = static_cast(d_doppler_step); + phase_step_rad = GPS_TWO_PI * (doppler) / static_cast(d_fs_in); + phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); + //printf("AAAh phase_step_rad_real for doppler step = %f\n", phase_step_rad_real); + if (phase_step_rad_real >= 1.0) + { + phase_step_rad_real = MAX_PHASE_STEP_RAD; + } + //printf("AAAh phase_step_rad_real for doppler step after checking = %f\n", phase_step_rad_real); + phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 + phase_step_rad_int = static_cast(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings + //printf("AAAh writing phase_step_rad_int for doppler step = %d to d map base 4\n", phase_step_rad_int); + d_map_base[4] = phase_step_rad_int; + //printf("AAAh writing num sweeps to d map base 5 = %d\n", num_sweeps); + d_map_base[5] = num_sweeps; +} + + +void fpga_acquisition::configure_acquisition() +{ + //printf("AAA d_select_queue = %d\n", d_select_queue); + d_map_base[0] = d_select_queue; + //printf("AAA writing d_vector_length = %d to d map base 1\n ", d_vector_length); + d_map_base[1] = d_vector_length; + //printf("AAA writing d_nsamples = %d to d map base 2\n ", d_nsamples); + d_map_base[2] = d_nsamples; + //printf("AAA writing LOG2 d_vector_length = %d to d map base 7\n ", (int)log2((float)d_vector_length)); + d_map_base[7] = static_cast(log2(static_cast(d_vector_length))); // log2 FFTlength + //printf("acquisition debug vector length = %d\n", d_vector_length); + //printf("acquisition debug vector length = %d\n", (int)log2((float)d_vector_length)); +} + + +void fpga_acquisition::set_phase_step(uint32_t doppler_index) +{ + float phase_step_rad_real; + float phase_step_rad_int_temp; + int32_t phase_step_rad_int; + int32_t doppler = -static_cast(d_doppler_max) + d_doppler_step * doppler_index; + //float phase_step_rad = GPS_TWO_PI * (d_freq + doppler) / static_cast(d_fs_in); + float phase_step_rad = GPS_TWO_PI * (doppler) / static_cast(d_fs_in); + // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing + // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) + // The FPGA also expects the phase to be negative since it produces cos(x) -j*sin(x) + // while the gnss-sdr software (volk_gnsssdr_s32f_sincos_32fc) generates cos(x) + j*sin(x) + phase_step_rad_real = phase_step_rad / (GPS_TWO_PI / 2); + // avoid saturation of the fixed point representation in the fpga + // (only the positive value can saturate due to the 2's complement representation) + //printf("AAA+ phase_step_rad_real = %f\n", phase_step_rad_real); + if (phase_step_rad_real >= 1.0) + { + phase_step_rad_real = MAX_PHASE_STEP_RAD; + } + //printf("AAA+ phase_step_rad_real after checking = %f\n", phase_step_rad_real); + phase_step_rad_int_temp = phase_step_rad_real * POW_2_2; // * 2^2 + phase_step_rad_int = static_cast(phase_step_rad_int_temp * (POW_2_29)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings + //printf("writing phase_step_rad_int = %d to d_map_base 3\n", phase_step_rad_int); d_map_base[3] = phase_step_rad_int; } void fpga_acquisition::read_acquisition_results(uint32_t *max_index, - float *max_magnitude, unsigned *initial_sample, float *power_sum) + float *max_magnitude, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index) { - unsigned readval = 0; + uint64_t initial_sample_tmp = 0; + + uint32_t readval = 0; + uint64_t readval_long = 0; + uint64_t readval_long_shifted = 0; readval = d_map_base[1]; - *initial_sample = readval; - readval = d_map_base[2]; + initial_sample_tmp = readval; + readval_long = d_map_base[2]; + readval_long_shifted = readval_long << 32; // 2^32 + initial_sample_tmp = initial_sample_tmp + readval_long_shifted; // 2^32 + //printf("----------------------------------------------------------------> acq initial sample TOTAL = %llu\n", initial_sample_tmp); + *initial_sample = initial_sample_tmp; + readval = d_map_base[6]; *max_magnitude = static_cast(readval); + //printf("read max_magnitude dmap 2 = %d\n", readval); readval = d_map_base[4]; *power_sum = static_cast(readval); + //printf("read power sum dmap 4 = %d\n", readval); + readval = d_map_base[5]; // read doppler index + *doppler_index = readval; + //printf("read doppler_index dmap 5 = %d\n", readval); readval = d_map_base[3]; *max_index = readval; + //printf("read max index dmap 3 = %d\n", readval); } @@ -249,7 +408,7 @@ void fpga_acquisition::unblock_samples() void fpga_acquisition::close_device() { - unsigned *aux = const_cast(d_map_base); + uint32_t *aux = const_cast(d_map_base); if (munmap(static_cast(aux), PAGE_SIZE) == -1) { printf("Failed to unmap memory uio\n"); @@ -260,5 +419,5 @@ void fpga_acquisition::close_device() void fpga_acquisition::reset_acquisition(void) { - d_map_base[6] = RESET_ACQUISITION; // writing a 2 to d_map_base[6] resets the multicorrelator + d_map_base[8] = RESET_ACQUISITION; // writing a 2 to d_map_base[8] resets the multicorrelator } diff --git a/src/algorithms/acquisition/libs/fpga_acquisition.h b/src/algorithms/acquisition/libs/fpga_acquisition.h index e9b1482db..c23e6b5d5 100644 --- a/src/algorithms/acquisition/libs/fpga_acquisition.h +++ b/src/algorithms/acquisition/libs/fpga_acquisition.h @@ -38,6 +38,7 @@ #include #include +#include /*! * \brief Class that implements carrier wipe-off and correlators. @@ -46,20 +47,24 @@ class fpga_acquisition { public: fpga_acquisition(std::string device_name, - unsigned int nsamples, - unsigned int doppler_max, - unsigned int nsamples_total, long fs_in, - unsigned int sampled_ms, unsigned select_queue, + uint32_t nsamples, + uint32_t doppler_max, + uint32_t nsamples_total, + int64_t fs_in, + uint32_t sampled_ms, + uint32_t select_queue, lv_16sc_t *all_fft_codes); + ~fpga_acquisition(); bool init(); - bool set_local_code( - unsigned int PRN); + bool set_local_code(uint32_t PRN); bool free(); + void set_doppler_sweep(uint32_t num_sweeps); + void set_doppler_sweep_debug(uint32_t num_sweeps, uint32_t doppler_index); void run_acquisition(void); - void set_phase_step(unsigned int doppler_index); + void set_phase_step(uint32_t doppler_index); void read_acquisition_results(uint32_t *max_index, float *max_magnitude, - unsigned *initial_sample, float *power_sum); + uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index); void block_samples(); void unblock_samples(); @@ -67,7 +72,7 @@ public: * \brief Set maximum Doppler grid search * \param doppler_max - Maximum Doppler shift considered in the grid search [Hz]. */ - void set_doppler_max(unsigned int doppler_max) + void set_doppler_max(uint32_t doppler_max) { d_doppler_max = doppler_max; } @@ -76,26 +81,26 @@ public: * \brief Set Doppler steps for the grid search * \param doppler_step - Frequency bin of the search grid [Hz]. */ - void set_doppler_step(unsigned int doppler_step) + void set_doppler_step(uint32_t doppler_step) { d_doppler_step = doppler_step; } private: - long d_fs_in; + int64_t d_fs_in; // data related to the hardware module and the driver - int d_fd; // driver descriptor - volatile unsigned *d_map_base; // driver memory map + int32_t d_fd; // driver descriptor + volatile uint32_t *d_map_base; // driver memory map lv_16sc_t *d_all_fft_codes; // memory that contains all the code ffts - unsigned int d_vector_length; // number of samples incluing padding and number of ms - unsigned int d_nsamples_total; // number of samples including padding - unsigned int d_nsamples; // number of samples not including padding - unsigned int d_select_queue; // queue selection + uint32_t d_vector_length; // number of samples incluing padding and number of ms + uint32_t d_nsamples_total; // number of samples including padding + uint32_t d_nsamples; // number of samples not including padding + uint32_t d_select_queue; // queue selection std::string d_device_name; // HW device name - unsigned int d_doppler_max; // max doppler - unsigned int d_doppler_step; // doppler step + uint32_t d_doppler_max; // max doppler + uint32_t d_doppler_step; // doppler step // FPGA private functions - unsigned fpga_acquisition_test_register(unsigned writeval); + uint32_t fpga_acquisition_test_register(uint32_t writeval); void fpga_configure_acquisition_local_code(lv_16sc_t fft_local_code[]); void configure_acquisition(); void reset_acquisition(void); diff --git a/src/algorithms/channel/CMakeLists.txt b/src/algorithms/channel/CMakeLists.txt index 077b74808..cd5604218 100644 --- a/src/algorithms/channel/CMakeLists.txt +++ b/src/algorithms/channel/CMakeLists.txt @@ -17,4 +17,4 @@ # add_subdirectory(adapters) -add_subdirectory(libs) \ No newline at end of file +add_subdirectory(libs) diff --git a/src/algorithms/channel/adapters/CMakeLists.txt b/src/algorithms/channel/adapters/CMakeLists.txt index a6d5245cd..65591834c 100644 --- a/src/algorithms/channel/adapters/CMakeLists.txt +++ b/src/algorithms/channel/adapters/CMakeLists.txt @@ -17,22 +17,31 @@ # set(CHANNEL_ADAPTER_SOURCES channel.cc) +set(CHANNEL_ADAPTER_HEADERS channel.h) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/channel/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/channel/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} +) + +add_library(channel_adapters + ${CHANNEL_ADAPTER_SOURCES} + ${CHANNEL_ADAPTER_HEADERS} ) -file(GLOB CHANNEL_ADAPTER_HEADERS "*.h") -list(SORT CHANNEL_ADAPTER_HEADERS) -add_library(channel_adapters ${CHANNEL_ADAPTER_SOURCES} ${CHANNEL_ADAPTER_HEADERS}) source_group(Headers FILES ${CHANNEL_ADAPTER_HEADERS}) -target_link_libraries(channel_adapters channel_fsm ${GNURADIO_RUNTIME_LIBRARIES} ${Boost_LIBRARIES} gnss_sdr_flags) + +target_link_libraries(channel_adapters + channel_fsm + ${GNURADIO_RUNTIME_LIBRARIES} + ${Boost_LIBRARIES} + gnss_sdr_flags +) diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index 480212e3a..8e4a3120d 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -34,12 +34,12 @@ #include "gnss_sdr_flags.h" #include #include - +#include using google::LogMessage; // Constructor -Channel::Channel(ConfigurationInterface* configuration, unsigned int channel, +Channel::Channel(ConfigurationInterface* configuration, uint32_t channel, std::shared_ptr pass_through, std::shared_ptr acq, std::shared_ptr trk, std::shared_ptr nav, std::string role, std::string implementation, gr::msg_queue::sptr queue) @@ -66,7 +66,7 @@ Channel::Channel(ConfigurationInterface* configuration, unsigned int channel, // Provide a warning to the user about the change of parameter name if (channel_ == 0) { - long int deprecation_warning = configuration->property("GNSS-SDR.internal_fs_hz", 0); + int64_t deprecation_warning = configuration->property("GNSS-SDR.internal_fs_hz", 0); if (deprecation_warning != 0) { std::cout << "WARNING: The global parameter name GNSS-SDR.internal_fs_hz has been DEPRECATED." << std::endl; @@ -76,9 +76,9 @@ Channel::Channel(ConfigurationInterface* configuration, unsigned int channel, // IMPORTANT: Do not change the order between set_doppler_step and set_threshold - unsigned int doppler_step = configuration->property("Acquisition_" + implementation_ + boost::lexical_cast(channel_) + ".doppler_step", 0); + uint32_t doppler_step = configuration->property("Acquisition_" + implementation_ + boost::lexical_cast(channel_) + ".doppler_step", 0); if (doppler_step == 0) doppler_step = configuration->property("Acquisition_" + implementation_ + ".doppler_step", 500); - if (FLAGS_doppler_step != 0) doppler_step = static_cast(FLAGS_doppler_step); + if (FLAGS_doppler_step != 0) doppler_step = static_cast(FLAGS_doppler_step); DLOG(INFO) << "Channel " << channel_ << " Doppler_step = " << doppler_step; acq_->set_doppler_step(doppler_step); @@ -196,6 +196,19 @@ void Channel::set_signal(const Gnss_Signal& gnss_signal) } +void Channel::stop_channel() +{ + std::lock_guard lk(mx); + bool result = channel_fsm_->Event_stop_channel(); + if (!result) + { + LOG(WARNING) << "Invalid channel event"; + return; + } + DLOG(INFO) + << "Channel stop_channel()"; +} + void Channel::start_acquisition() { std::lock_guard lk(mx); diff --git a/src/algorithms/channel/adapters/channel.h b/src/algorithms/channel/adapters/channel.h index d82ad0870..3802ff107 100644 --- a/src/algorithms/channel/adapters/channel.h +++ b/src/algorithms/channel/adapters/channel.h @@ -60,7 +60,7 @@ class Channel : public ChannelInterface { public: //! Constructor - Channel(ConfigurationInterface* configuration, unsigned int channel, + Channel(ConfigurationInterface* configuration, uint32_t channel, std::shared_ptr pass_through, std::shared_ptr acq, std::shared_ptr trk, std::shared_ptr nav, std::string role, std::string implementation, gr::msg_queue::sptr queue); @@ -73,21 +73,17 @@ public: gr::basic_block_sptr get_right_block() override; inline std::string role() override { return role_; } - //! Returns "Channel" inline std::string implementation() override { return implementation_; } - inline size_t item_size() override { return 0; } - inline Gnss_Signal get_signal() const override { return gnss_signal_; } - void start_acquisition() override; //!< Start the State Machine + void stop_channel() override; //!< Stop the State Machine void set_signal(const Gnss_Signal& gnss_signal_) override; //!< Sets the channel GNSS signal inline std::shared_ptr acquisition() { return acq_; } inline std::shared_ptr tracking() { return trk_; } inline std::shared_ptr telemetry() { return nav_; } - void msg_handler_events(pmt::pmt_t msg); private: @@ -99,7 +95,7 @@ private: std::string role_; std::string implementation_; bool flag_enable_fpga; - unsigned int channel_; + uint32_t channel_; Gnss_Synchro gnss_synchro_; Gnss_Signal gnss_signal_; bool connected_; diff --git a/src/algorithms/channel/libs/CMakeLists.txt b/src/algorithms/channel/libs/CMakeLists.txt index ffbc21a42..70bee59f9 100644 --- a/src/algorithms/channel/libs/CMakeLists.txt +++ b/src/algorithms/channel/libs/CMakeLists.txt @@ -16,28 +16,33 @@ # along with GNSS-SDR. If not, see . # -set(CHANNEL_FSM_SOURCES - channel_fsm.cc +set(CHANNEL_FSM_SOURCES + channel_fsm.cc channel_msg_receiver_cc.cc - ) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/channel/adapters - ${Boost_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} ) -file(GLOB CHANNEL_FSM_HEADERS "*.h") +set(CHANNEL_FSM_HEADERS + channel_fsm.h + channel_msg_receiver_cc.h +) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/channel/adapters + ${Boost_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} +) + list(SORT CHANNEL_FSM_HEADERS) +list(SORT CHANNEL_FSM_SOURCES) + add_library(channel_fsm ${CHANNEL_FSM_SOURCES} ${CHANNEL_FSM_HEADERS}) source_group(Headers FILES ${CHANNEL_FSM_HEADERS}) add_dependencies(channel_fsm glog-${glog_RELEASE}) target_link_libraries(channel_fsm gnss_rx) - diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index 5ac015f2d..14a4e6b12 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -39,19 +39,41 @@ ChannelFsm::ChannelFsm() { acq_ = nullptr; trk_ = nullptr; - channel_ = 0; - d_state = 0; + channel_ = 0U; + d_state = 0U; } ChannelFsm::ChannelFsm(std::shared_ptr acquisition) : acq_(acquisition) { trk_ = nullptr; - channel_ = 0; - d_state = 0; + channel_ = 0U; + d_state = 0U; } +bool ChannelFsm::Event_stop_channel() +{ + std::lock_guard lk(mx); + DLOG(INFO) << "CH = " << channel_ << ". Ev stop channel"; + switch (d_state) + { + case 0: //already in stanby + break; + case 1: //acquisition + d_state = 0; + stop_acquisition(); + break; + case 2: //tracking + d_state = 0; + stop_tracking(); + break; + default: + break; + } + return true; +} + bool ChannelFsm::Event_start_acquisition() { std::lock_guard lk(mx); @@ -129,7 +151,7 @@ bool ChannelFsm::Event_failed_tracking_standby() } else { - d_state = 0; + d_state = 0U; notify_stop_tracking(); DLOG(INFO) << "CH = " << channel_ << ". Ev failed tracking standby"; return true; @@ -158,13 +180,24 @@ void ChannelFsm::set_queue(gr::msg_queue::sptr queue) } -void ChannelFsm::set_channel(unsigned int channel) +void ChannelFsm::set_channel(uint32_t channel) { std::lock_guard lk(mx); channel_ = channel; } +void ChannelFsm::stop_acquisition() +{ + acq_->stop_acquisition(); +} + +void ChannelFsm::stop_tracking() +{ + trk_->stop_tracking(); +} + + void ChannelFsm::start_acquisition() { acq_->reset(); diff --git a/src/algorithms/channel/libs/channel_fsm.h b/src/algorithms/channel/libs/channel_fsm.h index 7489ca171..c2ee6c728 100644 --- a/src/algorithms/channel/libs/channel_fsm.h +++ b/src/algorithms/channel/libs/channel_fsm.h @@ -36,6 +36,7 @@ #include "tracking_interface.h" #include "telemetry_decoder_interface.h" #include +#include #include #include @@ -52,11 +53,12 @@ public: void set_acquisition(std::shared_ptr acquisition); void set_tracking(std::shared_ptr tracking); void set_queue(gr::msg_queue::sptr queue); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); //FSM EVENTS bool Event_start_acquisition(); bool Event_valid_acquisition(); + bool Event_stop_channel(); bool Event_failed_acquisition_repeat(); bool Event_failed_acquisition_no_repeat(); bool Event_failed_tracking_standby(); @@ -64,14 +66,16 @@ public: private: void start_acquisition(); void start_tracking(); + void stop_acquisition(); + void stop_tracking(); void request_satellite(); void notify_stop_tracking(); std::shared_ptr acq_; std::shared_ptr trk_; gr::msg_queue::sptr queue_; - unsigned int channel_; - unsigned int d_state; + uint32_t channel_; + uint32_t d_state; std::mutex mx; }; diff --git a/src/algorithms/channel/libs/channel_msg_receiver_cc.cc b/src/algorithms/channel/libs/channel_msg_receiver_cc.cc index ca4105f8e..f77f8c883 100644 --- a/src/algorithms/channel/libs/channel_msg_receiver_cc.cc +++ b/src/algorithms/channel/libs/channel_msg_receiver_cc.cc @@ -33,6 +33,7 @@ #include #include #include +#include using google::LogMessage; @@ -48,7 +49,7 @@ void channel_msg_receiver_cc::msg_handler_events(pmt::pmt_t msg) bool result = false; try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); switch (message) { case 1: // positive acquisition diff --git a/src/algorithms/conditioner/CMakeLists.txt b/src/algorithms/conditioner/CMakeLists.txt index de941b536..166f27d36 100644 --- a/src/algorithms/conditioner/CMakeLists.txt +++ b/src/algorithms/conditioner/CMakeLists.txt @@ -17,4 +17,3 @@ # add_subdirectory(adapters) -#add_subdirectory(gnuradio_blocks) \ No newline at end of file diff --git a/src/algorithms/conditioner/adapters/CMakeLists.txt b/src/algorithms/conditioner/adapters/CMakeLists.txt index cb83608aa..38d606824 100644 --- a/src/algorithms/conditioner/adapters/CMakeLists.txt +++ b/src/algorithms/conditioner/adapters/CMakeLists.txt @@ -17,25 +17,31 @@ # -set(COND_ADAPTER_SOURCES - signal_conditioner.cc - array_signal_conditioner.cc +set(COND_ADAPTER_SOURCES + signal_conditioner.cc + array_signal_conditioner.cc +) + +set(COND_ADAPTER_HEADERS + signal_conditioner.h + array_signal_conditioner.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} ) -file(GLOB COND_ADAPTER_HEADERS "*.h") list(SORT COND_ADAPTER_HEADERS) +list(SORT COND_ADAPTER_SOURCES) + add_library(conditioner_adapters ${COND_ADAPTER_SOURCES} ${COND_ADAPTER_HEADERS}) source_group(Headers FILES ${COND_ADAPTER_HEADERS}) -add_dependencies(conditioner_adapters glog-${glog_RELEASE}) \ No newline at end of file +add_dependencies(conditioner_adapters glog-${glog_RELEASE}) diff --git a/src/algorithms/data_type_adapter/CMakeLists.txt b/src/algorithms/data_type_adapter/CMakeLists.txt index 6037ad61f..1c15cc0ca 100644 --- a/src/algorithms/data_type_adapter/CMakeLists.txt +++ b/src/algorithms/data_type_adapter/CMakeLists.txt @@ -19,4 +19,3 @@ add_subdirectory(adapters) add_subdirectory(gnuradio_blocks) - diff --git a/src/algorithms/data_type_adapter/adapters/CMakeLists.txt b/src/algorithms/data_type_adapter/adapters/CMakeLists.txt index 836e2bfd8..1977f7a5a 100644 --- a/src/algorithms/data_type_adapter/adapters/CMakeLists.txt +++ b/src/algorithms/data_type_adapter/adapters/CMakeLists.txt @@ -17,31 +17,48 @@ # -set(DATATYPE_ADAPTER_SOURCES +set(DATATYPE_ADAPTER_SOURCES byte_to_short.cc ibyte_to_cbyte.cc ibyte_to_complex.cc ibyte_to_cshort.cc ishort_to_cshort.cc - ishort_to_complex.cc - ) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${VOLK_INCLUDE_DIRS} + ishort_to_complex.cc +) + +set(DATATYPE_ADAPTER_HEADERS + byte_to_short.h + ibyte_to_cbyte.h + ibyte_to_complex.h + ibyte_to_cshort.h + ishort_to_cshort.h + ishort_to_complex.h +) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_INCLUDE_DIRS} ) -file(GLOB DATATYPE_ADAPTER_HEADERS "*.h") list(SORT DATATYPE_ADAPTER_HEADERS) -add_library(datatype_adapters ${DATATYPE_ADAPTER_SOURCES} ${DATATYPE_ADAPTER_HEADERS}) +list(SORT DATATYPE_ADAPTER_SOURCES) + +add_library(datatype_adapters + ${DATATYPE_ADAPTER_SOURCES} + ${DATATYPE_ADAPTER_HEADERS} +) + source_group(Headers FILES ${DATATYPE_ADAPTER_HEADERS}) add_dependencies(datatype_adapters glog-${glog_RELEASE}) -target_link_libraries(datatype_adapters data_type_gr_blocks ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES}) - +target_link_libraries(datatype_adapters + data_type_gr_blocks + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} +) diff --git a/src/algorithms/data_type_adapter/gnuradio_blocks/CMakeLists.txt b/src/algorithms/data_type_adapter/gnuradio_blocks/CMakeLists.txt index 872dabfcf..b4f429db9 100644 --- a/src/algorithms/data_type_adapter/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/data_type_adapter/gnuradio_blocks/CMakeLists.txt @@ -17,20 +17,35 @@ # -set(DATA_TYPE_GR_BLOCKS_SOURCES - interleaved_byte_to_complex_byte.cc - interleaved_short_to_complex_short.cc - interleaved_byte_to_complex_short.cc +set(DATA_TYPE_GR_BLOCKS_SOURCES + interleaved_byte_to_complex_byte.cc + interleaved_short_to_complex_short.cc + interleaved_byte_to_complex_short.cc +) + +set(DATA_TYPE_GR_BLOCKS_HEADERS + interleaved_byte_to_complex_byte.h + interleaved_short_to_complex_short.h + interleaved_byte_to_complex_short.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${VOLK_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_INCLUDE_DIRS} ) -file(GLOB DATA_TYPE_GR_BLOCKS_HEADERS "*.h") list(SORT DATA_TYPE_GR_BLOCKS_HEADERS) -add_library(data_type_gr_blocks ${DATA_TYPE_GR_BLOCKS_SOURCES} ${DATA_TYPE_GR_BLOCKS_HEADERS}) +list(SORT DATA_TYPE_GR_BLOCKS_SOURCES) + +add_library(data_type_gr_blocks + ${DATA_TYPE_GR_BLOCKS_SOURCES} + ${DATA_TYPE_GR_BLOCKS_HEADERS} +) + source_group(Headers FILES ${DATA_TYPE_GR_BLOCKS_HEADERS}) -target_link_libraries(data_type_gr_blocks ${GNURADIO_RUNTIME_LIBRARIES} ${VOLK_LIBRARIES}) \ No newline at end of file + +target_link_libraries(data_type_gr_blocks + ${GNURADIO_RUNTIME_LIBRARIES} + ${VOLK_LIBRARIES} +) diff --git a/src/algorithms/input_filter/CMakeLists.txt b/src/algorithms/input_filter/CMakeLists.txt index 64cb2a571..1841d3dfc 100644 --- a/src/algorithms/input_filter/CMakeLists.txt +++ b/src/algorithms/input_filter/CMakeLists.txt @@ -17,4 +17,4 @@ # add_subdirectory(adapters) -add_subdirectory(gnuradio_blocks) \ No newline at end of file +add_subdirectory(gnuradio_blocks) diff --git a/src/algorithms/input_filter/adapters/CMakeLists.txt b/src/algorithms/input_filter/adapters/CMakeLists.txt index f12efd609..8153c6c3c 100644 --- a/src/algorithms/input_filter/adapters/CMakeLists.txt +++ b/src/algorithms/input_filter/adapters/CMakeLists.txt @@ -16,30 +16,54 @@ # along with GNSS-SDR. If not, see . # -set(INPUT_FILTER_ADAPTER_SOURCES - fir_filter.cc - freq_xlating_fir_filter.cc - beamformer_filter.cc - pulse_blanking_filter.cc - notch_filter.cc - notch_filter_lite.cc +set(INPUT_FILTER_ADAPTER_SOURCES + fir_filter.cc + freq_xlating_fir_filter.cc + beamformer_filter.cc + pulse_blanking_filter.cc + notch_filter.cc + notch_filter_lite.cc +) + +set(INPUT_FILTER_ADAPTER_HEADERS + fir_filter.h + freq_xlating_fir_filter.h + beamformer_filter.h + pulse_blanking_filter.h + notch_filter.h + notch_filter_lite.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/algorithms/input_filter/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${VOLK_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/algorithms/input_filter/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_INCLUDE_DIRS} ) -file(GLOB INPUT_FILTER_ADAPTER_HEADERS "*.h") +if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.13.4") + add_definitions(-DGR_GREATER_38=1) +endif() + list(SORT INPUT_FILTER_ADAPTER_HEADERS) -add_library(input_filter_adapters ${INPUT_FILTER_ADAPTER_SOURCES} ${INPUT_FILTER_ADAPTER_HEADERS}) +list(SORT INPUT_FILTER_ADAPTER_SOURCES) + +add_library(input_filter_adapters + ${INPUT_FILTER_ADAPTER_SOURCES} + ${INPUT_FILTER_ADAPTER_HEADERS} +) + source_group(Headers FILES ${INPUT_FILTER_ADAPTER_HEADERS}) add_dependencies(input_filter_adapters glog-${glog_RELEASE} gnss_sp_libs) -target_link_libraries(input_filter_adapters input_filter_gr_blocks ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES} ${GNURADIO_FILTER_LIBRARIES} gnss_sp_libs) +target_link_libraries(input_filter_adapters + input_filter_gr_blocks + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${GNURADIO_FILTER_LIBRARIES} + gnss_sp_libs +) diff --git a/src/algorithms/input_filter/adapters/fir_filter.h b/src/algorithms/input_filter/adapters/fir_filter.h index 05c494b5f..207d8e174 100644 --- a/src/algorithms/input_filter/adapters/fir_filter.h +++ b/src/algorithms/input_filter/adapters/fir_filter.h @@ -43,8 +43,12 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include #include +#endif #include #include #include diff --git a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc index 4f6088cae..1bdb2d841 100644 --- a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc +++ b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc @@ -43,38 +43,112 @@ using google::LogMessage; FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : config_(configuration), role_(role), in_streams_(in_streams), out_streams_(out_streams) { - size_t item_size; - (*this).init(); - int decimation_factor; + std::string default_input_item_type = "gr_complex"; + std::string default_output_item_type = "gr_complex"; + std::string default_taps_item_type = "float"; + std::string default_dump_filename = "../data/input_filter.dat"; + double default_intermediate_freq = 0.0; + double default_sampling_freq = 4000000.0; + int default_number_of_taps = 6; + unsigned int default_number_of_bands = 2; + std::vector default_bands = {0.0, 0.4, 0.6, 1.0}; + std::vector default_ampl = {1.0, 1.0, 0.0, 0.0}; + std::vector default_error_w = {1.0, 1.0}; + std::string default_filter_type = "bandpass"; + int default_grid_density = 16; int default_decimation_factor = 1; - decimation_factor = config_->property(role_ + ".decimation_factor", default_decimation_factor); + + DLOG(INFO) << "role " << role_; + + input_item_type_ = config_->property(role_ + ".input_item_type", default_input_item_type); + output_item_type_ = config_->property(role_ + ".output_item_type", default_output_item_type); + taps_item_type_ = config_->property(role_ + ".taps_item_type", default_taps_item_type); + dump_ = config_->property(role_ + ".dump", false); + dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); + intermediate_freq_ = config_->property(role_ + ".IF", default_intermediate_freq); + sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq); + int number_of_taps = config_->property(role_ + ".number_of_taps", default_number_of_taps); + unsigned int number_of_bands = config_->property(role_ + ".number_of_bands", default_number_of_bands); + std::string filter_type = config_->property(role_ + ".filter_type", default_filter_type); + decimation_factor_ = config_->property(role_ + ".decimation_factor", default_decimation_factor); + + if (filter_type.compare("lowpass") != 0) + { + std::vector taps_d; + std::vector bands; + std::vector ampl; + std::vector error_w; + std::string option; + double option_value; + + for (unsigned int i = 0; i < number_of_bands; i++) + { + option = ".band" + boost::lexical_cast(i + 1) + "_begin"; + option_value = config_->property(role_ + option, default_bands[i]); + bands.push_back(option_value); + + option = ".band" + boost::lexical_cast(i + 1) + "_end"; + option_value = config_->property(role_ + option, default_bands[i]); + bands.push_back(option_value); + + option = ".ampl" + boost::lexical_cast(i + 1) + "_begin"; + option_value = config_->property(role_ + option, default_bands[i]); + ampl.push_back(option_value); + + option = ".ampl" + boost::lexical_cast(i + 1) + "_end"; + option_value = config_->property(role_ + option, default_bands[i]); + ampl.push_back(option_value); + + option = ".band" + boost::lexical_cast(i + 1) + "_error"; + option_value = config_->property(role_ + option, default_bands[i]); + error_w.push_back(option_value); + } + + int grid_density = config_->property(role_ + ".grid_density", default_grid_density); + taps_d = gr::filter::pm_remez(number_of_taps - 1, bands, ampl, error_w, filter_type, grid_density); + taps_.reserve(taps_d.size()); + for (std::vector::iterator it = taps_d.begin(); it != taps_d.end(); it++) + { + taps_.push_back(static_cast(*it)); + } + } + else + { + double default_bw = (sampling_freq_ / decimation_factor_) / 2; + double bw_ = config_->property(role_ + ".bw", default_bw); + double default_tw = bw_ / 10.0; + double tw_ = config_->property(role_ + ".tw", default_tw); + taps_ = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_, tw_); + } + + size_t item_size; if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("gr_complex") == 0) && (output_item_type_.compare("gr_complex") == 0)) { item_size = sizeof(gr_complex); //output input_size_ = sizeof(gr_complex); //input - freq_xlating_fir_filter_ccf_ = gr::filter::freq_xlating_fir_filter_ccf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); + freq_xlating_fir_filter_ccf_ = gr::filter::freq_xlating_fir_filter_ccf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_ccf_->unique_id() << ")"; } else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("float") == 0) && (output_item_type_.compare("gr_complex") == 0)) { item_size = sizeof(gr_complex); input_size_ = sizeof(float); //input - freq_xlating_fir_filter_fcf_ = gr::filter::freq_xlating_fir_filter_fcf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); + freq_xlating_fir_filter_fcf_ = gr::filter::freq_xlating_fir_filter_fcf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_fcf_->unique_id() << ")"; } else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("short") == 0) && (output_item_type_.compare("gr_complex") == 0)) { item_size = sizeof(gr_complex); input_size_ = sizeof(int16_t); //input - freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); + freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; } else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("short") == 0) && (output_item_type_.compare("cshort") == 0)) { item_size = sizeof(lv_16sc_t); input_size_ = sizeof(int16_t); //input - freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); + freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; complex_to_float_ = gr::blocks::complex_to_float::make(); float_to_short_1_ = gr::blocks::float_to_short::make(); @@ -86,7 +160,7 @@ FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration item_size = sizeof(gr_complex); input_size_ = sizeof(int8_t); //input gr_char_to_short_ = gr::blocks::char_to_short::make(); - freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); + freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; } else if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("byte") == 0) && (output_item_type_.compare("cbyte") == 0)) @@ -94,7 +168,7 @@ FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration item_size = sizeof(lv_8sc_t); input_size_ = sizeof(int8_t); //input gr_char_to_short_ = gr::blocks::char_to_short::make(); - freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_); + freq_xlating_fir_filter_scf_ = gr::filter::freq_xlating_fir_filter_scf::make(decimation_factor_, taps_, intermediate_freq_, sampling_freq_); DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_scf_->unique_id() << ")"; complex_to_complex_byte_ = make_complex_float_to_complex_byte(); } @@ -311,83 +385,3 @@ gr::basic_block_sptr FreqXlatingFirFilter::get_right_block() LOG(ERROR) << " Unknown input filter input/output item type conversion"; } } - - -void FreqXlatingFirFilter::init() -{ - std::string default_input_item_type = "gr_complex"; - std::string default_output_item_type = "gr_complex"; - std::string default_taps_item_type = "float"; - std::string default_dump_filename = "../data/input_filter.dat"; - double default_intermediate_freq = 0.0; - double default_sampling_freq = 4000000.0; - int default_number_of_taps = 6; - unsigned int default_number_of_bands = 2; - std::vector default_bands = {0.0, 0.4, 0.6, 1.0}; - std::vector default_ampl = {1.0, 1.0, 0.0, 0.0}; - std::vector default_error_w = {1.0, 1.0}; - std::string default_filter_type = "bandpass"; - int default_grid_density = 16; - - DLOG(INFO) << "role " << role_; - - input_item_type_ = config_->property(role_ + ".input_item_type", default_input_item_type); - output_item_type_ = config_->property(role_ + ".output_item_type", default_output_item_type); - taps_item_type_ = config_->property(role_ + ".taps_item_type", default_taps_item_type); - dump_ = config_->property(role_ + ".dump", false); - dump_filename_ = config_->property(role_ + ".dump_filename", default_dump_filename); - intermediate_freq_ = config_->property(role_ + ".IF", default_intermediate_freq); - sampling_freq_ = config_->property(role_ + ".sampling_frequency", default_sampling_freq); - int number_of_taps = config_->property(role_ + ".number_of_taps", default_number_of_taps); - unsigned int number_of_bands = config_->property(role_ + ".number_of_bands", default_number_of_bands); - std::string filter_type = config_->property(role_ + ".filter_type", default_filter_type); - - if (filter_type.compare("lowpass") != 0) - { - std::vector taps_d; - std::vector bands; - std::vector ampl; - std::vector error_w; - std::string option; - double option_value; - - for (unsigned int i = 0; i < number_of_bands; i++) - { - option = ".band" + boost::lexical_cast(i + 1) + "_begin"; - option_value = config_->property(role_ + option, default_bands[i]); - bands.push_back(option_value); - - option = ".band" + boost::lexical_cast(i + 1) + "_end"; - option_value = config_->property(role_ + option, default_bands[i]); - bands.push_back(option_value); - - option = ".ampl" + boost::lexical_cast(i + 1) + "_begin"; - option_value = config_->property(role_ + option, default_bands[i]); - ampl.push_back(option_value); - - option = ".ampl" + boost::lexical_cast(i + 1) + "_end"; - option_value = config_->property(role_ + option, default_bands[i]); - ampl.push_back(option_value); - - option = ".band" + boost::lexical_cast(i + 1) + "_error"; - option_value = config_->property(role_ + option, default_bands[i]); - error_w.push_back(option_value); - } - - int grid_density = config_->property(role_ + ".grid_density", default_grid_density); - taps_d = gr::filter::pm_remez(number_of_taps - 1, bands, ampl, error_w, filter_type, grid_density); - taps_.reserve(taps_d.size()); - for (std::vector::iterator it = taps_d.begin(); it != taps_d.end(); it++) - { - taps_.push_back(static_cast(*it)); - } - } - else - { - double default_bw = 2000000.0; - double bw_ = config_->property(role_ + ".bw", default_bw); - double default_tw = bw_ / 10.0; - double tw_ = config_->property(role_ + ".tw", default_tw); - taps_ = gr::filter::firdes::low_pass(1.0, sampling_freq_, bw_, tw_); - } -} diff --git a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.h b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.h index d7549d9ab..8f69efc97 100644 --- a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.h +++ b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.h @@ -36,9 +36,13 @@ #include "gnss_block_interface.h" #include "short_x2_to_cshort.h" #include "complex_float_to_complex_byte.h" +#ifdef GR_GREATER_38 +#include +#else #include #include #include +#endif #include #include #include @@ -95,6 +99,7 @@ private: gr::filter::freq_xlating_fir_filter_fcf::sptr freq_xlating_fir_filter_fcf_; gr::filter::freq_xlating_fir_filter_scf::sptr freq_xlating_fir_filter_scf_; ConfigurationInterface* config_; + int decimation_factor_; bool dump_; std::string dump_filename_; std::string input_item_type_; @@ -114,7 +119,6 @@ private: gr::blocks::float_to_short::sptr float_to_short_2_; short_x2_to_cshort_sptr short_x2_to_cshort_; complex_float_to_complex_byte_sptr complex_to_complex_byte_; - void init(); }; #endif // GNSS_SDR_FREQ_XLATING_FIR_FILTER_H_ diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h index 0d9d17cb4..87f8c4994 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.h +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.h @@ -35,7 +35,11 @@ #include "gnss_block_interface.h" #include "pulse_blanking_cc.h" #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include class ConfigurationInterface; diff --git a/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt b/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt index 698c828dd..8a4aefc11 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/input_filter/gnuradio_blocks/CMakeLists.txt @@ -18,30 +18,44 @@ set(INPUT_FILTER_GR_BLOCKS_SOURCES - beamformer.cc - pulse_blanking_cc.cc - notch_cc.cc - notch_lite_cc.cc + beamformer.cc + pulse_blanking_cc.cc + notch_cc.cc + notch_lite_cc.cc +) + +set(INPUT_FILTER_GR_BLOCKS_HEADERS + beamformer.h + pulse_blanking_cc.h + notch_cc.h + notch_lite_cc.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${GNURADIO_BLOCKS_INCLUDE_DIRS} - ${VOLK_GNSSSDR_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${GNURADIO_BLOCKS_INCLUDE_DIRS} + ${VOLK_GNSSSDR_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} ) -file(GLOB INPUT_FILTER_GR_BLOCKS_HEADERS "*.h") list(SORT INPUT_FILTER_GR_BLOCKS_HEADERS) -add_library(input_filter_gr_blocks ${INPUT_FILTER_GR_BLOCKS_SOURCES} ${INPUT_FILTER_GR_BLOCKS_HEADERS}) +list(SORT INPUT_FILTER_GR_BLOCKS_SOURCES) + +add_library(input_filter_gr_blocks + ${INPUT_FILTER_GR_BLOCKS_SOURCES} + ${INPUT_FILTER_GR_BLOCKS_HEADERS}) + source_group(Headers FILES ${INPUT_FILTER_GR_BLOCKS_HEADERS}) -target_link_libraries(input_filter_gr_blocks ${GNURADIO_FILTER_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${LOG4CPP_LIBRARIES}) +target_link_libraries(input_filter_gr_blocks + ${GNURADIO_FILTER_LIBRARIES} + ${VOLK_GNSSSDR_LIBRARIES} + ${LOG4CPP_LIBRARIES}) -if(NOT VOLK_GNSSSDR_FOUND) +if(NOT VOLKGNSSSDR_FOUND) add_dependencies(input_filter_gr_blocks volk_gnsssdr_module glog-${glog_RELEASE}) -else(NOT VOLK_GNSSSDR_FOUND) +else() add_dependencies(input_filter_gr_blocks glog-${glog_RELEASE}) -endif(NOT VOLK_GNSSSDR_FOUND) +endif() diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 5e7870cd4..d7cc09c33 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -39,7 +39,7 @@ using google::LogMessage; notch_sptr make_notch_filter(float pfa, float p_c_factor, - int length_, int n_segments_est, int n_segments_reset) + int32_t length_, int32_t n_segments_est, int32_t n_segments_reset) { return notch_sptr(new Notch(pfa, p_c_factor, length_, n_segments_est, n_segments_reset)); } @@ -47,31 +47,31 @@ notch_sptr make_notch_filter(float pfa, float p_c_factor, Notch::Notch(float pfa, float p_c_factor, - int length_, - int n_segments_est, - int n_segments_reset) : gr::block("Notch", - gr::io_signature::make(1, 1, sizeof(gr_complex)), - gr::io_signature::make(1, 1, sizeof(gr_complex))) + int32_t length_, + int32_t n_segments_est, + int32_t n_segments_reset) : gr::block("Notch", + gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(gr_complex))) { - const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); + const int32_t alignment_multiple = volk_get_alignment() / sizeof(gr_complex); set_alignment(std::max(1, alignment_multiple)); set_history(2); this->pfa = pfa; noise_pow_est = 0.0; - this->p_c_factor = gr_complex(p_c_factor, 0); - this->length_ = length_; //Set the number of samples per segment - filter_state_ = false; //Initial state of the filter - n_deg_fred = 2 * length_; //Number of dregrees of freedom + this->p_c_factor = gr_complex(p_c_factor, 0.0); + this->length_ = length_; // Set the number of samples per segment + filter_state_ = false; // Initial state of the filter + n_deg_fred = 2 * length_; // Number of dregrees of freedom n_segments = 0; this->n_segments_est = n_segments_est; // Set the number of segments for noise power estimation this->n_segments_reset = n_segments_reset; // Set the period (in segments) when the noise power is estimated - z_0 = gr_complex(0, 0); + z_0 = gr_complex(0.0, 0.0); boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); c_samples = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); angle_ = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); power_spect = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); - last_out = gr_complex(0, 0); + last_out = gr_complex(0.0, 0.0); d_fft = std::unique_ptr(new gr::fft::fft_complex(length_, true)); } @@ -86,7 +86,7 @@ Notch::~Notch() void Notch::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) { - for (unsigned int aux = 0; aux < ninput_items_required.size(); aux++) + for (uint32_t aux = 0; aux < ninput_items_required.size(); aux++) { ninput_items_required[aux] = length_; } @@ -96,7 +96,7 @@ void Notch::forecast(int noutput_items __attribute__((unused)), gr_vector_int &n int Notch::general_work(int noutput_items, gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - int index_out = 0; + int32_t index_out = 0; float sig2dB = 0.0; float sig2lin = 0.0; lv_32fc_t dot_prod_; @@ -127,7 +127,7 @@ int Notch::general_work(int noutput_items, gr_vector_int &ninput_items __attribu } volk_32fc_x2_multiply_conjugate_32fc(c_samples, in, (in - 1), length_); volk_32fc_s32f_atan2_32f(angle_, c_samples, static_cast(1.0), length_); - for (int aux = 0; aux < length_; aux++) + for (int32_t aux = 0; aux < length_; aux++) { z_0 = std::exp(gr_complex(0, 1) * (*(angle_ + aux))); *(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out; diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h index 160494346..ab8f3b693 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.h @@ -34,6 +34,7 @@ #include #include #include +#include #include class Notch; @@ -41,7 +42,7 @@ class Notch; typedef boost::shared_ptr notch_sptr; notch_sptr make_notch_filter(float pfa, float p_c_factor, - int length_, int n_segments_est, int n_segments_reset); + int32_t length_, int32_t n_segments_est, int32_t n_segments_reset); /*! * \brief This class implements a real-time software-defined multi state notch filter @@ -53,11 +54,11 @@ private: float pfa; float noise_pow_est; float thres_; - int length_; - int n_deg_fred; - unsigned int n_segments; - unsigned int n_segments_est; - unsigned int n_segments_reset; + int32_t length_; + int32_t n_deg_fred; + uint32_t n_segments; + uint32_t n_segments_est; + uint32_t n_segments_reset; bool filter_state_; gr_complex last_out; gr_complex z_0; @@ -68,7 +69,7 @@ private: std::unique_ptr d_fft; public: - Notch(float pfa, float p_c_factor, int length_, int n_segments_est, int n_segments_reset); + Notch(float pfa, float p_c_factor, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset); ~Notch(); diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc index 41d684a2a..435b36470 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.cc @@ -38,7 +38,7 @@ using google::LogMessage; -notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff) +notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset, int32_t n_segments_coeff) { return notch_lite_sptr(new NotchLite(p_c_factor, pfa, length_, n_segments_est, n_segments_reset, n_segments_coeff)); } @@ -46,17 +46,17 @@ notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, NotchLite::NotchLite(float p_c_factor, float pfa, - int length_, - int n_segments_est, - int n_segments_reset, - int n_segments_coeff) : gr::block("NotchLite", - gr::io_signature::make(1, 1, sizeof(gr_complex)), - gr::io_signature::make(1, 1, sizeof(gr_complex))) + int32_t length_, + int32_t n_segments_est, + int32_t n_segments_reset, + int32_t n_segments_coeff) : gr::block("NotchLite", + gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(gr_complex))) { - const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); + const int32_t alignment_multiple = volk_get_alignment() / sizeof(gr_complex); set_alignment(std::max(1, alignment_multiple)); set_history(2); - this->p_c_factor = gr_complex(p_c_factor, 0); + this->p_c_factor = gr_complex(p_c_factor, 0.0); this->n_segments_est = n_segments_est; this->n_segments_reset = n_segments_reset; this->n_segments_coeff_reset = n_segments_coeff; @@ -68,12 +68,12 @@ NotchLite::NotchLite(float p_c_factor, n_deg_fred = 2 * length_; noise_pow_est = 0.0; filter_state_ = false; - z_0 = gr_complex(0, 0); - last_out = gr_complex(0, 0); + z_0 = gr_complex(0.0, 0.0); + last_out = gr_complex(0.0, 0.0); boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); - c_samples1 = gr_complex(0, 0); - c_samples2 = gr_complex(0, 0); + c_samples1 = gr_complex(0.0, 0.0); + c_samples2 = gr_complex(0.0, 0.0); angle1 = 0.0; angle2 = 0.0; power_spect = static_cast(volk_malloc(length_ * sizeof(float), volk_get_alignment())); @@ -89,7 +89,7 @@ NotchLite::~NotchLite() void NotchLite::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) { - for (unsigned int aux = 0; aux < ninput_items_required.size(); aux++) + for (uint32_t aux = 0; aux < ninput_items_required.size(); aux++) { ninput_items_required[aux] = length_; } @@ -99,7 +99,7 @@ void NotchLite::forecast(int noutput_items __attribute__((unused)), gr_vector_in int NotchLite::general_work(int noutput_items, gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - int index_out = 0; + int32_t index_out = 0; float sig2dB = 0.0; float sig2lin = 0.0; lv_32fc_t dot_prod_; @@ -138,7 +138,7 @@ int NotchLite::general_work(int noutput_items, gr_vector_int &ninput_items __att float angle_ = (angle1 + angle2) / 2.0; z_0 = std::exp(gr_complex(0, 1) * angle_); } - for (int aux = 0; aux < length_; aux++) + for (int32_t aux = 0; aux < length_; aux++) { *(out + aux) = *(in + aux) - z_0 * (*(in + aux - 1)) + p_c_factor * z_0 * last_out; last_out = *(out + aux); diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h index 531bedc13..c312c2b98 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_lite_cc.h @@ -34,13 +34,14 @@ #include #include #include +#include #include class NotchLite; typedef boost::shared_ptr notch_lite_sptr; -notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff); +notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset, int32_t n_segments_coeff); /*! * \brief This class implements a real-time software-defined multi state notch filter light version @@ -49,13 +50,13 @@ notch_lite_sptr make_notch_filter_lite(float p_c_factor, float pfa, int length_, class NotchLite : public gr::block { private: - int length_; - int n_segments; - int n_segments_est; - int n_segments_reset; - int n_segments_coeff_reset; - int n_segments_coeff; - int n_deg_fred; + int32_t length_; + int32_t n_segments; + int32_t n_segments_est; + int32_t n_segments_reset; + int32_t n_segments_coeff_reset; + int32_t n_segments_coeff; + int32_t n_deg_fred; float pfa; float thres_; float noise_pow_est; @@ -71,7 +72,7 @@ private: std::unique_ptr d_fft; public: - NotchLite(float p_c_factor, float pfa, int length_, int n_segments_est, int n_segments_reset, int n_segments_coeff); + NotchLite(float p_c_factor, float pfa, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset, int32_t n_segments_coeff); ~NotchLite(); diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc index 4a65097d0..ea1232c30 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.cc @@ -37,21 +37,21 @@ using google::LogMessage; -pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_, - int n_segments_est, int n_segments_reset) +pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int32_t length_, + int32_t n_segments_est, int32_t n_segments_reset) { return pulse_blanking_cc_sptr(new pulse_blanking_cc(pfa, length_, n_segments_est, n_segments_reset)); } pulse_blanking_cc::pulse_blanking_cc(float pfa, - int length_, - int n_segments_est, - int n_segments_reset) : gr::block("pulse_blanking_cc", - gr::io_signature::make(1, 1, sizeof(gr_complex)), - gr::io_signature::make(1, 1, sizeof(gr_complex))) + int32_t length_, + int32_t n_segments_est, + int32_t n_segments_reset) : gr::block("pulse_blanking_cc", + gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(gr_complex))) { - const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); + const int32_t alignment_multiple = volk_get_alignment() / sizeof(gr_complex); set_alignment(std::max(1, alignment_multiple)); this->pfa = pfa; this->length_ = length_; @@ -64,9 +64,9 @@ pulse_blanking_cc::pulse_blanking_cc(float pfa, boost::math::chi_squared_distribution my_dist_(n_deg_fred); thres_ = boost::math::quantile(boost::math::complement(my_dist_, pfa)); zeros_ = static_cast(volk_malloc(length_ * sizeof(gr_complex), volk_get_alignment())); - for (int aux = 0; aux < length_; aux++) + for (int32_t aux = 0; aux < length_; aux++) { - zeros_[aux] = gr_complex(0, 0); + zeros_[aux] = gr_complex(0.0, 0.0); } } @@ -79,7 +79,7 @@ pulse_blanking_cc::~pulse_blanking_cc() void pulse_blanking_cc::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) { - for (unsigned int aux = 0; aux < ninput_items_required.size(); aux++) + for (uint32_t aux = 0; aux < ninput_items_required.size(); aux++) { ninput_items_required[aux] = length_; } @@ -93,7 +93,7 @@ int pulse_blanking_cc::general_work(int noutput_items, gr_vector_int &ninput_ite gr_complex *out = reinterpret_cast(output_items[0]); float *magnitude = static_cast(volk_malloc(noutput_items * sizeof(float), volk_get_alignment())); volk_32fc_magnitude_squared_32f(magnitude, in, noutput_items); - int sample_index = 0; + int32_t sample_index = 0; float segment_energy; while ((sample_index + length_) < noutput_items) { diff --git a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h index 62e8ee0a7..4d0f72f00 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h +++ b/src/algorithms/input_filter/gnuradio_blocks/pulse_blanking_cc.h @@ -33,22 +33,23 @@ #include #include +#include class pulse_blanking_cc; typedef boost::shared_ptr pulse_blanking_cc_sptr; -pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int length_, int n_segments_est, int n_segments_reset); +pulse_blanking_cc_sptr make_pulse_blanking_cc(float pfa, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset); class pulse_blanking_cc : public gr::block { private: - int length_; - int n_segments; - int n_segments_est; - int n_segments_reset; - int n_deg_fred; + int32_t length_; + int32_t n_segments; + int32_t n_segments_est; + int32_t n_segments_reset; + int32_t n_deg_fred; bool last_filtered; float noise_power_estimation; float thres_; @@ -56,7 +57,7 @@ private: gr_complex *zeros_; public: - pulse_blanking_cc(float pfa, int length_, int n_segments_est, int n_segments_reset); + pulse_blanking_cc(float pfa, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset); ~pulse_blanking_cc(); diff --git a/src/algorithms/libs/CMakeLists.txt b/src/algorithms/libs/CMakeLists.txt index bdce5d1cf..9ef2da55c 100644 --- a/src/algorithms/libs/CMakeLists.txt +++ b/src/algorithms/libs/CMakeLists.txt @@ -18,60 +18,80 @@ add_subdirectory(rtklib) +set(GNSS_SPLIBS_SOURCES + gps_l2c_signal.cc + gps_l5_signal.cc + galileo_e1_signal_processing.cc + gnss_sdr_valve.cc + gnss_sdr_sample_counter.cc + gnss_signal_processing.cc + gps_sdr_signal_processing.cc + glonass_l1_signal_processing.cc + glonass_l2_signal_processing.cc + pass_through.cc + galileo_e5_signal_processing.cc + complex_byte_to_float_x2.cc + byte_x2_to_complex_byte.cc + cshort_to_float_x2.cc + short_x2_to_cshort.cc + complex_float_to_complex_byte.cc + conjugate_cc.cc + conjugate_sc.cc + conjugate_ic.cc + gnss_sdr_create_directory.cc + geofunctions.cc +) + +set(GNSS_SPLIBS_HEADERS + gps_l2c_signal.h + gps_l5_signal.h + galileo_e1_signal_processing.h + gnss_sdr_valve.h + gnss_sdr_sample_counter.h + gnss_signal_processing.h + gps_sdr_signal_processing.h + glonass_l1_signal_processing.h + glonass_l2_signal_processing.h + pass_through.h + galileo_e5_signal_processing.h + complex_byte_to_float_x2.h + byte_x2_to_complex_byte.h + cshort_to_float_x2.h + short_x2_to_cshort.h + complex_float_to_complex_byte.h + conjugate_cc.h + conjugate_sc.h + conjugate_ic.h + gnss_sdr_create_directory.h + gnss_circular_deque.h + geofunctions.h +) + if(ENABLE_FPGA) set(GNSS_SPLIBS_SOURCES - gps_l2c_signal.cc - gps_l5_signal.cc - galileo_e1_signal_processing.cc - gnss_sdr_valve.cc - gnss_sdr_sample_counter.cc + ${GNSS_SPLIBS_SOURCES} gnss_sdr_time_counter.cc - gnss_signal_processing.cc - gps_sdr_signal_processing.cc - glonass_l1_signal_processing.cc - glonass_l2_signal_processing.cc - pass_through.cc - galileo_e5_signal_processing.cc - complex_byte_to_float_x2.cc - byte_x2_to_complex_byte.cc - cshort_to_float_x2.cc - short_x2_to_cshort.cc - complex_float_to_complex_byte.cc - conjugate_cc.cc - conjugate_sc.cc - conjugate_ic.cc - ) -else(ENABLE_FPGA) - set(GNSS_SPLIBS_SOURCES - gps_l2c_signal.cc - gps_l5_signal.cc - galileo_e1_signal_processing.cc - gnss_sdr_valve.cc - gnss_sdr_sample_counter.cc - gnss_signal_processing.cc - gps_sdr_signal_processing.cc - glonass_l1_signal_processing.cc - glonass_l2_signal_processing.cc - pass_through.cc - galileo_e5_signal_processing.cc - complex_byte_to_float_x2.cc - byte_x2_to_complex_byte.cc - cshort_to_float_x2.cc - short_x2_to_cshort.cc - complex_float_to_complex_byte.cc - conjugate_cc.cc - conjugate_sc.cc - conjugate_ic.cc + gnss_sdr_fpga_sample_counter.cc ) -endif(ENABLE_FPGA) + set(GNSS_SPLIBS_HEADERS + ${GNSS_SPLIBS_HEADERS} + gnss_sdr_time_counter.h + gnss_sdr_fpga_sample_counter.h + ) +endif() if(OPENCL_FOUND) set(GNSS_SPLIBS_SOURCES ${GNSS_SPLIBS_SOURCES} - opencl/fft_execute.cc # Needs OpenCL - opencl/fft_setup.cc # Needs OpenCL - opencl/fft_kernelstring.cc # Needs OpenCL - ) -endif(OPENCL_FOUND) + opencl/fft_execute.cc # Needs OpenCL + opencl/fft_setup.cc # Needs OpenCL + opencl/fft_kernelstring.cc # Needs OpenCL + ) + set(GNSS_SPLIBS_HEADERS ${GNSS_SPLIBS_HEADERS} + opencl/fft_execute.h # Needs OpenCL + opencl/fft_setup.h # Needs OpenCL + opencl/fft_kernelstring.h # Needs OpenCL + ) +endif() include_directories( ${CMAKE_CURRENT_SOURCE_DIR} @@ -81,6 +101,7 @@ include_directories( ${Boost_INCLUDE_DIRS} ${GLOG_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} + ${ARMADILLO_INCLUDE_DIRS} ${GNURADIO_RUNTIME_INCLUDE_DIRS} ${GNURADIO_BLOCKS_INCLUDE_DIRS} ${VOLK_INCLUDE_DIRS} @@ -88,26 +109,28 @@ include_directories( ) if(OPENCL_FOUND) - include_directories( ${OPENCL_INCLUDE_DIRS} ) + include_directories(${OPENCL_INCLUDE_DIRS}) if(OS_IS_MACOSX) set(OPT_LIBRARIES ${OPT_LIBRARIES} "-framework OpenCL") - else(OS_IS_MACOSX) + else() set(OPT_LIBRARIES ${OPT_LIBRARIES} ${OPENCL_LIBRARIES}) - endif(OS_IS_MACOSX) -endif(OPENCL_FOUND) + endif() +endif() add_definitions(-DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}") -file(GLOB GNSS_SPLIBS_HEADERS "*.h") -list(REMOVE_ITEM GNSS_SPLIBS_HEADERS gnss_sdr_flags.h) list(SORT GNSS_SPLIBS_HEADERS) +list(SORT GNSS_SPLIBS_SOURCES) + add_library(gnss_sp_libs ${GNSS_SPLIBS_SOURCES} ${GNSS_SPLIBS_HEADERS}) source_group(Headers FILES ${GNSS_SPLIBS_HEADERS}) -target_link_libraries(gnss_sp_libs ${GNURADIO_RUNTIME_LIBRARIES} +target_link_libraries(gnss_sp_libs + ${GNURADIO_RUNTIME_LIBRARIES} ${VOLK_LIBRARIES} ${ORC_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${ORC_LIBRARIES} ${GFlags_LIBS} + ${ARMADILLO_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES} ${GNURADIO_FFT_LIBRARIES} ${GNURADIO_FILTER_LIBRARIES} @@ -115,13 +138,16 @@ target_link_libraries(gnss_sp_libs ${GNURADIO_RUNTIME_LIBRARIES} gnss_rx ) -if(NOT VOLK_GNSSSDR_FOUND) - add_dependencies(gnss_sp_libs volk_gnsssdr_module) -endif(NOT VOLK_GNSSSDR_FOUND) +if(NOT VOLKGNSSSDR_FOUND) + add_dependencies(gnss_sp_libs volk_gnsssdr_module + armadillo-${armadillo_RELEASE}) +else() + add_dependencies(gnss_sp_libs armadillo-${armadillo_RELEASE}) +endif() if(${GFLAGS_GREATER_20}) add_definitions(-DGFLAGS_GREATER_2_0=1) -endif(${GFLAGS_GREATER_20}) +endif() add_library(gnss_sdr_flags gnss_sdr_flags.cc gnss_sdr_flags.h) source_group(Headers FILES gnss_sdr_flags.h) diff --git a/src/algorithms/libs/galileo_e1_signal_processing.cc b/src/algorithms/libs/galileo_e1_signal_processing.cc index 2e0d224cf..3aaf2047c 100644 --- a/src/algorithms/libs/galileo_e1_signal_processing.cc +++ b/src/algorithms/libs/galileo_e1_signal_processing.cc @@ -33,16 +33,17 @@ #include "galileo_e1_signal_processing.h" #include "Galileo_E1.h" #include "gnss_signal_processing.h" +#include #include -void galileo_e1_code_gen_int(int* _dest, char _Signal[3], signed int _prn) +void galileo_e1_code_gen_int(int* _dest, char _Signal[3], int32_t _prn) { std::string _galileo_signal = _Signal; - signed int prn = _prn - 1; - int index = 0; + int32_t prn = _prn - 1; + int32_t index = 0; - /* A simple error check */ + // A simple error check if ((_prn < 1) || (_prn > 50)) { return; @@ -67,17 +68,17 @@ void galileo_e1_code_gen_int(int* _dest, char _Signal[3], signed int _prn) } -void galileo_e1_sinboc_11_gen_int(int* _dest, int* _prn, unsigned int _length_out) +void galileo_e1_sinboc_11_gen_int(int* _dest, int* _prn, uint32_t _length_out) { - const unsigned int _length_in = Galileo_E1_B_CODE_LENGTH_CHIPS; - unsigned int _period = static_cast(_length_out / _length_in); - for (unsigned int i = 0; i < _length_in; i++) + const uint32_t _length_in = Galileo_E1_B_CODE_LENGTH_CHIPS; + uint32_t _period = static_cast(_length_out / _length_in); + for (uint32_t i = 0; i < _length_in; i++) { - for (unsigned int j = 0; j < (_period / 2); j++) + for (uint32_t j = 0; j < (_period / 2); j++) { _dest[i * _period + j] = _prn[i]; } - for (unsigned int j = (_period / 2); j < _period; j++) + for (uint32_t j = (_period / 2); j < _period; j++) { _dest[i * _period + j] = -_prn[i]; } @@ -85,53 +86,55 @@ void galileo_e1_sinboc_11_gen_int(int* _dest, int* _prn, unsigned int _length_ou } -void galileo_e1_sinboc_61_gen_int(int* _dest, int* _prn, unsigned int _length_out) +void galileo_e1_sinboc_61_gen_int(int* _dest, int* _prn, uint32_t _length_out) { - const unsigned int _length_in = Galileo_E1_B_CODE_LENGTH_CHIPS; - unsigned int _period = static_cast(_length_out / _length_in); + const uint32_t _length_in = Galileo_E1_B_CODE_LENGTH_CHIPS; + uint32_t _period = static_cast(_length_out / _length_in); - for (unsigned int i = 0; i < _length_in; i++) + for (uint32_t i = 0; i < _length_in; i++) { - for (unsigned int j = 0; j < _period; j += 2) + for (uint32_t j = 0; j < _period; j += 2) { _dest[i * _period + j] = _prn[i]; } - for (unsigned int j = 1; j < _period; j += 2) + for (uint32_t j = 1; j < _period; j += 2) { _dest[i * _period + j] = -_prn[i]; } } } -void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], unsigned int _prn) + +void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], uint32_t _prn) { std::string _galileo_signal = _Signal; - unsigned int _codeLength = static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS); - int primary_code_E1_chips[4092]; // _codeLength not accepted by Clang + const uint32_t _codeLength = static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS); + int32_t primary_code_E1_chips[4092]; // _codeLength not accepted by Clang galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn); //generate Galileo E1 code, 1 sample per chip - for (unsigned int i = 0; i < _codeLength; i++) + for (uint32_t i = 0; i < _codeLength; i++) { _dest[2 * i] = static_cast(primary_code_E1_chips[i]); _dest[2 * i + 1] = -_dest[2 * i]; } } + void galileo_e1_gen_float(float* _dest, int* _prn, char _Signal[3]) { std::string _galileo_signal = _Signal; - const unsigned int _codeLength = 12 * Galileo_E1_B_CODE_LENGTH_CHIPS; + const uint32_t _codeLength = 12 * Galileo_E1_B_CODE_LENGTH_CHIPS; const float alpha = sqrt(10.0 / 11.0); const float beta = sqrt(1.0 / 11.0); - int sinboc_11[12 * 4092]; // _codeLength not accepted by Clang - int sinboc_61[12 * 4092]; + int32_t sinboc_11[12 * 4092] = {0}; // _codeLength not accepted by Clang + int32_t sinboc_61[12 * 4092] = {0}; galileo_e1_sinboc_11_gen_int(sinboc_11, _prn, _codeLength); //generate sinboc(1,1) 12 samples per chip galileo_e1_sinboc_61_gen_int(sinboc_61, _prn, _codeLength); //generate sinboc(6,1) 12 samples per chip if (_galileo_signal.rfind("1B") != std::string::npos && _galileo_signal.length() >= 2) { - for (unsigned int i = 0; i < _codeLength; i++) + for (uint32_t i = 0; i < _codeLength; i++) { _dest[i] = alpha * static_cast(sinboc_11[i]) + beta * static_cast(sinboc_61[i]); @@ -139,7 +142,7 @@ void galileo_e1_gen_float(float* _dest, int* _prn, char _Signal[3]) } else if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2) { - for (unsigned int i = 0; i < _codeLength; i++) + for (uint32_t i = 0; i < _codeLength; i++) { _dest[i] = alpha * static_cast(sinboc_11[i]) - beta * static_cast(sinboc_61[i]); @@ -149,21 +152,22 @@ void galileo_e1_gen_float(float* _dest, int* _prn, char _Signal[3]) void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3], - bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift, + bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift, bool _secondary_flag) { // This function is based on the GNU software GPS for MATLAB in Kay Borre's book std::string _galileo_signal = _Signal; - unsigned int _samplesPerCode; - const int _codeFreqBasis = Galileo_E1_CODE_CHIP_RATE_HZ; //Hz - unsigned int _codeLength = Galileo_E1_B_CODE_LENGTH_CHIPS; - int primary_code_E1_chips[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)]; - _samplesPerCode = static_cast(static_cast(_fs) / (static_cast(_codeFreqBasis) / static_cast(_codeLength))); - const int _samplesPerChip = (_cboc == true) ? 12 : 2; + uint32_t _samplesPerCode; + const int32_t _codeFreqBasis = Galileo_E1_CODE_CHIP_RATE_HZ; // Hz + uint32_t _codeLength = static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS); + int32_t* primary_code_E1_chips = static_cast(volk_gnsssdr_malloc(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) * sizeof(int32_t), volk_gnsssdr_get_alignment())); - const unsigned int delay = ((static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) - _chip_shift) % static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)) * _samplesPerCode / Galileo_E1_B_CODE_LENGTH_CHIPS; + _samplesPerCode = static_cast(static_cast(_fs) / (static_cast(_codeFreqBasis) / static_cast(_codeLength))); + const int32_t _samplesPerChip = (_cboc == true) ? 12 : 2; - galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn); //generate Galileo E1 code, 1 sample per chip + const uint32_t delay = ((static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) - _chip_shift) % static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)) * _samplesPerCode / Galileo_E1_B_CODE_LENGTH_CHIPS; + + galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn); // generate Galileo E1 code, 1 sample per chip float* _signal_E1; @@ -172,24 +176,26 @@ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3], if (_cboc == true) { - galileo_e1_gen_float(_signal_E1, primary_code_E1_chips, _Signal); //generate cboc 12 samples per chip + galileo_e1_gen_float(_signal_E1, primary_code_E1_chips, _Signal); // generate cboc 12 samples per chip } else { - int _signal_E1_int[_codeLength]; - galileo_e1_sinboc_11_gen_int(_signal_E1_int, primary_code_E1_chips, _codeLength); //generate sinboc(1,1) 2 samples per chip + int32_t* _signal_E1_int = static_cast(volk_gnsssdr_malloc(_codeLength * sizeof(int32_t), volk_gnsssdr_get_alignment())); + galileo_e1_sinboc_11_gen_int(_signal_E1_int, primary_code_E1_chips, _codeLength); // generate sinboc(1,1) 2 samples per chip - for (unsigned int ii = 0; ii < _codeLength; ++ii) + for (uint32_t ii = 0; ii < _codeLength; ++ii) { _signal_E1[ii] = static_cast(_signal_E1_int[ii]); } + volk_gnsssdr_free(_signal_E1_int); } if (_fs != _samplesPerChip * _codeFreqBasis) { float* _resampled_signal = new float[_samplesPerCode]; + resampler(_signal_E1, _resampled_signal, _samplesPerChip * _codeFreqBasis, _fs, - _codeLength, _samplesPerCode); //resamples code to fs + _codeLength, _samplesPerCode); // resamples code to fs delete[] _signal_E1; _signal_E1 = _resampled_signal; @@ -197,9 +203,9 @@ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3], if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2 && _secondary_flag) { - float* _signal_E1C_secondary = new float[static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH) * _samplesPerCode]; + float* _signal_E1C_secondary = new float[static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH) * _samplesPerCode]; - for (unsigned int i = 0; i < static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); i++) + for (uint32_t i = 0; i < static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); i++) { for (unsigned k = 0; k < _samplesPerCode; k++) { @@ -207,55 +213,57 @@ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3], } } - _samplesPerCode *= static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); + _samplesPerCode *= static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); delete[] _signal_E1; _signal_E1 = _signal_E1C_secondary; } - for (unsigned int i = 0; i < _samplesPerCode; i++) + for (uint32_t i = 0; i < _samplesPerCode; i++) { _dest[(i + delay) % _samplesPerCode] = _signal_E1[i]; } delete[] _signal_E1; + volk_gnsssdr_free(primary_code_E1_chips); } void galileo_e1_code_gen_complex_sampled(std::complex* _dest, char _Signal[3], - bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift, + bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift, bool _secondary_flag) { std::string _galileo_signal = _Signal; - const int _codeFreqBasis = Galileo_E1_CODE_CHIP_RATE_HZ; //Hz - unsigned int _samplesPerCode = static_cast(static_cast(_fs) / - (static_cast(_codeFreqBasis) / static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS))); + const int32_t _codeFreqBasis = Galileo_E1_CODE_CHIP_RATE_HZ; // Hz + uint32_t _samplesPerCode = static_cast(static_cast(_fs) / + (static_cast(_codeFreqBasis) / static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS))); if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2 && _secondary_flag) { - _samplesPerCode *= static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); + _samplesPerCode *= static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); } - float real_code[_samplesPerCode]; + float* real_code = static_cast(volk_gnsssdr_malloc(_samplesPerCode * sizeof(float), volk_gnsssdr_get_alignment())); galileo_e1_code_gen_float_sampled(real_code, _Signal, _cboc, _prn, _fs, _chip_shift, _secondary_flag); - for (unsigned int ii = 0; ii < _samplesPerCode; ++ii) + for (uint32_t ii = 0; ii < _samplesPerCode; ++ii) { _dest[ii] = std::complex(real_code[ii], 0.0f); } + volk_gnsssdr_free(real_code); } void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3], - bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift) + bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift) { galileo_e1_code_gen_float_sampled(_dest, _Signal, _cboc, _prn, _fs, _chip_shift, false); } void galileo_e1_code_gen_complex_sampled(std::complex* _dest, char _Signal[3], - bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift) + bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift) { galileo_e1_code_gen_complex_sampled(_dest, _Signal, _cboc, _prn, _fs, _chip_shift, false); } diff --git a/src/algorithms/libs/galileo_e1_signal_processing.h b/src/algorithms/libs/galileo_e1_signal_processing.h index f7133fd2d..6784e6f22 100644 --- a/src/algorithms/libs/galileo_e1_signal_processing.h +++ b/src/algorithms/libs/galileo_e1_signal_processing.h @@ -33,12 +33,13 @@ #define GNSS_SDR_GALILEO_E1_SIGNAL_PROCESSING_H_ #include +#include /*! * \brief This function generates Galileo E1 code (can select E1B or E1C sinboc). * */ -void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], unsigned int _prn); +void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], uint32_t _prn); /*! * \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc @@ -46,7 +47,7 @@ void galileo_e1_code_gen_sinboc11_float(float* _dest, char _Signal[3], unsigned * */ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3], - bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift, + bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift, bool _secondary_flag); /*! @@ -55,7 +56,7 @@ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3], * */ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3], - bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift); + bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift); /*! * \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc @@ -63,13 +64,13 @@ void galileo_e1_code_gen_float_sampled(float* _dest, char _Signal[3], * */ void galileo_e1_code_gen_complex_sampled(std::complex* _dest, char _Signal[3], - bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift, + bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift, bool _secondary_flag); /*! * \brief galileo_e1_code_gen_complex_sampled without _secondary_flag for backward compatibility. */ void galileo_e1_code_gen_complex_sampled(std::complex* _dest, char _Signal[3], - bool _cboc, unsigned int _prn, signed int _fs, unsigned int _chip_shift); + bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift); #endif /* GNSS_SDR_GALILEO_E1_SIGNAL_PROCESSING_H_ */ diff --git a/src/algorithms/libs/galileo_e5_signal_processing.cc b/src/algorithms/libs/galileo_e5_signal_processing.cc index ca6eb675a..82ef4ed54 100644 --- a/src/algorithms/libs/galileo_e5_signal_processing.cc +++ b/src/algorithms/libs/galileo_e5_signal_processing.cc @@ -37,11 +37,11 @@ #include -void galileo_e5_a_code_gen_complex_primary(std::complex* _dest, signed int _prn, char _Signal[3]) +void galileo_e5_a_code_gen_complex_primary(std::complex* _dest, int32_t _prn, char _Signal[3]) { - unsigned int prn = _prn - 1; - unsigned int index = 0; - int a[4]; + uint32_t prn = _prn - 1; + uint32_t index = 0; + int32_t a[4]; if ((_prn < 1) || (_prn > 50)) { return; @@ -80,7 +80,7 @@ void galileo_e5_a_code_gen_complex_primary(std::complex* _dest, signed in } else if (_Signal[0] == '5' && _Signal[1] == 'X') { - int b[4]; + int32_t b[4]; for (size_t i = 0; i < Galileo_E5a_I_PRIMARY_CODE[prn].length() - 1; i++) { hex_to_binary_converter(a, Galileo_E5a_I_PRIMARY_CODE[prn].at(i)); @@ -99,19 +99,20 @@ void galileo_e5_a_code_gen_complex_primary(std::complex* _dest, signed in } } + void galileo_e5_a_code_gen_complex_sampled(std::complex* _dest, char _Signal[3], - unsigned int _prn, signed int _fs, unsigned int _chip_shift) + uint32_t _prn, int32_t _fs, uint32_t _chip_shift) { - unsigned int _samplesPerCode; - unsigned int delay; - const unsigned int _codeLength = Galileo_E5a_CODE_LENGTH_CHIPS; - const int _codeFreqBasis = Galileo_E5a_CODE_CHIP_RATE_HZ; + uint32_t _samplesPerCode; + uint32_t delay; + const uint32_t _codeLength = Galileo_E5a_CODE_LENGTH_CHIPS; + const int32_t _codeFreqBasis = Galileo_E5a_CODE_CHIP_RATE_HZ; std::complex* _code = new std::complex[_codeLength](); galileo_e5_a_code_gen_complex_primary(_code, _prn, _Signal); - _samplesPerCode = static_cast(static_cast(_fs) / (static_cast(_codeFreqBasis) / static_cast(_codeLength))); + _samplesPerCode = static_cast(static_cast(_fs) / (static_cast(_codeFreqBasis) / static_cast(_codeLength))); delay = ((_codeLength - _chip_shift) % _codeLength) * _samplesPerCode / _codeLength; @@ -121,21 +122,15 @@ void galileo_e5_a_code_gen_complex_sampled(std::complex* _dest, char _Sig if (posix_memalign((void**)&_resampled_signal, 16, _samplesPerCode * sizeof(gr_complex)) == 0) { }; - resampler(_code, _resampled_signal, _codeFreqBasis, _fs, _codeLength, _samplesPerCode); //resamples code to fs + resampler(_code, _resampled_signal, _codeFreqBasis, _fs, _codeLength, _samplesPerCode); // resamples code to fs delete[] _code; _code = _resampled_signal; } - for (unsigned int i = 0; i < _samplesPerCode; i++) + for (uint32_t i = 0; i < _samplesPerCode; i++) { _dest[(i + delay) % _samplesPerCode] = _code[i]; } - if (_fs != _codeFreqBasis) - { - free(_code); - } - else - { - delete[] _code; - } + + delete[] _code; } diff --git a/src/algorithms/libs/galileo_e5_signal_processing.h b/src/algorithms/libs/galileo_e5_signal_processing.h index 998d3b98f..46deaae24 100644 --- a/src/algorithms/libs/galileo_e5_signal_processing.h +++ b/src/algorithms/libs/galileo_e5_signal_processing.h @@ -35,23 +35,23 @@ #define GNSS_SDR_GALILEO_E5_SIGNAL_PROCESSING_H_ #include +#include /*! * \brief Generates Galileo E5a code at 1 sample/chip * bool _pilot generates E5aQ code if true and E5aI (data signal) if false. */ -void galileo_e5_a_code_gen_complex_primary(std::complex* _dest, signed int _prn, char _Signal[3]); +void galileo_e5_a_code_gen_complex_primary(std::complex* _dest, int32_t _prn, char _Signal[3]); - -void galileo_e5_a_code_gen_tiered(std::complex* _dest, std::complex* _primary, unsigned int _prn, char _Signal[3]); +void galileo_e5_a_code_gen_tiered(std::complex* _dest, std::complex* _primary, uint32_t _prn, char _Signal[3]); /*! * \brief Generates Galileo E5a complex code, shifted to the desired chip and sampled at a frequency fs * bool _pilot generates E5aQ code if true and E5aI (data signal) if false. */ void galileo_e5_a_code_gen_complex_sampled(std::complex* _dest, - char _Signal[3], unsigned int _prn, signed int _fs, unsigned int _chip_shift); + char _Signal[3], uint32_t _prn, int32_t _fs, uint32_t _chip_shift); #endif /* GNSS_SDR_GALILEO_E5_SIGNAL_PROCESSING_H_ */ diff --git a/src/algorithms/libs/geofunctions.cc b/src/algorithms/libs/geofunctions.cc new file mode 100644 index 000000000..bf67e07f8 --- /dev/null +++ b/src/algorithms/libs/geofunctions.cc @@ -0,0 +1,775 @@ +/*! + * \file geofunctions.cc + * \brief A set of coordinate transformations functions and helpers, + * some of them migrated from MATLAB, for geographic information systems. + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "geofunctions.h" + +const double STRP_PI = 3.1415926535898; // Pi as defined in IS-GPS-200E + +arma::mat Skew_symmetric(const arma::vec &a) +{ + arma::mat A = arma::zeros(3, 3); + + A << 0.0 << -a(2) << a(1) << arma::endr + << a(2) << 0.0 << -a(0) << arma::endr + << -a(1) << a(0) << 0 << arma::endr; + + // {{0, -a(2), a(1)}, + // {a(2), 0, -a(0)}, + // {-a(1), a(0), 0}}; + return A; +} + + +double WGS84_g0(double Lat_rad) +{ + const double k = 0.001931853; // normal gravity constant + const double e2 = 0.00669438002290; // the square of the first numerical eccentricity + const double nge = 9.7803253359; // normal gravity value on the equator (m/sec^2) + double b = sin(Lat_rad); // Lat in degrees + b = b * b; + double g0 = nge * (1 + k * b) / (sqrt(1 - e2 * b)); + return g0; +} + + +double WGS84_geocentric_radius(double Lat_geodetic_rad) +{ + // WGS84 earth model Geocentric radius (Eq. 2.88) + const double WGS84_A = 6378137.0; // Semi-major axis of the Earth, a [m] + const double WGS84_IF = 298.257223563; // Inverse flattening of the Earth + const double WGS84_F = (1.0 / WGS84_IF); // The flattening of the Earth + // double WGS84_B=(WGS84_A*(1-WGS84_F)); // Semi-minor axis of the Earth [m] + double WGS84_E = (sqrt(2 * WGS84_F - WGS84_F * WGS84_F)); // Eccentricity of the Earth + + // transverse radius of curvature + double R_E = WGS84_A / sqrt(1 - WGS84_E * WGS84_E * sin(Lat_geodetic_rad) * sin(Lat_geodetic_rad)); // (Eq. 2.66) + + // geocentric radius at the Earth surface + double r_eS = R_E * sqrt(cos(Lat_geodetic_rad) * cos(Lat_geodetic_rad) + + (1 - WGS84_E * WGS84_E) * (1 - WGS84_E * WGS84_E) * sin(Lat_geodetic_rad) * sin(Lat_geodetic_rad)); // (Eq. 2.88) + return r_eS; +} + + +int topocent(double *Az, double *El, double *D, const arma::vec &x, const arma::vec &dx) +{ + double lambda; + double phi; + double h; + const double dtr = STRP_PI / 180.0; + const double a = 6378137.0; // semi-major axis of the reference ellipsoid WGS-84 + const double finv = 298.257223563; // inverse of flattening of the reference ellipsoid WGS-84 + + // Transform x into geodetic coordinates + togeod(&phi, &lambda, &h, a, finv, x(0), x(1), x(2)); + + double cl = cos(lambda * dtr); + double sl = sin(lambda * dtr); + double cb = cos(phi * dtr); + double sb = sin(phi * dtr); + + arma::mat F = {{-sl, -sb * cl, cb * cl}, + {cl, -sb * sl, cb * sl}, + {0.0, cb, sb}}; + + arma::vec local_vector; + + local_vector = arma::htrans(F) * dx; + + double E = local_vector(0); + double N = local_vector(1); + double U = local_vector(2); + + double hor_dis; + hor_dis = sqrt(E * E + N * N); + + if (hor_dis < 1.0E-20) + { + *Az = 0.0; + *El = 90.0; + } + else + { + *Az = atan2(E, N) / dtr; + *El = atan2(U, hor_dis) / dtr; + } + + if (*Az < 0) + { + *Az = *Az + 360.0; + } + + *D = sqrt(dx(0) * dx(0) + dx(1) * dx(1) + dx(2) * dx(2)); + return 0; +} + + +int togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z) +{ + *h = 0.0; + const double tolsq = 1.e-10; // tolerance to accept convergence + const int maxit = 10; // max number of iterations + const double rtd = 180.0 / STRP_PI; + + // compute square of eccentricity + double esq; + if (finv < 1.0E-20) + { + esq = 0.0; + } + else + { + esq = (2.0 - 1.0 / finv) / finv; + } + + // first guess + double P = sqrt(X * X + Y * Y); // P is distance from spin axis + + // direct calculation of longitude + if (P > 1.0E-20) + { + *dlambda = atan2(Y, X) * rtd; + } + else + { + *dlambda = 0.0; + } + + // correct longitude bound + if (*dlambda < 0) + { + *dlambda = *dlambda + 360.0; + } + + double r = sqrt(P * P + Z * Z); // r is distance from origin (0,0,0) + + double sinphi; + if (r > 1.0E-20) + { + sinphi = Z / r; + } + else + { + sinphi = 0.0; + } + *dphi = asin(sinphi); + + // initial value of height = distance from origin minus + // approximate distance from origin to surface of ellipsoid + if (r < 1.0E-20) + { + *h = 0.0; + return 1; + } + + *h = r - a * (1 - sinphi * sinphi / finv); + + // iterate + double cosphi; + double N_phi; + double dP; + double dZ; + double oneesq = 1.0 - esq; + + for (int i = 0; i < maxit; i++) + { + sinphi = sin(*dphi); + cosphi = cos(*dphi); + + // compute radius of curvature in prime vertical direction + N_phi = a / sqrt(1.0 - esq * sinphi * sinphi); + + // compute residuals in P and Z + dP = P - (N_phi + (*h)) * cosphi; + dZ = Z - (N_phi * oneesq + (*h)) * sinphi; + + // update height and latitude + *h = *h + (sinphi * dZ + cosphi * dP); + *dphi = *dphi + (cosphi * dZ - sinphi * dP) / (N_phi + (*h)); + + // test for convergence + if ((dP * dP + dZ * dZ) < tolsq) + { + break; + } + if (i == (maxit - 1)) + { + // LOG(WARNING) << "The computation of geodetic coordinates did not converge"; + } + } + *dphi = (*dphi) * rtd; + return 0; +} + + +arma::mat Gravity_ECEF(const arma::vec &r_eb_e) +{ + // Parameters + const double R_0 = 6378137.0; // WGS84 Equatorial radius in meters + const double mu = 3.986004418E14; // WGS84 Earth gravitational constant (m^3 s^-2) + const double J_2 = 1.082627E-3; // WGS84 Earth's second gravitational constant + const double omega_ie = 7.292115E-5; // Earth rotation rate (rad/s) + // Calculate distance from center of the Earth + double mag_r = sqrt(arma::as_scalar(r_eb_e.t() * r_eb_e)); + // If the input position is 0,0,0, produce a dummy output + arma::vec g = arma::zeros(3, 1); + if (mag_r != 0) + { + // Calculate gravitational acceleration using (2.142) + double z_scale = 5 * pow((r_eb_e(2) / mag_r), 2); + arma::vec tmp_vec = {(1 - z_scale) * r_eb_e(0), + (1 - z_scale) * r_eb_e(1), + (3 - z_scale) * r_eb_e(2)}; + arma::vec gamma_ = (-mu / pow(mag_r, 3)) * (r_eb_e + 1.5 * J_2 * pow(R_0 / mag_r, 2) * tmp_vec); + + // Add centripetal acceleration using (2.133) + g(0) = gamma_(0) + pow(omega_ie, 2) * r_eb_e(0); + g(1) = gamma_(1) + pow(omega_ie, 2) * r_eb_e(1); + g(2) = gamma_(2); + } + return g; +} + + +arma::vec LLH_to_deg(const arma::vec &LLH) +{ + const double rtd = 180.0 / STRP_PI; + arma::vec deg = arma::zeros(3, 1); + deg(0) = LLH(0) * rtd; + deg(1) = LLH(1) * rtd; + deg(2) = LLH(2); + return deg; +} + + +double degtorad(double angleInDegrees) +{ + double angleInRadians = (STRP_PI / 180.0) * angleInDegrees; + return angleInRadians; +} + + +double radtodeg(double angleInRadians) +{ + double angleInDegrees = (180.0 / STRP_PI) * angleInRadians; + return angleInDegrees; +} + + +double mstoknotsh(double MetersPerSeconds) +{ + double knots = mstokph(MetersPerSeconds) * 0.539957; + return knots; +} + + +double mstokph(double MetersPerSeconds) +{ + double kph = 3600.0 * MetersPerSeconds / 1e3; + return kph; +} + + +arma::vec CTM_to_Euler(const arma::mat &C) +{ + // Calculate Euler angles using (2.23) + arma::mat CTM(C); + arma::vec eul = arma::zeros(3, 1); + eul(0) = atan2(CTM(1, 2), CTM(2, 2)); // roll + if (CTM(0, 2) < -1.0) CTM(0, 2) = -1.0; + if (CTM(0, 2) > 1.0) CTM(0, 2) = 1.0; + eul(1) = -asin(CTM(0, 2)); // pitch + eul(2) = atan2(CTM(0, 1), CTM(0, 0)); // yaw + return eul; +} + + +arma::mat Euler_to_CTM(const arma::vec &eul) +{ + // Eq.2.15 + // Euler angles to Attitude matrix is equivalent to rotate the body + // in the three axes: + // arma::mat Ax= {{1,0,0}, {0,cos(Att_phi),sin(Att_phi)} ,{0,-sin(Att_phi),cos(Att_phi)}}; + // arma::mat Ay= {{cos(Att_theta), 0, -sin(Att_theta)}, {0,1,0} , {sin(Att_theta), 0, cos(Att_theta)}}; + // arma::mat Az= {{cos(Att_psi), sin(Att_psi), 0}, {-sin(Att_psi), cos(Att_psi), 0},{0,0,1}}; + // arma::mat C_b_n=Ax*Ay*Az; // Attitude expressed in the LOCAL FRAME (NED) + // C_b_n=C_b_n.t(); + + // Precalculate sines and cosines of the Euler angles + double sin_phi = sin(eul(0)); + double cos_phi = cos(eul(0)); + double sin_theta = sin(eul(1)); + double cos_theta = cos(eul(1)); + double sin_psi = sin(eul(2)); + double cos_psi = cos(eul(2)); + + // Calculate coordinate transformation matrix using (2.22) + arma::mat C = {{cos_theta * cos_psi, cos_theta * sin_psi, -sin_theta}, + {-cos_phi * sin_psi + sin_phi * sin_theta * cos_psi, cos_phi * cos_psi + sin_phi * sin_theta * sin_psi, sin_phi * cos_theta}, + {sin_phi * sin_psi + cos_phi * sin_theta * cos_psi, -sin_phi * cos_psi + cos_phi * sin_theta * sin_psi, cos_phi * cos_theta}}; + return C; +} + + +arma::vec cart2geo(const arma::vec &XYZ, int elipsoid_selection) +{ + const double a[5] = {6378388.0, 6378160.0, 6378135.0, 6378137.0, 6378137.0}; + const double f[5] = {1.0 / 297.0, 1.0 / 298.247, 1.0 / 298.26, 1.0 / 298.257222101, 1.0 / 298.257223563}; + + double lambda = atan2(XYZ[1], XYZ[0]); + double ex2 = (2.0 - f[elipsoid_selection]) * f[elipsoid_selection] / ((1.0 - f[elipsoid_selection]) * (1.0 - f[elipsoid_selection])); + double c = a[elipsoid_selection] * sqrt(1.0 + ex2); + double phi = atan(XYZ[2] / ((sqrt(XYZ[0] * XYZ[0] + XYZ[1] * XYZ[1]) * (1.0 - (2.0 - f[elipsoid_selection])) * f[elipsoid_selection]))); + + double h = 0.1; + double oldh = 0.0; + double N; + int iterations = 0; + do + { + oldh = h; + N = c / sqrt(1.0 + ex2 * (cos(phi) * cos(phi))); + phi = atan(XYZ[2] / ((sqrt(XYZ[0] * XYZ[0] + XYZ[1] * XYZ[1]) * (1.0 - (2.0 - f[elipsoid_selection]) * f[elipsoid_selection] * N / (N + h))))); + h = sqrt(XYZ[0] * XYZ[0] + XYZ[1] * XYZ[1]) / cos(phi) - N; + iterations = iterations + 1; + if (iterations > 100) + { + // std::cout << "Failed to approximate h with desired precision. h-oldh= " << h - oldh; + break; + } + } + while (std::fabs(h - oldh) > 1.0e-12); + + arma::vec LLH = {{phi, lambda, h}}; // radians + return LLH; +} + + +void ECEF_to_Geo(const arma::vec &r_eb_e, const arma::vec &v_eb_e, const arma::mat &C_b_e, arma::vec &LLH, arma::vec &v_eb_n, arma::mat &C_b_n) +{ + // Compute the Latitude of the ECEF position + LLH = cart2geo(r_eb_e, 4); // ECEF -> WGS84 geographical + + // Calculate ECEF to Geographical coordinate transformation matrix using (2.150) + double cos_lat = cos(LLH(0)); + double sin_lat = sin(LLH(0)); + double cos_long = cos(LLH(1)); + double sin_long = sin(LLH(1)); + // C++11 and arma >= 5.2 + // arma::mat C_e_n = {{-sin_lat * cos_long, -sin_lat * sin_long, cos_lat}, + // {-sin_long, cos_long, 0}, + // {-cos_lat * cos_long, -cos_lat * sin_long, -sin_lat}}; //ECEF to Geo + arma::mat C_e_n = arma::zeros(3, 3); + C_e_n << -sin_lat * cos_long << -sin_lat * sin_long << cos_lat << arma::endr + << -sin_long << cos_long << 0 << arma::endr + << -cos_lat * cos_long << -cos_lat * sin_long << -sin_lat << arma::endr; // ECEF to Geo + // Transform velocity using (2.73) + v_eb_n = C_e_n * v_eb_e; + + C_b_n = C_e_n * C_b_e; // Attitude conversion from ECEF to NED +} + + +void Geo_to_ECEF(const arma::vec &LLH, const arma::vec &v_eb_n, const arma::mat &C_b_n, arma::vec &r_eb_e, arma::vec &v_eb_e, arma::mat &C_b_e) +{ + // Parameters + double R_0 = 6378137.0; // WGS84 Equatorial radius in meters + double e = 0.0818191908425; // WGS84 eccentricity + + // Calculate transverse radius of curvature using (2.105) + double R_E = R_0 / sqrt(1.0 - (e * sin(LLH(0))) * (e * sin(LLH(0)))); + + // Convert position using (2.112) + double cos_lat = cos(LLH(0)); + double sin_lat = sin(LLH(0)); + double cos_long = cos(LLH(1)); + double sin_long = sin(LLH(1)); + r_eb_e = {(R_E + LLH(2)) * cos_lat * cos_long, + (R_E + LLH(2)) * cos_lat * sin_long, + ((1 - e * e) * R_E + LLH(2)) * sin_lat}; + + // Calculate ECEF to Geo coordinate transformation matrix using (2.150) + // C++11 and arma>=5.2 + // arma::mat C_e_n = {{-sin_lat * cos_long, -sin_lat * sin_long, cos_lat}, + // {-sin_long, cos_long, 0}, + // {-cos_lat * cos_long, -cos_lat * sin_long, -sin_lat}}; + arma::mat C_e_n = arma::zeros(3, 3); + C_e_n << -sin_lat * cos_long << -sin_lat * sin_long << cos_lat << arma::endr + << -sin_long << cos_long << 0 << arma::endr + << -cos_lat * cos_long << -cos_lat * sin_long << -sin_lat << arma::endr; + + // Transform velocity using (2.73) + v_eb_e = C_e_n.t() * v_eb_n; + + // Transform attitude using (2.15) + C_b_e = C_e_n.t() * C_b_n; +} + + +void pv_Geo_to_ECEF(double L_b, double lambda_b, double h_b, const arma::vec &v_eb_n, arma::vec &r_eb_e, arma::vec &v_eb_e) +{ + // Parameters + const double R_0 = 6378137.0; // WGS84 Equatorial radius in meters + const double e = 0.0818191908425; // WGS84 eccentricity + + // Calculate transverse radius of curvature using (2.105) + double R_E = R_0 / sqrt(1 - pow(e * sin(L_b), 2)); + + // Convert position using (2.112) + double cos_lat = cos(L_b); + double sin_lat = sin(L_b); + double cos_long = cos(lambda_b); + double sin_long = sin(lambda_b); + r_eb_e = {(R_E + h_b) * cos_lat * cos_long, + (R_E + h_b) * cos_lat * sin_long, + ((1 - pow(e, 2)) * R_E + h_b) * sin_lat}; + + // Calculate ECEF to Geo coordinate transformation matrix using (2.150) + arma::mat C_e_n = arma::zeros(3, 3); + C_e_n << -sin_lat * cos_long << -sin_lat * sin_long << cos_lat << arma::endr + << -sin_long << cos_long << 0 << arma::endr + << -cos_lat * cos_long << -cos_lat * sin_long << -sin_lat << arma::endr; + + // Transform velocity using (2.73) + v_eb_e = C_e_n.t() * v_eb_n; +} + + +double great_circle_distance(double lat1, double lon1, double lat2, double lon2) +{ + // The Haversine formula determines the great-circle distance between two points on a sphere given their longitudes and latitudes. + // generally used geo measurement function + double R = 6378.137; // Radius of earth in KM + double dLat = lat2 * STRP_PI / 180.0 - lat1 * STRP_PI / 180.0; + double dLon = lon2 * STRP_PI / 180.0 - lon1 * STRP_PI / 180.0; + double a = sin(dLat / 2.0) * sin(dLat / 2.0) + + cos(lat1 * STRP_PI / 180.0) * cos(lat2 * STRP_PI / 180.0) * + sin(dLon / 2) * sin(dLon / 2.0); + double c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a)); + double d = R * c; + return d * 1000.0; // meters +} + + +void cart2utm(const arma::vec &r_eb_e, int zone, arma::vec &r_enu) +{ + // Transformation of (X,Y,Z) to (E,N,U) in UTM, zone 'zone' + // + // Inputs: + // r_eb_e - Cartesian coordinates. Coordinates are referenced + // with respect to the International Terrestrial Reference + // Frame 1996 (ITRF96) + // zone - UTM zone of the given position + // + // Outputs: + // r_enu - UTM coordinates (Easting, Northing, Uping) + // + // Originally written in Matlab by Kai Borre, Nov. 1994 + // Implemented in C++ by J.Arribas + // + // This implementation is based upon + // O. Andersson & K. Poder (1981) Koordinattransformationer + // ved Geod\ae{}tisk Institut. Landinspekt\oe{}ren + // Vol. 30: 552--571 and Vol. 31: 76 + // + // An excellent, general reference (KW) is + // R. Koenig & K.H. Weise (1951) Mathematische Grundlagen der + // h\"oheren Geod\"asie und Kartographie. + // Erster Band, Springer Verlag + // + // Explanation of variables used: + // f flattening of ellipsoid + // a semi major axis in m + // m0 1 - scale at central meridian; for UTM 0.0004 + // Q_n normalized meridian quadrant + // E0 Easting of central meridian + // L0 Longitude of central meridian + // bg constants for ellipsoidal geogr. to spherical geogr. + // gb constants for spherical geogr. to ellipsoidal geogr. + // gtu constants for ellipsoidal N, E to spherical N, E + // utg constants for spherical N, E to ellipoidal N, E + // tolutm tolerance for utm, 1.2E-10*meridian quadrant + // tolgeo tolerance for geographical, 0.00040 second of arc + // + // B, L refer to latitude and longitude. Southern latitude is negative + // International ellipsoid of 1924, valid for ED50 + + double a = 6378388.0; + double f = 1.0 / 297.0; + double ex2 = (2.0 - f) * f / ((1.0 - f) * (1.0 - f)); + double c = a * sqrt(1.0 + ex2); + arma::vec vec = r_eb_e; + vec(2) = vec(2) - 4.5; + double alpha = 0.756e-6; + arma::mat R = {{1.0, -alpha, 0.0}, {alpha, 1.0, 0.0}, {0.0, 0.0, 1.0}}; + arma::vec trans = {89.5, 93.8, 127.6}; + double scale = 0.9999988; + arma::vec v = scale * R * vec + trans; // coordinate vector in ED50 + double L = atan2(v(1), v(0)); + double N1 = 6395000.0; // preliminary value + double B = atan2(v(2) / ((1.0 - f) * (1.0 - f) * N1), arma::norm(v.subvec(0, 1)) / N1); // preliminary value + double U = 0.1; + double oldU = 0.0; + int iterations = 0; + while (fabs(U - oldU) > 1.0E-4) + { + oldU = U; + N1 = c / sqrt(1.0 + ex2 * (cos(B) * cos(B))); + B = atan2(v(2) / ((1.0 - f) * (1.0 - f) * N1 + U), arma::norm(v.subvec(0, 1)) / (N1 + U)); + U = arma::norm(v.subvec(0, 1)) / cos(B) - N1; + iterations = iterations + 1; + if (iterations > 100) + { + std::cout << "Failed to approximate U with desired precision. U-oldU:" << U - oldU << std::endl; + break; + } + } + // Normalized meridian quadrant, KW p. 50 (96), p. 19 (38b), p. 5 (21) + double m0 = 0.0004; + double n = f / (2.0 - f); + double m = n * n * (1.0 / 4.0 + n * n / 64.0); + double w = (a * (-n - m0 + m * (1.0 - m0))) / (1.0 + n); + double Q_n = a + w; + + // Easting and longitude of central meridian + double E0 = 500000.0; + double L0 = (zone - 30) * 6.0 - 3.0; + + // Check tolerance for reverse transformation + // double tolutm = STRP_PI / 2.0 * 1.2e-10 * Q_n; + // double tolgeo = 0.000040; + // Coefficients of trigonometric series + // + // ellipsoidal to spherical geographical, KW p .186 --187, (51) - (52) + // bg[1] = n * (-2 + n * (2 / 3 + n * (4 / 3 + n * (-82 / 45)))); + // bg[2] = n ^ 2 * (5 / 3 + n * (-16 / 15 + n * (-13 / 9))); + // bg[3] = n ^ 3 * (-26 / 15 + n * 34 / 21); + // bg[4] = n ^ 4 * 1237 / 630; + // + // spherical to ellipsoidal geographical, KW p.190 --191, (61) - (62) % gb[1] = n * (2 + n * (-2 / 3 + n * (-2 + n * 116 / 45))); + // gb[2] = n ^ 2 * (7 / 3 + n * (-8 / 5 + n * (-227 / 45))); + // gb[3] = n ^ 3 * (56 / 15 + n * (-136 / 35)); + // gb[4] = n ^ 4 * 4279 / 630; + // + // spherical to ellipsoidal N, E, KW p.196, (69) % gtu[1] = n * (1 / 2 + n * (-2 / 3 + n * (5 / 16 + n * 41 / 180))); + // gtu[2] = n ^ 2 * (13 / 48 + n * (-3 / 5 + n * 557 / 1440)); + // gtu[3] = n ^ 3 * (61 / 240 + n * (-103 / 140)); + // gtu[4] = n ^ 4 * 49561 / 161280; + // + // ellipsoidal to spherical N, E, KW p.194, (65) % utg[1] = n * (-1 / 2 + n * (2 / 3 + n * (-37 / 96 + n * 1 / 360))); + // utg[2] = n ^ 2 * (-1 / 48 + n * (-1 / 15 + n * 437 / 1440)); + // utg[3] = n ^ 3 * (-17 / 480 + n * 37 / 840); + // utg[4] = n ^ 4 * (-4397 / 161280); + // + // With f = 1 / 297 we get + + arma::colvec bg = {-3.37077907e-3, + 4.73444769e-6, + -8.29914570e-9, + 1.58785330e-11}; + + arma::colvec gb = {3.37077588e-3, + 6.62769080e-6, + 1.78718601e-8, + 5.49266312e-11}; + + arma::colvec gtu = {8.41275991e-4, + 7.67306686e-7, + 1.21291230e-9, + 2.48508228e-12}; + + arma::colvec utg = {-8.41276339e-4, + -5.95619298e-8, + -1.69485209e-10, + -2.20473896e-13}; + + // Ellipsoidal latitude, longitude to spherical latitude, longitude + bool neg_geo = false; + + if (B < 0.0) neg_geo = true; + + double Bg_r = fabs(B); + double res_clensin = clsin(bg, 4, 2.0 * Bg_r); + Bg_r = Bg_r + res_clensin; + L0 = L0 * STRP_PI / 180.0; + double Lg_r = L - L0; + + // Spherical latitude, longitude to complementary spherical latitude % i.e.spherical N, E + double cos_BN = cos(Bg_r); + double Np = atan2(sin(Bg_r), cos(Lg_r) * cos_BN); + double Ep = atanh(sin(Lg_r) * cos_BN); + + // Spherical normalized N, E to ellipsoidal N, E + Np = 2.0 * Np; + Ep = 2.0 * Ep; + + double dN; + double dE; + clksin(gtu, 4, Np, Ep, &dN, &dE); + Np = Np / 2.0; + Ep = Ep / 2.0; + Np = Np + dN; + Ep = Ep + dE; + double N = Q_n * Np; + double E = Q_n * Ep + E0; + if (neg_geo) + { + N = -N + 20000000.0; + } + r_enu(0) = E; + r_enu(1) = N; + r_enu(2) = U; +} + + +double clsin(const arma::colvec &ar, int degree, double argument) +{ + // Clenshaw summation of sinus of argument. + // + // result = clsin(ar, degree, argument); + // + // Originally written in Matlab by Kai Borre + // Implemented in C++ by J.Arribas + + double cos_arg = 2.0 * cos(argument); + double hr1 = 0.0; + double hr = 0.0; + double hr2; + for (int t = degree; t > 0; t--) + { + hr2 = hr1; + hr1 = hr; + hr = ar(t - 1) + cos_arg * hr1 - hr2; + } + + return (hr * sin(argument)); +} + + +void clksin(const arma::colvec &ar, int degree, double arg_real, double arg_imag, double *re, double *im) +{ + // Clenshaw summation of sinus with complex argument + // [re, im] = clksin(ar, degree, arg_real, arg_imag); + // + // Originally written in Matlab by Kai Borre + // Implemented in C++ by J.Arribas + + double sin_arg_r = sin(arg_real); + double cos_arg_r = cos(arg_real); + double sinh_arg_i = sinh(arg_imag); + double cosh_arg_i = cosh(arg_imag); + + double r = 2.0 * cos_arg_r * cosh_arg_i; + double i = -2.0 * sin_arg_r * sinh_arg_i; + + double hr1 = 0.0; + double hr = 0.0; + double hi1 = 0.0; + double hi = 0.0; + double hi2; + double hr2; + for (int t = degree; t > 0; t--) + { + hr2 = hr1; + hr1 = hr; + hi2 = hi1; + hi1 = hi; + double z = ar(t - 1) + r * hr1 - i * hi - hr2; + hi = i * hr1 + r * hi1 - hi2; + hr = z; + } + + r = sin_arg_r * cosh_arg_i; + i = cos_arg_r * sinh_arg_i; + + *re = r * hr - i * hi; + *im = r * hi + i * hr; +} + + +int findUtmZone(double latitude_deg, double longitude_deg) +{ + // Function finds the UTM zone number for given longitude and latitude. + // The longitude value must be between -180 (180 degree West) and 180 (180 + // degree East) degree. The latitude must be within -80 (80 degree South) and + // 84 (84 degree North). + // + // utmZone = findUtmZone(latitude, longitude); + // + // Latitude and longitude must be in decimal degrees (e.g. 15.5 degrees not + // 15 deg 30 min). + // + // Originally written in Matlab by Darius Plausinaitis + // Implemented in C++ by J.Arribas + + // Check value bounds + if ((longitude_deg > 180.0) || (longitude_deg < -180.0)) + std::cout << "Longitude value exceeds limits (-180:180).\n"; + + if ((latitude_deg > 84.0) || (latitude_deg < -80.0)) + std::cout << "Latitude value exceeds limits (-80:84).\n"; + + // + // Find zone + // + + // Start at 180 deg west = -180 deg + int utmZone = floor((180 + longitude_deg) / 6) + 1; + + // Correct zone numbers for particular areas + if (latitude_deg > 72.0) + { + // Corrections for zones 31 33 35 37 + if ((longitude_deg >= 0.0) && (longitude_deg < 9.0)) + { + utmZone = 31; + } + else if ((longitude_deg >= 9.0) && (longitude_deg < 21.0)) + { + utmZone = 33; + } + else if ((longitude_deg >= 21.0) && (longitude_deg < 33.0)) + { + utmZone = 35; + } + else if ((longitude_deg >= 33.0) && (longitude_deg < 42.0)) + { + utmZone = 37; + } + } + else if ((latitude_deg >= 56.0) && (latitude_deg < 64.0)) + { + // Correction for zone 32 + if ((longitude_deg >= 3.0) && (longitude_deg < 12.0)) + utmZone = 32; + } + return utmZone; +} diff --git a/src/algorithms/libs/geofunctions.h b/src/algorithms/libs/geofunctions.h new file mode 100644 index 000000000..677dc4a1d --- /dev/null +++ b/src/algorithms/libs/geofunctions.h @@ -0,0 +1,184 @@ +/*! + * \file geofunctions.h + * \brief A set of coordinate transformations functions and helpers, + * some of them migrated from MATLAB, for geographic information systems. + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GEOFUNCTIONS_H +#define GNSS_SDR_GEOFUNCTIONS_H + +#include + +arma::mat Skew_symmetric(const arma::vec &a); //!< Calculates skew-symmetric matrix + +double WGS84_g0(double Lat_rad); + +double WGS84_geocentric_radius(double Lat_geodetic_rad); + +/*! + * \brief Transformation of vector dx into topocentric coordinate + * system with origin at x + * Inputs: + * x - vector origin coordinates (in ECEF system [X; Y; Z;]) + * dx - vector ([dX; dY; dZ;]). + * + * Outputs: + * D - vector length. Units like the input + * Az - azimuth from north positive clockwise, degrees + * El - elevation angle, degrees + * + * Based on a Matlab function by Kai Borre + */ +int topocent(double *Az, double *El, double *D, const arma::vec &x, const arma::vec &dx); + +/*! + * \brief Subroutine to calculate geodetic coordinates latitude, longitude, + * height given Cartesian coordinates X,Y,Z, and reference ellipsoid + * values semi-major axis (a) and the inverse of flattening (finv). + * + * The output units of angular quantities will be in decimal degrees + * (15.5 degrees not 15 deg 30 min). The output units of h will be the + * same as the units of X,Y,Z,a. + * + * Inputs: + * a - semi-major axis of the reference ellipsoid + * finv - inverse of flattening of the reference ellipsoid + * X,Y,Z - Cartesian coordinates + * + * Outputs: + * dphi - latitude + * dlambda - longitude + * h - height above reference ellipsoid + * + * Based in a Matlab function by Kai Borre + */ +int togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z); + +arma::mat Gravity_ECEF(const arma::vec &r_eb_e); //!< Calculates acceleration due to gravity resolved about ECEF-frame + +/*! + * \brief Conversion of Cartesian coordinates (X,Y,Z) to geographical + * coordinates (latitude, longitude, h) on a selected reference ellipsoid. + * + * Choices of Reference Ellipsoid for Geographical Coordinates + * 0. International Ellipsoid 1924 + * 1. International Ellipsoid 1967 + * 2. World Geodetic System 1972 + * 3. Geodetic Reference System 1980 + * 4. World Geodetic System 1984 + */ +arma::vec cart2geo(const arma::vec &XYZ, int elipsoid_selection); + +arma::vec LLH_to_deg(const arma::vec &LLH); + +double degtorad(double angleInDegrees); + +double radtodeg(double angleInRadians); + +double mstoknotsh(double MetersPerSeconds); + +double mstokph(double Kph); + +arma::vec CTM_to_Euler(const arma::mat &C); + +arma::mat Euler_to_CTM(const arma::vec &eul); + +void ECEF_to_Geo(const arma::vec &r_eb_e, const arma::vec &v_eb_e, const arma::mat &C_b_e, arma::vec &LLH, arma::vec &v_eb_n, arma::mat &C_b_n); + + +/*! + * \brief From Geographic to ECEF coordinates + * + * Inputs: + * LLH latitude (rad), longitude (rad), height (m) + * v_eb_n velocity of body frame w.r.t. ECEF frame, resolved along + * north, east, and down (m/s) + * C_b_n body-to-NED coordinate transformation matrix + * + * Outputs: + * r_eb_e Cartesian position of body frame w.r.t. ECEF frame, resolved + * along ECEF-frame axes (m) + * v_eb_e velocity of body frame w.r.t. ECEF frame, resolved along + * ECEF-frame axes (m/s) + * C_b_e body-to-ECEF-frame coordinate transformation matrix + * + */ +void Geo_to_ECEF(const arma::vec &LLH, const arma::vec &v_eb_n, const arma::mat &C_b_n, arma::vec &r_eb_e, arma::vec &v_eb_e, arma::mat &C_b_e); + + +/*! + * \brief Converts curvilinear to Cartesian position and velocity + * resolving axes from NED to ECEF + * This function created 11/4/2012 by Paul Groves + * + * Inputs: + * L_b latitude (rad) + * lambda_b longitude (rad) + * h_b height (m) + * v_eb_n velocity of body frame w.r.t. ECEF frame, resolved along + * north, east, and down (m/s) + * + * Outputs: + * r_eb_e Cartesian position of body frame w.r.t. ECEF frame, resolved + * along ECEF-frame axes (m) + * v_eb_e velocity of body frame w.r.t. ECEF frame, resolved along + * ECEF-frame axes (m/s) + */ +void pv_Geo_to_ECEF(double L_b, double lambda_b, double h_b, const arma::vec &v_eb_n, arma::vec &r_eb_e, arma::vec &v_eb_e); + + +/*! + * \brief The Haversine formula determines the great-circle distance between two points on a sphere given their longitudes and latitudes. + */ +double great_circle_distance(double lat1, double lon1, double lat2, double lon2); + + +/*! + * \brief Transformation of ECEF (X,Y,Z) to (E,N,U) in UTM, zone 'zone'. + */ +void cart2utm(const arma::vec &r_eb_e, int zone, arma::vec &r_enu); + + +/*! + * \brief Function finds the UTM zone number for given longitude and latitude. + */ +int findUtmZone(double latitude_deg, double longitude_deg); + + +/*! + * \brief Clenshaw summation of sinus of argument. + */ +double clsin(const arma::colvec &ar, int degree, double argument); + + +/*! + * \brief Clenshaw summation of sinus with complex argument. + */ +void clksin(const arma::colvec &ar, int degree, double arg_real, double arg_imag, double *re, double *im); + +#endif diff --git a/src/algorithms/libs/glonass_l1_signal_processing.cc b/src/algorithms/libs/glonass_l1_signal_processing.cc index 509137d15..045b53626 100644 --- a/src/algorithms/libs/glonass_l1_signal_processing.cc +++ b/src/algorithms/libs/glonass_l1_signal_processing.cc @@ -32,17 +32,17 @@ #include "glonass_l1_signal_processing.h" -auto auxCeil = [](float x) { return static_cast(static_cast((x) + 1)); }; +auto auxCeil = [](float x) { return static_cast(static_cast((x) + 1)); }; -void glonass_l1_ca_code_gen_complex(std::complex* _dest, /* signed int _prn,*/ unsigned int _chip_shift) +void glonass_l1_ca_code_gen_complex(std::complex* _dest, /* int32_t _prn,*/ uint32_t _chip_shift) { - const unsigned int _code_length = 511; + const uint32_t _code_length = 511; bool G1[_code_length]; bool G1_register[9]; bool feedback1; bool aux; - unsigned int delay; - unsigned int lcv, lcv2; + uint32_t delay; + uint32_t lcv, lcv2; for (lcv = 0; lcv < 9; lcv++) { @@ -104,26 +104,26 @@ void glonass_l1_ca_code_gen_complex(std::complex* _dest, /* signed int _p /* * Generates complex GLONASS L1 C/A code for the desired SV ID and sampled to specific sampling frequency */ -void glonass_l1_ca_code_gen_complex_sampled(std::complex* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift) +void glonass_l1_ca_code_gen_complex_sampled(std::complex* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift) { // This function is based on the GNU software GPS for MATLAB in the Kay Borre book std::complex _code[511]; - signed int _samplesPerCode, _codeValueIndex; + int32_t _samplesPerCode, _codeValueIndex; float _ts; float _tc; float aux; - const signed int _codeFreqBasis = 511000; //Hz - const signed int _codeLength = 511; + const int32_t _codeFreqBasis = 511000; //Hz + const int32_t _codeLength = 511; //--- Find number of samples per spreading code ---------------------------- - _samplesPerCode = static_cast(static_cast(_fs) / static_cast(_codeFreqBasis / _codeLength)); + _samplesPerCode = static_cast(static_cast(_fs) / static_cast(_codeFreqBasis / _codeLength)); //--- Find time constants -------------------------------------------------- _ts = 1.0 / static_cast(_fs); // Sampling period in sec _tc = 1.0 / static_cast(_codeFreqBasis); // C/A chip period in sec glonass_l1_ca_code_gen_complex(_code, _chip_shift); //generate C/A code 1 sample per chip - for (signed int i = 0; i < _samplesPerCode; i++) + for (int32_t i = 0; i < _samplesPerCode; i++) { //=== Digitizing ======================================================= diff --git a/src/algorithms/libs/glonass_l1_signal_processing.h b/src/algorithms/libs/glonass_l1_signal_processing.h index bcf1e89f2..0b1a26cfc 100644 --- a/src/algorithms/libs/glonass_l1_signal_processing.h +++ b/src/algorithms/libs/glonass_l1_signal_processing.h @@ -34,14 +34,15 @@ #define GNSS_SDR_GLONASS_SDR_SIGNAL_PROCESSING_H_ #include +#include //!Generates complex GLONASS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency -void glonass_l1_ca_code_gen_complex(std::complex* _dest, /*signed int _prn,*/ unsigned int _chip_shift); +void glonass_l1_ca_code_gen_complex(std::complex* _dest, /*int32_t _prn,*/ uint32_t _chip_shift); //! Generates N complex GLONASS L1 C/A codes for the desired SV ID and code shift -void glonass_l1_ca_code_gen_complex_sampled(std::complex* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift, unsigned int _ncodes); +void glonass_l1_ca_code_gen_complex_sampled(std::complex* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift, uint32_t _ncodes); //! Generates complex GLONASS L1 C/A code for the desired SV ID and code shift -void glonass_l1_ca_code_gen_complex_sampled(std::complex* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift); +void glonass_l1_ca_code_gen_complex_sampled(std::complex* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift); #endif /* GNSS_SDR_GLONASS_SDR_SIGNAL_PROCESSING_H_ */ diff --git a/src/algorithms/libs/glonass_l2_signal_processing.cc b/src/algorithms/libs/glonass_l2_signal_processing.cc index fa82b88b1..f486429e1 100644 --- a/src/algorithms/libs/glonass_l2_signal_processing.cc +++ b/src/algorithms/libs/glonass_l2_signal_processing.cc @@ -32,17 +32,17 @@ #include "glonass_l2_signal_processing.h" -auto auxCeil = [](float x) { return static_cast(static_cast((x) + 1)); }; +auto auxCeil = [](float x) { return static_cast(static_cast((x) + 1)); }; -void glonass_l2_ca_code_gen_complex(std::complex* _dest, /* signed int _prn,*/ unsigned int _chip_shift) +void glonass_l2_ca_code_gen_complex(std::complex* _dest, /* int32_t _prn,*/ uint32_t _chip_shift) { - const unsigned int _code_length = 511; + const uint32_t _code_length = 511; bool G1[_code_length]; bool G1_register[9]; bool feedback1; bool aux; - unsigned int delay; - unsigned int lcv, lcv2; + uint32_t delay; + uint32_t lcv, lcv2; for (lcv = 0; lcv < 9; lcv++) { @@ -104,26 +104,26 @@ void glonass_l2_ca_code_gen_complex(std::complex* _dest, /* signed int _p /* * Generates complex GLONASS L2 C/A code for the desired SV ID and sampled to specific sampling frequency */ -void glonass_l2_ca_code_gen_complex_sampled(std::complex* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift) +void glonass_l2_ca_code_gen_complex_sampled(std::complex* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift) { // This function is based on the GNU software GPS for MATLAB in the Kay Borre book std::complex _code[511]; - signed int _samplesPerCode, _codeValueIndex; + int32_t _samplesPerCode, _codeValueIndex; float _ts; float _tc; float aux; - const signed int _codeFreqBasis = 511000; //Hz - const signed int _codeLength = 511; + const int32_t _codeFreqBasis = 511000; //Hz + const int32_t _codeLength = 511; //--- Find number of samples per spreading code ---------------------------- - _samplesPerCode = static_cast(static_cast(_fs) / static_cast(_codeFreqBasis / _codeLength)); + _samplesPerCode = static_cast(static_cast(_fs) / static_cast(_codeFreqBasis / _codeLength)); //--- Find time constants -------------------------------------------------- _ts = 1.0 / static_cast(_fs); // Sampling period in sec _tc = 1.0 / static_cast(_codeFreqBasis); // C/A chip period in sec glonass_l2_ca_code_gen_complex(_code, _chip_shift); //generate C/A code 1 sample per chip - for (signed int i = 0; i < _samplesPerCode; i++) + for (int32_t i = 0; i < _samplesPerCode; i++) { //=== Digitizing ======================================================= diff --git a/src/algorithms/libs/glonass_l2_signal_processing.h b/src/algorithms/libs/glonass_l2_signal_processing.h index ff4a699e1..7c798f45a 100644 --- a/src/algorithms/libs/glonass_l2_signal_processing.h +++ b/src/algorithms/libs/glonass_l2_signal_processing.h @@ -34,14 +34,15 @@ #define GNSS_SDR_GLONASS_L2_SIGNAL_PROCESSING_H_ #include +#include //!Generates complex GLONASS L2 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency -void glonass_l2_ca_code_gen_complex(std::complex* _dest, /*signed int _prn,*/ unsigned int _chip_shift); +void glonass_l2_ca_code_gen_complex(std::complex* _dest, /*int32_t _prn,*/ uint32_t _chip_shift); //! Generates N complex GLONASS L2 C/A codes for the desired SV ID and code shift -void glonass_l2_ca_code_gen_complex_sampled(std::complex* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift, unsigned int _ncodes); +void glonass_l2_ca_code_gen_complex_sampled(std::complex* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift, uint32_t _ncodes); //! Generates complex GLONASS L2 C/A code for the desired SV ID and code shift -void glonass_l2_ca_code_gen_complex_sampled(std::complex* _dest, /* unsigned int _prn,*/ signed int _fs, unsigned int _chip_shift); +void glonass_l2_ca_code_gen_complex_sampled(std::complex* _dest, /* uint32_t _prn,*/ int32_t _fs, uint32_t _chip_shift); #endif /* GNSS_SDR_GLONASS_L2_SIGNAL_PROCESSING_H_ */ diff --git a/src/algorithms/libs/gnss_sdr_create_directory.cc b/src/algorithms/libs/gnss_sdr_create_directory.cc new file mode 100644 index 000000000..3a880143b --- /dev/null +++ b/src/algorithms/libs/gnss_sdr_create_directory.cc @@ -0,0 +1,87 @@ +/*! + * \file gnss_sdr_create_directory.cc + * \brief Create a directory + * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "gnss_sdr_create_directory.h" +#include // for create_directories, exists +#include // for path, operator<< +#include // for filesystem +#include + + +bool gnss_sdr_create_directory(const std::string& foldername) +{ + std::string new_folder; + for (auto& folder : boost::filesystem::path(foldername)) + { + new_folder += folder.string(); + boost::system::error_code ec; + if (!boost::filesystem::exists(new_folder)) + { + try + { + if (!boost::filesystem::create_directory(new_folder, ec)) + { + return false; + } + } + catch (std::exception& e) + { + return false; + } + } + new_folder += boost::filesystem::path::preferred_separator; + } + + // Check if we have writing permissions + std::string test_file = foldername + "/test_file.txt"; + std::ofstream os_test_file; + os_test_file.open(test_file.c_str(), std::ios::out | std::ios::binary); + + if (os_test_file.is_open()) + { + boost::system::error_code ec; + os_test_file.close(); + try + { + boost::filesystem::remove(test_file, ec); + } + catch (std::exception& e) + { + return false; + } + return true; + } + else + { + os_test_file.close(); + return false; + } +} diff --git a/src/algorithms/libs/gnss_sdr_create_directory.h b/src/algorithms/libs/gnss_sdr_create_directory.h new file mode 100644 index 000000000..23de7ec14 --- /dev/null +++ b/src/algorithms/libs/gnss_sdr_create_directory.h @@ -0,0 +1,38 @@ +/*! + * \file gnss_sdr_create_directory.h + * \brief Create a directory + * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GNSS_SDR_CREATE_DIRECTORY_H_ +#define GNSS_SDR_GNSS_SDR_CREATE_DIRECTORY_H_ + +#include + +bool gnss_sdr_create_directory(const std::string& foldername); + +#endif diff --git a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc new file mode 100644 index 000000000..727de7521 --- /dev/null +++ b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.cc @@ -0,0 +1,305 @@ +/*! + * \file gnss_sdr_fpga_sample_counter.cc + * \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks + * \author Javier Arribas 2018. jarribas(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "gnss_sdr_fpga_sample_counter.h" +#include "gnss_synchro.h" +#include +#include +#include +#include +#include +#include // libraries used by the GIPO +#include // libraries used by the GIPO + +#include + +#define PAGE_SIZE 0x10000 // default page size for the multicorrelator memory map +#define TEST_REG_SANITY_CHECK 0x55AA // value to check the presence of the test register (to detect the hw) + +gnss_sdr_fpga_sample_counter::gnss_sdr_fpga_sample_counter(double _fs, int32_t _interval_ms) : gr::block("fpga_fpga_sample_counter", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) +{ + message_port_register_out(pmt::mp("fpga_sample_counter")); + set_max_noutput_items(1); + interval_ms = _interval_ms; + fs = _fs; + //printf("CREATOR fs = %f\n", fs); + //printf("CREATOR interval_ms = %" PRIu32 "\n", interval_ms); + samples_per_output = std::round(fs * static_cast(interval_ms) / 1e3); + //printf("CREATOR samples_per_output = %" PRIu32 "\n", samples_per_output); + //todo: Load here the hardware counter register with this amount of samples. It should produce an + //interrupt every samples_per_output count. + //The hardware timer must keep always interrupting the PS. It must not wait for the interrupt to + //be served. + open_device(); + + sample_counter = 0ULL; + current_T_rx_ms = 0; + current_s = 0; + current_m = 0; + current_h = 0; + current_days = 0; + report_interval_ms = 1000; // default reporting 1 second + flag_enable_send_msg = false; // enable it for reporting time with asynchronous message + flag_m = false; + flag_h = false; + flag_days = false; +} + + +gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms) +{ + gnss_sdr_fpga_sample_counter_sptr fpga_sample_counter_(new gnss_sdr_fpga_sample_counter(_fs, _interval_ms)); + return fpga_sample_counter_; +} + + +// Called by gnuradio to enable drivers, etc for i/o devices. +bool gnss_sdr_fpga_sample_counter::start() +{ + //todo: place here the RE-INITIALIZATION routines. This function will be called by GNURadio at every start of the flowgraph. + + // configure the number of samples per output in the FPGA and enable the interrupts + configure_samples_per_output(samples_per_output); + + // return true if everything is ok. + return true; +} + + +// Called by GNURadio to disable drivers, etc for i/o devices. +bool gnss_sdr_fpga_sample_counter::stop() +{ + //todo: place here the routines to stop the associated hardware (if needed).This function will be called by GNURadio at every stop of the flowgraph. + // return true if everything is ok. + close_device(); + + return true; +} + + +int gnss_sdr_fpga_sample_counter::general_work(int noutput_items __attribute__((unused)), + __attribute__((unused)) gr_vector_int &ninput_items, + __attribute__((unused)) gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + //todo: Call here a function that waits for an interrupt. Do not open a thread, + //it must be a simple call to a BLOCKING function. + // The function will return the actual absolute sample count of the internal counter of the timmer. + // store the sample count in class member sample_counter + // Possible problem: what happen if the PS is overloaded and gnuradio does not call this function + // with the sufficient rate to catch all the interrupts in the counter. To be evaluated later. + + uint32_t counter = wait_for_interrupt_and_read_counter(); + uint64_t samples_passed = 2*static_cast(samples_per_output) - static_cast(counter); // ellapsed samples + //printf("============================================ interrupter : samples_passed = %" PRIu64 "\n", samples_passed); + // Note: at this moment the sample counter is implemented as a sample counter that decreases to zero and then it is automatically + // reloaded again and keeps counter. It is done in this way to minimize the logic in the FPGA and maximize the FPGA clock performance + // (it takes less resources and latency in the FPGA to compare a number against a fixed value like zero than to compare it to a programmable + // variable number). + + sample_counter = sample_counter + samples_passed; //samples_per_output; + Gnss_Synchro *out = reinterpret_cast(output_items[0]); + out[0] = Gnss_Synchro(); + out[0].Flag_valid_symbol_output = false; + out[0].Flag_valid_word = false; + out[0].Channel_ID = -1; + out[0].fs = fs; + if ((current_T_rx_ms % report_interval_ms) == 0) + { + //printf("time to print sample_counter = %" PRIu64 "\n", sample_counter); + //printf("time to print current Tx ms : %" PRIu64 "\n", current_T_rx_ms); + //printf("time to print report_interval_ms : %" PRIu32 "\n", report_interval_ms); + //printf("time to print %f\n", (current_T_rx_ms % report_interval_ms)); + current_s++; + if ((current_s % 60) == 0) + { + current_s = 0; + current_m++; + flag_m = true; + if ((current_m % 60) == 0) + { + current_m = 0; + current_h++; + flag_h = true; + if ((current_h % 24) == 0) + { + current_h = 0; + current_days++; + flag_days = true; + } + } + } + + if (flag_days) + { + std::string day; + if (current_days == 1) + { + day = " day "; + } + else + { + day = " days "; + } + std::cout << "Current receiver time: " << current_days << day << current_h << " h " << current_m << " min " << current_s << " s" << std::endl; + } + else + { + if (flag_h) + { + std::cout << "Current receiver time: " << current_h << " h " << current_m << " min " << current_s << " s" << std::endl; + } + else + { + if (flag_m) + { + std::cout << "Current receiver time: " << current_m << " min " << current_s << " s" << std::endl; + } + else + { + std::cout << "Current receiver time: " << current_s << " s" << std::endl; + } + } + } + if (flag_enable_send_msg) + { + message_port_pub(pmt::mp("receiver_time"), pmt::from_double(static_cast(current_T_rx_ms) / 1000.0)); + } + } + out[0].Tracking_sample_counter = sample_counter; + //current_T_rx_ms = (sample_counter * 1000) / samples_per_output; + current_T_rx_ms = interval_ms*(sample_counter) / samples_per_output; + return 1; +} + +uint32_t gnss_sdr_fpga_sample_counter::test_register(uint32_t writeval) +{ + uint32_t readval; + // write value to test register + map_base[3] = writeval; + // read value from test register + readval = map_base[3]; + // return read value + return readval; +} + +void gnss_sdr_fpga_sample_counter::configure_samples_per_output(uint32_t interval) +{ + // note : the counter is a 48-bit value in the HW. + //printf("============================================ total counter - interrupted interval : %" PRIu32 "\n", interval); + //uint64_t temp_interval; + //temp_interval = (interval & static_cast(0xFFFFFFFF)); + //printf("LSW counter - interrupted interval : %" PRIu32 "\n", static_cast(temp_interval)); + //map_base[0] = static_cast(temp_interval); + map_base[0] = interval - 1; + //temp_interval = (interval >> 32) & static_cast(0xFFFFFFFF); + //printf("MSbits counter - interrupted interval : %" PRIu32 "\n", static_cast(temp_interval)); + //map_base[1] = static_cast(temp_interval); // writing the most significant bits also enables the interrupts +} + +void gnss_sdr_fpga_sample_counter::open_device() +{ + // open communication with HW accelerator + if ((fd = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1) + { + LOG(WARNING) << "Cannot open deviceio" << device_name; + std::cout << "Counter-Intr: cannot open deviceio" << device_name << std::endl; + } + map_base = reinterpret_cast(mmap(NULL, PAGE_SIZE, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); + + if (map_base == reinterpret_cast(-1)) + { + LOG(WARNING) << "Cannot map the FPGA acquisition module into user memory"; + std::cout << "Counter-Intr: cannot map deviceio" << device_name << std::endl; + } + + // sanity check : check test register + uint32_t writeval = TEST_REG_SANITY_CHECK; + uint32_t readval; + readval = gnss_sdr_fpga_sample_counter::test_register(writeval); + if (writeval != readval) + { + LOG(WARNING) << "Acquisition test register sanity check failed"; + } + else + { + LOG(INFO) << "Acquisition test register sanity check success!"; + //std::cout << "Acquisition test register sanity check success!" << std::endl; + } +} + +void gnss_sdr_fpga_sample_counter::close_device() +{ + //printf("=========================================== NOW closing device ...\n"); + map_base[2] = 0; // disable the generation of the interrupt in the device + + uint32_t *aux = const_cast(map_base); + if (munmap(static_cast(aux), PAGE_SIZE) == -1) + { + printf("Failed to unmap memory uio\n"); + } + close(fd); +} + +uint32_t gnss_sdr_fpga_sample_counter::wait_for_interrupt_and_read_counter() +{ + int32_t irq_count; + ssize_t nb; + int32_t counter; + + // enable interrupts + int32_t reenable = 1; + write(fd, reinterpret_cast(&reenable), sizeof(int32_t)); + + // wait for interrupt + //printf("============================================ interrupter : going to wait for interupt\n"); + nb = read(fd, &irq_count, sizeof(irq_count)); + //printf("============================================ interrupter : interrupt received\n"); + //printf("interrupt received\n"); + if (nb != sizeof(irq_count)) + { + printf("acquisition module Read failed to retrieve 4 bytes!\n"); + printf("acquisition module Interrupt number %d\n", irq_count); + } + + // acknowledge the interrupt + map_base[1] = 0; // writing anything to reg 1 acknowledges the interrupt + + // add number of passed samples or read the current counter value for more accuracy + counter = samples_per_output; //map_base[0]; + return counter; + +} + + diff --git a/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h new file mode 100644 index 000000000..e02320afc --- /dev/null +++ b/src/algorithms/libs/gnss_sdr_fpga_sample_counter.h @@ -0,0 +1,81 @@ +/*! + * \file gnss_sdr_fpga_sample_counter.h + * \brief Simple block to report the current receiver time based on the output of the tracking or telemetry blocks + * \author Javier Arribas 2018. jarribas(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ +#ifndef GNSS_SDR_FPGA_sample_counter_H_ +#define GNSS_SDR_FPGA_sample_counter_H_ + +#include +#include +#include + +class gnss_sdr_fpga_sample_counter; + +typedef boost::shared_ptr gnss_sdr_fpga_sample_counter_sptr; + +gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms); + +class gnss_sdr_fpga_sample_counter : public gr::block +{ +private: + gnss_sdr_fpga_sample_counter(double _fs, int32_t _interval_ms); + uint32_t test_register(uint32_t writeval); + void configure_samples_per_output(uint32_t interval); + void close_device(void); + void open_device(void); + bool start(); + bool stop(); + uint32_t wait_for_interrupt_and_read_counter(void); + uint32_t samples_per_output; + double fs; + uint64_t sample_counter; + uint32_t interval_ms; + uint64_t current_T_rx_ms; // Receiver time in ms since the beginning of the run + uint32_t current_s; // Receiver time in seconds, modulo 60 + bool flag_m; // True if the receiver has been running for at least 1 minute + uint32_t current_m; // Receiver time in minutes, modulo 60 + bool flag_h; // True if the receiver has been running for at least 1 hour + uint32_t current_h; // Receiver time in hours, modulo 24 + bool flag_days; // True if the receiver has been running for at least 1 day + uint32_t current_days; // Receiver time in days since the beginning of the run + int32_t report_interval_ms; + bool flag_enable_send_msg; + int32_t fd; // driver descriptor + volatile uint32_t *map_base; // driver memory map + std::string device_name = "/dev/uio26"; // HW device name + +public: + friend gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms); + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /*GNSS_SDR_FPGA_sample_counter_H_*/ diff --git a/src/algorithms/libs/gnss_sdr_sample_counter.cc b/src/algorithms/libs/gnss_sdr_sample_counter.cc index a94d4ddeb..9fdc7e00e 100644 --- a/src/algorithms/libs/gnss_sdr_sample_counter.cc +++ b/src/algorithms/libs/gnss_sdr_sample_counter.cc @@ -36,13 +36,17 @@ #include #include -gnss_sdr_sample_counter::gnss_sdr_sample_counter(double _fs, size_t _size) : gr::sync_decimator("sample_counter", - gr::io_signature::make(1, 1, _size), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - static_cast(std::floor(_fs * 0.001))) +gnss_sdr_sample_counter::gnss_sdr_sample_counter(double _fs, int32_t _interval_ms, size_t _size) : gr::sync_decimator("sample_counter", + gr::io_signature::make(1, 1, _size), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + static_cast(std::round(_fs * static_cast(_interval_ms) / 1e3))) { message_port_register_out(pmt::mp("sample_counter")); set_max_noutput_items(1); + interval_ms = _interval_ms; + fs = _fs; + samples_per_output = std::round(fs * static_cast(interval_ms) / 1e3); + sample_counter = 0; current_T_rx_ms = 0; current_s = 0; current_m = 0; @@ -56,9 +60,9 @@ gnss_sdr_sample_counter::gnss_sdr_sample_counter(double _fs, size_t _size) : gr: } -gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, size_t _size) +gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, int32_t _interval_ms, size_t _size) { - gnss_sdr_sample_counter_sptr sample_counter_(new gnss_sdr_sample_counter(_fs, _size)); + gnss_sdr_sample_counter_sptr sample_counter_(new gnss_sdr_sample_counter(_fs, _interval_ms, _size)); return sample_counter_; } @@ -69,6 +73,10 @@ int gnss_sdr_sample_counter::work(int noutput_items __attribute__((unused)), { Gnss_Synchro *out = reinterpret_cast(output_items[0]); out[0] = Gnss_Synchro(); + out[0].Flag_valid_symbol_output = false; + out[0].Flag_valid_word = false; + out[0].Channel_ID = -1; + out[0].fs = fs; if ((current_T_rx_ms % report_interval_ms) == 0) { current_s++; @@ -127,6 +135,8 @@ int gnss_sdr_sample_counter::work(int noutput_items __attribute__((unused)), message_port_pub(pmt::mp("receiver_time"), pmt::from_double(static_cast(current_T_rx_ms) / 1000.0)); } } - current_T_rx_ms++; + sample_counter += samples_per_output; + out[0].Tracking_sample_counter = sample_counter; + current_T_rx_ms += interval_ms; return 1; } diff --git a/src/algorithms/libs/gnss_sdr_sample_counter.h b/src/algorithms/libs/gnss_sdr_sample_counter.h index f398684f5..90c05cb28 100644 --- a/src/algorithms/libs/gnss_sdr_sample_counter.h +++ b/src/algorithms/libs/gnss_sdr_sample_counter.h @@ -33,31 +33,36 @@ #include #include +#include class gnss_sdr_sample_counter; typedef boost::shared_ptr gnss_sdr_sample_counter_sptr; -gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, size_t _size); +gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, int32_t _interval_ms, size_t _size); class gnss_sdr_sample_counter : public gr::sync_decimator { private: - gnss_sdr_sample_counter(double _fs, size_t _size); - long long int current_T_rx_ms; // Receiver time in ms since the beginning of the run - unsigned int current_s; // Receiver time in seconds, modulo 60 - bool flag_m; // True if the receiver has been running for at least 1 minute - unsigned int current_m; // Receiver time in minutes, modulo 60 - bool flag_h; // True if the receiver has been running for at least 1 hour - unsigned int current_h; // Receiver time in hours, modulo 24 - bool flag_days; // True if the receiver has been running for at least 1 day - unsigned int current_days; // Receiver time in days since the beginning of the run - int report_interval_ms; + gnss_sdr_sample_counter(double _fs, int32_t _interval_ms, size_t _size); + uint32_t samples_per_output; + double fs; + uint64_t sample_counter; + int32_t interval_ms; + int64_t current_T_rx_ms; // Receiver time in ms since the beginning of the run + uint32_t current_s; // Receiver time in seconds, modulo 60 + bool flag_m; // True if the receiver has been running for at least 1 minute + uint32_t current_m; // Receiver time in minutes, modulo 60 + bool flag_h; // True if the receiver has been running for at least 1 hour + uint32_t current_h; // Receiver time in hours, modulo 24 + bool flag_days; // True if the receiver has been running for at least 1 day + uint32_t current_days; // Receiver time in days since the beginning of the run + int32_t report_interval_ms; bool flag_enable_send_msg; public: - friend gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, size_t _size); + friend gnss_sdr_sample_counter_sptr gnss_sdr_make_sample_counter(double _fs, int32_t _interval_ms, size_t _size); int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); diff --git a/src/algorithms/libs/gnss_sdr_time_counter.h b/src/algorithms/libs/gnss_sdr_time_counter.h index 91261e37d..12cc8094b 100644 --- a/src/algorithms/libs/gnss_sdr_time_counter.h +++ b/src/algorithms/libs/gnss_sdr_time_counter.h @@ -33,7 +33,7 @@ #include #include - +#include class gnss_sdr_time_counter; @@ -45,20 +45,20 @@ class gnss_sdr_time_counter : public gr::block { private: gnss_sdr_time_counter(); - long long int current_T_rx_ms; // Receiver time in ms since the beginning of the run - unsigned int current_s; // Receiver time in seconds, modulo 60 - bool flag_m; // True if the receiver has been running for at least 1 minute - unsigned int current_m; // Receiver time in minutes, modulo 60 - bool flag_h; // True if the receiver has been running for at least 1 hour - unsigned int current_h; // Receiver time in hours, modulo 24 - bool flag_days; // True if the receiver has been running for at least 1 day - unsigned int current_days; // Receiver time in days since the beginning of the run - int report_interval_ms; + int64_t current_T_rx_ms; // Receiver time in ms since the beginning of the run + uint32_t current_s; // Receiver time in seconds, modulo 60 + bool flag_m; // True if the receiver has been running for at least 1 minute + uint32_t current_m; // Receiver time in minutes, modulo 60 + bool flag_h; // True if the receiver has been running for at least 1 hour + uint32_t current_h; // Receiver time in hours, modulo 24 + bool flag_days; // True if the receiver has been running for at least 1 day + uint32_t current_days; // Receiver time in days since the beginning of the run + int32_t report_interval_ms; public: friend gnss_sdr_time_counter_sptr gnss_sdr_make_time_counter(); int general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), - gr_vector_const_void_star &input_items __attribute__((unused)), gr_vector_void_star &output_items); + gr_vector_const_void_star &input_items __attribute__((unused)), gr_vector_void_star &output_items); }; #endif /*GNSS_SDR_SAMPLE_COUNTER_H_*/ diff --git a/src/algorithms/libs/gnss_sdr_valve.cc b/src/algorithms/libs/gnss_sdr_valve.cc index b49ab50f9..c8d0e1385 100644 --- a/src/algorithms/libs/gnss_sdr_valve.cc +++ b/src/algorithms/libs/gnss_sdr_valve.cc @@ -2,6 +2,7 @@ * \file gnss_sdr_valve.cc * \brief Implementation of a GNU Radio block that sends a STOP message to the * control queue right after a specific number of samples have passed through it. + * \author Javier Arribas, 2018. jarribas(at)cttc.es * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com * * @@ -39,42 +40,70 @@ gnss_sdr_valve::gnss_sdr_valve(size_t sizeof_stream_item, unsigned long long nitems, - gr::msg_queue::sptr queue) : gr::sync_block("valve", - gr::io_signature::make(1, 1, sizeof_stream_item), - gr::io_signature::make(1, 1, sizeof_stream_item)), - d_nitems(nitems), - d_ncopied_items(0), - d_queue(queue) + gr::msg_queue::sptr queue, + bool stop_flowgraph) : gr::sync_block("valve", + gr::io_signature::make(1, 1, sizeof_stream_item), + gr::io_signature::make(1, 1, sizeof_stream_item)), + d_nitems(nitems), + d_ncopied_items(0), + d_queue(queue), + d_stop_flowgraph(stop_flowgraph) { + d_open_valve = false; +} + + +boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, gr::msg_queue::sptr queue, bool stop_flowgraph) +{ + boost::shared_ptr valve_(new gnss_sdr_valve(sizeof_stream_item, nitems, queue, stop_flowgraph)); + return valve_; } boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, gr::msg_queue::sptr queue) { - boost::shared_ptr valve_(new gnss_sdr_valve(sizeof_stream_item, nitems, queue)); + boost::shared_ptr valve_(new gnss_sdr_valve(sizeof_stream_item, nitems, queue, true)); return valve_; } +void gnss_sdr_valve::open_valve() +{ + d_open_valve = true; +} + + int gnss_sdr_valve::work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - if (d_ncopied_items >= d_nitems) + if (d_open_valve == false) { - ControlMessageFactory *cmf = new ControlMessageFactory(); - d_queue->handle(cmf->GetQueueMessage(200, 0)); - LOG(INFO) << "Stopping receiver, " << d_ncopied_items << " samples processed"; - delete cmf; - return -1; // Done! + if (d_ncopied_items >= d_nitems) + { + ControlMessageFactory *cmf = new ControlMessageFactory(); + d_queue->handle(cmf->GetQueueMessage(200, 0)); + LOG(INFO) << "Stopping receiver, " << d_ncopied_items << " samples processed"; + delete cmf; + if (d_stop_flowgraph) + { + return -1; // Done! + } + else + { + usleep(1000000); + return 0; // do not produce or consume + } + } + unsigned long long n = std::min(d_nitems - d_ncopied_items, static_cast(noutput_items)); + if (n == 0) return 0; + memcpy(output_items[0], input_items[0], n * input_signature()->sizeof_stream_item(0)); + d_ncopied_items += n; + return n; + } + else + { + memcpy(output_items[0], input_items[0], noutput_items * input_signature()->sizeof_stream_item(0)); + return noutput_items; } - unsigned long long n = std::min(d_nitems - d_ncopied_items, static_cast(noutput_items)); - if (n == 0) return 0; - memcpy(output_items[0], input_items[0], n * input_signature()->sizeof_stream_item(0)); - //for(long long i = 0; i++; i #include - boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, gr::msg_queue::sptr queue); + +boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, + unsigned long long nitems, + gr::msg_queue::sptr queue, + bool stop_flowgraph); + /*! * \brief Implementation of a GNU Radio block that sends a STOP message to the * control queue right after a specific number of samples have passed through it. @@ -50,14 +56,23 @@ class gnss_sdr_valve : public gr::sync_block friend boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, gr::msg_queue::sptr queue); - gnss_sdr_valve(size_t sizeof_stream_item, + friend boost::shared_ptr gnss_sdr_make_valve(size_t sizeof_stream_item, unsigned long long nitems, - gr::msg_queue::sptr queue); + gr::msg_queue::sptr queue, + bool stop_flowgraph); + unsigned long long d_nitems; unsigned long long d_ncopied_items; gr::msg_queue::sptr d_queue; + bool d_stop_flowgraph; + bool d_open_valve; public: + gnss_sdr_valve(size_t sizeof_stream_item, + unsigned long long nitems, + gr::msg_queue::sptr queue, bool stop_flowgraph); + void open_valve(); + int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); diff --git a/src/algorithms/libs/gnss_signal_processing.cc b/src/algorithms/libs/gnss_signal_processing.cc index 1d3be66e3..0dea461e7 100644 --- a/src/algorithms/libs/gnss_signal_processing.cc +++ b/src/algorithms/libs/gnss_signal_processing.cc @@ -36,9 +36,9 @@ #include -auto auxCeil2 = [](float x) { return static_cast(static_cast((x) + 1)); }; +auto auxCeil2 = [](float x) { return static_cast(static_cast((x) + 1)); }; -void complex_exp_gen(std::complex* _dest, double _f, double _fs, unsigned int _samps) +void complex_exp_gen(std::complex* _dest, double _f, double _fs, uint32_t _samps) { gr::fxpt_nco d_nco; d_nco.set_freq((GPS_TWO_PI * _f) / _fs); @@ -46,14 +46,15 @@ void complex_exp_gen(std::complex* _dest, double _f, double _fs, unsigned } -void complex_exp_gen_conj(std::complex* _dest, double _f, double _fs, unsigned int _samps) +void complex_exp_gen_conj(std::complex* _dest, double _f, double _fs, uint32_t _samps) { gr::fxpt_nco d_nco; d_nco.set_freq(-(GPS_TWO_PI * _f) / _fs); d_nco.sincos(_dest, _samps, 1); } -void hex_to_binary_converter(int* _dest, char _from) + +void hex_to_binary_converter(int32_t* _dest, char _from) { switch (_from) { @@ -156,15 +157,16 @@ void hex_to_binary_converter(int* _dest, char _from) } } -void resampler(float* _from, float* _dest, float _fs_in, - float _fs_out, unsigned int _length_in, unsigned int _length_out) + +void resampler(const float* _from, float* _dest, float _fs_in, + float _fs_out, uint32_t _length_in, uint32_t _length_out) { - unsigned int _codeValueIndex; + uint32_t _codeValueIndex; float aux; //--- Find time constants -------------------------------------------------- const float _t_in = 1 / _fs_in; // Incoming sampling period in sec const float _t_out = 1 / _fs_out; // Out sampling period in sec - for (unsigned int i = 0; i < _length_out - 1; i++) + for (uint32_t i = 0; i < _length_out - 1; i++) { //=== Digitizing ======================================================= //--- compute index array to read sampled values ------------------------- @@ -179,15 +181,16 @@ void resampler(float* _from, float* _dest, float _fs_in, _dest[_length_out - 1] = _from[_length_in - 1]; } -void resampler(std::complex* _from, std::complex* _dest, float _fs_in, - float _fs_out, unsigned int _length_in, unsigned int _length_out) + +void resampler(const std::complex* _from, std::complex* _dest, float _fs_in, + float _fs_out, uint32_t _length_in, uint32_t _length_out) { - unsigned int _codeValueIndex; + uint32_t _codeValueIndex; float aux; //--- Find time constants -------------------------------------------------- const float _t_in = 1 / _fs_in; // Incoming sampling period in sec const float _t_out = 1 / _fs_out; // Out sampling period in sec - for (unsigned int i = 0; i < _length_out - 1; i++) + for (uint32_t i = 0; i < _length_out - 1; i++) { //=== Digitizing ======================================================= //--- compute index array to read sampled values ------------------------- diff --git a/src/algorithms/libs/gnss_signal_processing.h b/src/algorithms/libs/gnss_signal_processing.h index 514815d82..3ed363e3e 100644 --- a/src/algorithms/libs/gnss_signal_processing.h +++ b/src/algorithms/libs/gnss_signal_processing.h @@ -36,6 +36,7 @@ #define GNSS_SDR_GNSS_SIGNAL_PROCESSING_H_ #include +#include /*! @@ -43,14 +44,14 @@ * */ void complex_exp_gen(std::complex* _dest, double _f, double _fs, - unsigned int _samps); + uint32_t _samps); /*! * \brief This function generates a conjugate complex exponential in _dest. * */ void complex_exp_gen_conj(std::complex* _dest, double _f, double _fs, - unsigned int _samps); + uint32_t _samps); /*! @@ -58,21 +59,21 @@ void complex_exp_gen_conj(std::complex* _dest, double _f, double _fs, * to binary (the output are 4 ints with +1 or -1 values). * */ -void hex_to_binary_converter(int* _dest, char _from); +void hex_to_binary_converter(int32_t* _dest, char _from); /*! * \brief This function resamples a sequence of float values. * */ -void resampler(float* _from, float* _dest, - float _fs_in, float _fs_out, unsigned int _length_in, - unsigned int _length_out); +void resampler(const float* _from, float* _dest, + float _fs_in, float _fs_out, uint32_t _length_in, + uint32_t _length_out); /*! * \brief This function resamples a sequence of complex values. * */ -void resampler(std::complex* _from, std::complex* _dest, - float _fs_in, float _fs_out, unsigned int _length_in, - unsigned int _length_out); +void resampler(const std::complex* _from, std::complex* _dest, + float _fs_in, float _fs_out, uint32_t _length_in, + uint32_t _length_out); #endif /* GNSS_SDR_GNSS_SIGNAL_PROCESSING_H_ */ diff --git a/src/algorithms/libs/gps_l2c_signal.cc b/src/algorithms/libs/gps_l2c_signal.cc index 81ad79c78..4f41e620f 100644 --- a/src/algorithms/libs/gps_l2c_signal.cc +++ b/src/algorithms/libs/gps_l2c_signal.cc @@ -32,7 +32,6 @@ #include "gps_l2c_signal.h" #include "GPS_L2C.h" -#include #include @@ -42,11 +41,11 @@ int32_t gps_l2c_m_shift(int32_t x) } -void gps_l2c_m_code(int32_t* _dest, unsigned int _prn) +void gps_l2c_m_code(int32_t* _dest, uint32_t _prn) { int32_t x; x = GPS_L2C_M_INIT_REG[_prn - 1]; - for (int n = 0; n < GPS_L2_M_CODE_LENGTH_CHIPS; n++) + for (int32_t n = 0; n < GPS_L2_M_CODE_LENGTH_CHIPS; n++) { _dest[n] = static_cast(x & 1); x = gps_l2c_m_shift(x); @@ -54,7 +53,7 @@ void gps_l2c_m_code(int32_t* _dest, unsigned int _prn) } -void gps_l2c_m_code_gen_complex(std::complex* _dest, unsigned int _prn) +void gps_l2c_m_code_gen_complex(std::complex* _dest, uint32_t _prn) { int32_t* _code = new int32_t[GPS_L2_M_CODE_LENGTH_CHIPS]; @@ -63,7 +62,7 @@ void gps_l2c_m_code_gen_complex(std::complex* _dest, unsigned int _prn) gps_l2c_m_code(_code, _prn); } - for (signed int i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++) + for (int32_t i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++) { _dest[i] = std::complex(1.0 - 2.0 * _code[i], 0.0); } @@ -71,7 +70,8 @@ void gps_l2c_m_code_gen_complex(std::complex* _dest, unsigned int _prn) delete[] _code; } -void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn) + +void gps_l2c_m_code_gen_float(float* _dest, uint32_t _prn) { int32_t* _code = new int32_t[GPS_L2_M_CODE_LENGTH_CHIPS]; @@ -80,7 +80,7 @@ void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn) gps_l2c_m_code(_code, _prn); } - for (signed int i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++) + for (int32_t i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++) { _dest[i] = 1.0 - 2.0 * static_cast(_code[i]); } @@ -92,7 +92,7 @@ void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn) /* * Generates complex GPS L2C M code for the desired SV ID and sampled to specific sampling frequency */ -void gps_l2c_m_code_gen_complex_sampled(std::complex* _dest, unsigned int _prn, signed int _fs) +void gps_l2c_m_code_gen_complex_sampled(std::complex* _dest, uint32_t _prn, int32_t _fs) { int32_t* _code = new int32_t[GPS_L2_M_CODE_LENGTH_CHIPS]; if (_prn > 0 and _prn < 51) @@ -100,20 +100,20 @@ void gps_l2c_m_code_gen_complex_sampled(std::complex* _dest, unsigned int gps_l2c_m_code(_code, _prn); } - signed int _samplesPerCode, _codeValueIndex; + int32_t _samplesPerCode, _codeValueIndex; float _ts; float _tc; - const signed int _codeLength = GPS_L2_M_CODE_LENGTH_CHIPS; + const int32_t _codeLength = GPS_L2_M_CODE_LENGTH_CHIPS; //--- Find number of samples per spreading code ---------------------------- - _samplesPerCode = static_cast(static_cast(_fs) / (static_cast(GPS_L2_M_CODE_RATE_HZ) / static_cast(_codeLength))); + _samplesPerCode = static_cast(static_cast(_fs) / (static_cast(GPS_L2_M_CODE_RATE_HZ) / static_cast(_codeLength))); //--- Find time constants -------------------------------------------------- _ts = 1.0 / static_cast(_fs); // Sampling period in sec _tc = 1.0 / static_cast(GPS_L2_M_CODE_RATE_HZ); // C/A chip period in sec //float aux; - for (signed int i = 0; i < _samplesPerCode; i++) + for (int32_t i = 0; i < _samplesPerCode; i++) { //=== Digitizing ======================================================= @@ -121,7 +121,7 @@ void gps_l2c_m_code_gen_complex_sampled(std::complex* _dest, unsigned int //TODO: Check this formula! Seems to start with an extra sample _codeValueIndex = ceil((_ts * (static_cast(i) + 1)) / _tc) - 1; //aux = (_ts * (i + 1)) / _tc; - //_codeValueIndex = static_cast(static_cast(aux)) - 1; + //_codeValueIndex = static_cast(static_cast(aux)) - 1; //--- Make the digitized version of the L2C code ----------------------- if (i == _samplesPerCode - 1) diff --git a/src/algorithms/libs/gps_l2c_signal.h b/src/algorithms/libs/gps_l2c_signal.h index c76c4692f..84d51e485 100644 --- a/src/algorithms/libs/gps_l2c_signal.h +++ b/src/algorithms/libs/gps_l2c_signal.h @@ -34,13 +34,14 @@ #define GNSS_SDR_GPS_L2C_SIGNAL_H_ #include +#include -//!Generates complex GPS L2C M code for the desired SV ID -void gps_l2c_m_code_gen_complex(std::complex* _dest, unsigned int _prn); -void gps_l2c_m_code_gen_float(float* _dest, unsigned int _prn); +//! Generates complex GPS L2C M code for the desired SV ID +void gps_l2c_m_code_gen_complex(std::complex* _dest, uint32_t _prn); +void gps_l2c_m_code_gen_float(float* _dest, uint32_t _prn); //! Generates complex GPS L2C M code for the desired SV ID, and sampled to specific sampling frequency -void gps_l2c_m_code_gen_complex_sampled(std::complex* _dest, unsigned int _prn, signed int _fs); +void gps_l2c_m_code_gen_complex_sampled(std::complex* _dest, uint32_t _prn, int32_t _fs); #endif /* GNSS_GPS_L2C_SIGNAL_H_ */ diff --git a/src/algorithms/libs/gps_l5_signal.cc b/src/algorithms/libs/gps_l5_signal.cc index 84cc1843e..26656d569 100644 --- a/src/algorithms/libs/gps_l5_signal.cc +++ b/src/algorithms/libs/gps_l5_signal.cc @@ -89,7 +89,7 @@ std::deque make_l5i_xa() std::deque xa = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; std::deque y(GPS_L5i_CODE_LENGTH_CHIPS, 0); - for (int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++) + for (int32_t i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++) { y[i] = xa[12]; xa = l5i_xa_shift(xa); @@ -103,7 +103,7 @@ std::deque make_l5i_xb() std::deque xb = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; std::deque y(GPS_L5i_CODE_LENGTH_CHIPS, 0); - for (int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++) + for (int32_t i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++) { y[i] = xb[12]; xb = l5i_xb_shift(xb); @@ -117,7 +117,7 @@ std::deque make_l5q_xa() std::deque xa = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; std::deque y(GPS_L5q_CODE_LENGTH_CHIPS, 0); - for (int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++) + for (int32_t i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++) { y[i] = xa[12]; xa = l5q_xa_shift(xa); @@ -131,7 +131,7 @@ std::deque make_l5q_xb() std::deque xb = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; std::deque y(GPS_L5q_CODE_LENGTH_CHIPS, 0); - for (int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++) + for (int32_t i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++) { y[i] = xb[12]; xb = l5q_xb_shift(xb); @@ -140,47 +140,47 @@ std::deque make_l5q_xb() } -void make_l5i(int32_t* _dest, int prn) +void make_l5i(int32_t* _dest, int32_t prn) { - int xb_offset = GPS_L5i_INIT_REG[prn]; + int32_t xb_offset = GPS_L5i_INIT_REG[prn]; std::deque xb = make_l5i_xb(); std::deque xa = make_l5i_xa(); std::deque xb_shift(GPS_L5i_CODE_LENGTH_CHIPS, 0); - for (int n = 0; n < GPS_L5i_CODE_LENGTH_CHIPS; n++) + for (int32_t n = 0; n < GPS_L5i_CODE_LENGTH_CHIPS; n++) { xb_shift[n] = xb[(xb_offset + n) % GPS_L5i_CODE_LENGTH_CHIPS]; } std::deque out_code(GPS_L5i_CODE_LENGTH_CHIPS, 0); - for (int n = 0; n < GPS_L5i_CODE_LENGTH_CHIPS; n++) + for (int32_t n = 0; n < GPS_L5i_CODE_LENGTH_CHIPS; n++) { _dest[n] = xa[n] xor xb_shift[n]; } } -void make_l5q(int32_t* _dest, int prn) +void make_l5q(int32_t* _dest, int32_t prn) { - int xb_offset = GPS_L5q_INIT_REG[prn]; + int32_t xb_offset = GPS_L5q_INIT_REG[prn]; std::deque xb = make_l5q_xb(); std::deque xa = make_l5q_xa(); std::deque xb_shift(GPS_L5q_CODE_LENGTH_CHIPS, 0); - for (int n = 0; n < GPS_L5q_CODE_LENGTH_CHIPS; n++) + for (int32_t n = 0; n < GPS_L5q_CODE_LENGTH_CHIPS; n++) { xb_shift[n] = xb[(xb_offset + n) % GPS_L5q_CODE_LENGTH_CHIPS]; } std::deque out_code(GPS_L5q_CODE_LENGTH_CHIPS, 0); - for (int n = 0; n < GPS_L5q_CODE_LENGTH_CHIPS; n++) + for (int32_t n = 0; n < GPS_L5q_CODE_LENGTH_CHIPS; n++) { _dest[n] = xa[n] xor xb_shift[n]; } } -void gps_l5i_code_gen_complex(std::complex* _dest, unsigned int _prn) +void gps_l5i_code_gen_complex(std::complex* _dest, uint32_t _prn) { int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS]; @@ -189,7 +189,7 @@ void gps_l5i_code_gen_complex(std::complex* _dest, unsigned int _prn) make_l5i(_code, _prn - 1); } - for (signed int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++) + for (int32_t i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++) { _dest[i] = std::complex(1.0 - 2.0 * _code[i], 0.0); } @@ -197,7 +197,8 @@ void gps_l5i_code_gen_complex(std::complex* _dest, unsigned int _prn) delete[] _code; } -void gps_l5i_code_gen_float(float* _dest, unsigned int _prn) + +void gps_l5i_code_gen_float(float* _dest, uint32_t _prn) { int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS]; @@ -206,7 +207,7 @@ void gps_l5i_code_gen_float(float* _dest, unsigned int _prn) make_l5i(_code, _prn - 1); } - for (signed int i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++) + for (int32_t i = 0; i < GPS_L5i_CODE_LENGTH_CHIPS; i++) { _dest[i] = 1.0 - 2.0 * static_cast(_code[i]); } @@ -214,10 +215,11 @@ void gps_l5i_code_gen_float(float* _dest, unsigned int _prn) delete[] _code; } + /* * Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency */ -void gps_l5i_code_gen_complex_sampled(std::complex* _dest, unsigned int _prn, signed int _fs) +void gps_l5i_code_gen_complex_sampled(std::complex* _dest, uint32_t _prn, int32_t _fs) { int32_t* _code = new int32_t[GPS_L5i_CODE_LENGTH_CHIPS]; if (_prn > 0 and _prn < 51) @@ -225,20 +227,20 @@ void gps_l5i_code_gen_complex_sampled(std::complex* _dest, unsigned int _ make_l5i(_code, _prn - 1); } - signed int _samplesPerCode, _codeValueIndex; + int32_t _samplesPerCode, _codeValueIndex; float _ts; float _tc; - const signed int _codeLength = GPS_L5i_CODE_LENGTH_CHIPS; + const int32_t _codeLength = GPS_L5i_CODE_LENGTH_CHIPS; //--- Find number of samples per spreading code ---------------------------- - _samplesPerCode = static_cast(static_cast(_fs) / (static_cast(GPS_L5i_CODE_RATE_HZ) / static_cast(_codeLength))); + _samplesPerCode = static_cast(static_cast(_fs) / (static_cast(GPS_L5i_CODE_RATE_HZ) / static_cast(_codeLength))); //--- Find time constants -------------------------------------------------- _ts = 1.0 / static_cast(_fs); // Sampling period in sec _tc = 1.0 / static_cast(GPS_L5i_CODE_RATE_HZ); // C/A chip period in sec //float aux; - for (signed int i = 0; i < _samplesPerCode; i++) + for (int32_t i = 0; i < _samplesPerCode; i++) { //=== Digitizing ======================================================= @@ -246,7 +248,7 @@ void gps_l5i_code_gen_complex_sampled(std::complex* _dest, unsigned int _ //TODO: Check this formula! Seems to start with an extra sample _codeValueIndex = ceil((_ts * (static_cast(i) + 1)) / _tc) - 1; //aux = (_ts * (i + 1)) / _tc; - //_codeValueIndex = static_cast(static_cast(aux)) - 1; + //_codeValueIndex = static_cast (static_cast(aux)) - 1; //--- Make the digitized version of the L2C code ----------------------- if (i == _samplesPerCode - 1) @@ -263,7 +265,7 @@ void gps_l5i_code_gen_complex_sampled(std::complex* _dest, unsigned int _ } -void gps_l5q_code_gen_complex(std::complex* _dest, unsigned int _prn) +void gps_l5q_code_gen_complex(std::complex* _dest, uint32_t _prn) { int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS]; @@ -272,7 +274,7 @@ void gps_l5q_code_gen_complex(std::complex* _dest, unsigned int _prn) make_l5q(_code, _prn - 1); } - for (signed int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++) + for (int32_t i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++) { _dest[i] = std::complex(1.0 - 2.0 * _code[i], 0.0); } @@ -280,7 +282,8 @@ void gps_l5q_code_gen_complex(std::complex* _dest, unsigned int _prn) delete[] _code; } -void gps_l5q_code_gen_float(float* _dest, unsigned int _prn) + +void gps_l5q_code_gen_float(float* _dest, uint32_t _prn) { int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS]; @@ -289,17 +292,19 @@ void gps_l5q_code_gen_float(float* _dest, unsigned int _prn) make_l5q(_code, _prn - 1); } - for (signed int i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++) + for (int32_t i = 0; i < GPS_L5q_CODE_LENGTH_CHIPS; i++) { _dest[i] = 1.0 - 2.0 * static_cast(_code[i]); } delete[] _code; } + + /* * Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency */ -void gps_l5q_code_gen_complex_sampled(std::complex* _dest, unsigned int _prn, signed int _fs) +void gps_l5q_code_gen_complex_sampled(std::complex* _dest, uint32_t _prn, int32_t _fs) { int32_t* _code = new int32_t[GPS_L5q_CODE_LENGTH_CHIPS]; if (_prn > 0 and _prn < 51) @@ -307,20 +312,20 @@ void gps_l5q_code_gen_complex_sampled(std::complex* _dest, unsigned int _ make_l5q(_code, _prn - 1); } - signed int _samplesPerCode, _codeValueIndex; + int32_t _samplesPerCode, _codeValueIndex; float _ts; float _tc; - const signed int _codeLength = GPS_L5q_CODE_LENGTH_CHIPS; + const int32_t _codeLength = GPS_L5q_CODE_LENGTH_CHIPS; //--- Find number of samples per spreading code ---------------------------- - _samplesPerCode = static_cast(static_cast(_fs) / (static_cast(GPS_L5q_CODE_RATE_HZ) / static_cast(_codeLength))); + _samplesPerCode = static_cast(static_cast(_fs) / (static_cast(GPS_L5q_CODE_RATE_HZ) / static_cast(_codeLength))); //--- Find time constants -------------------------------------------------- _ts = 1.0 / static_cast(_fs); // Sampling period in sec _tc = 1.0 / static_cast(GPS_L5q_CODE_RATE_HZ); // C/A chip period in sec //float aux; - for (signed int i = 0; i < _samplesPerCode; i++) + for (int32_t i = 0; i < _samplesPerCode; i++) { //=== Digitizing ======================================================= @@ -328,7 +333,7 @@ void gps_l5q_code_gen_complex_sampled(std::complex* _dest, unsigned int _ //TODO: Check this formula! Seems to start with an extra sample _codeValueIndex = ceil((_ts * (static_cast(i) + 1)) / _tc) - 1; //aux = (_ts * (i + 1)) / _tc; - //_codeValueIndex = static_cast(static_cast(aux)) - 1; + //_codeValueIndex = static_cast (static_cast(aux)) - 1; //--- Make the digitized version of the L2C code ----------------------- if (i == _samplesPerCode - 1) diff --git a/src/algorithms/libs/gps_l5_signal.h b/src/algorithms/libs/gps_l5_signal.h index d226b0288..b0b24d2a5 100644 --- a/src/algorithms/libs/gps_l5_signal.h +++ b/src/algorithms/libs/gps_l5_signal.h @@ -34,21 +34,21 @@ #define GNSS_SDR_GPS_L5_SIGNAL_H_ #include - +#include //!Generates complex GPS L5i M code for the desired SV ID -void gps_l5i_code_gen_complex(std::complex* _dest, unsigned int _prn); -void gps_l5i_code_gen_float(float* _dest, unsigned int _prn); +void gps_l5i_code_gen_complex(std::complex* _dest, uint32_t _prn); +void gps_l5i_code_gen_float(float* _dest, uint32_t _prn); //!Generates complex GPS L5q M code for the desired SV ID -void gps_l5q_code_gen_complex(std::complex* _dest, unsigned int _prn); -void gps_l5q_code_gen_float(float* _dest, unsigned int _prn); +void gps_l5q_code_gen_complex(std::complex* _dest, uint32_t _prn); +void gps_l5q_code_gen_float(float* _dest, uint32_t _prn); //! Generates complex GPS L5i M code for the desired SV ID, and sampled to specific sampling frequency -void gps_l5i_code_gen_complex_sampled(std::complex* _dest, unsigned int _prn, signed int _fs); +void gps_l5i_code_gen_complex_sampled(std::complex* _dest, uint32_t _prn, int32_t _fs); //! Generates complex GPS L5q M code for the desired SV ID, and sampled to specific sampling frequency -void gps_l5q_code_gen_complex_sampled(std::complex* _dest, unsigned int _prn, signed int _fs); +void gps_l5q_code_gen_complex_sampled(std::complex* _dest, uint32_t _prn, int32_t _fs); #endif /* GNSS_SDR_GPS_L5_SIGNAL_H_ */ diff --git a/src/algorithms/libs/gps_sdr_signal_processing.cc b/src/algorithms/libs/gps_sdr_signal_processing.cc index 4dee98f05..db3c33eff 100644 --- a/src/algorithms/libs/gps_sdr_signal_processing.cc +++ b/src/algorithms/libs/gps_sdr_signal_processing.cc @@ -32,22 +32,22 @@ #include "gps_sdr_signal_processing.h" -auto auxCeil = [](float x) { return static_cast(static_cast((x) + 1)); }; +auto auxCeil = [](float x) { return static_cast(static_cast((x) + 1)); }; -void gps_l1_ca_code_gen_int(int* _dest, signed int _prn, unsigned int _chip_shift) +void gps_l1_ca_code_gen_int(int32_t* _dest, int32_t _prn, uint32_t _chip_shift) { - const unsigned int _code_length = 1023; + const uint32_t _code_length = 1023; bool G1[_code_length]; bool G2[_code_length]; bool G1_register[10], G2_register[10]; bool feedback1, feedback2; bool aux; - unsigned int lcv, lcv2; - unsigned int delay; - signed int prn_idx; + uint32_t lcv, lcv2; + uint32_t delay; + int32_t prn_idx; /* G2 Delays as defined in GPS-ISD-200D */ - const signed int delays[51] = {5 /*PRN1*/, 6, 7, 8, 17, 18, 139, 140, 141, 251, 252, 254, 255, 256, 257, 258, 469, 470, 471, 472, + const int32_t delays[51] = {5 /*PRN1*/, 6, 7, 8, 17, 18, 139, 140, 141, 251, 252, 254, 255, 256, 257, 258, 469, 470, 471, 472, 473, 474, 509, 512, 513, 514, 515, 516, 859, 860, 861, 862 /*PRN32*/, 145 /*PRN120*/, 175, 52, 21, 237, 235, 886, 657, 634, 762, 355, 1012, 176, 603, 130, 359, 595, 68, 386 /*PRN138*/}; @@ -114,28 +114,28 @@ void gps_l1_ca_code_gen_int(int* _dest, signed int _prn, unsigned int _chip_shif } -void gps_l1_ca_code_gen_float(float* _dest, signed int _prn, unsigned int _chip_shift) +void gps_l1_ca_code_gen_float(float* _dest, int32_t _prn, uint32_t _chip_shift) { - unsigned int _code_length = 1023; - int ca_code_int[_code_length]; + const uint32_t _code_length = 1023; + int32_t ca_code_int[_code_length]; gps_l1_ca_code_gen_int(ca_code_int, _prn, _chip_shift); - for (unsigned int ii = 0; ii < _code_length; ++ii) + for (uint32_t ii = 0; ii < _code_length; ++ii) { _dest[ii] = static_cast(ca_code_int[ii]); } } -void gps_l1_ca_code_gen_complex(std::complex* _dest, signed int _prn, unsigned int _chip_shift) +void gps_l1_ca_code_gen_complex(std::complex* _dest, int32_t _prn, uint32_t _chip_shift) { - unsigned int _code_length = 1023; - int ca_code_int[_code_length]; + const uint32_t _code_length = 1023; + int32_t ca_code_int[_code_length] = {0}; gps_l1_ca_code_gen_int(ca_code_int, _prn, _chip_shift); - for (unsigned int ii = 0; ii < _code_length; ++ii) + for (uint32_t ii = 0; ii < _code_length; ++ii) { _dest[ii] = std::complex(static_cast(ca_code_int[ii]), 0.0f); } @@ -144,27 +144,28 @@ void gps_l1_ca_code_gen_complex(std::complex* _dest, signed int _prn, uns /* * Generates complex GPS L1 C/A code for the desired SV ID and sampled to specific sampling frequency + * NOTICE: the number of samples is rounded towards zero (integer truncation) */ -void gps_l1_ca_code_gen_complex_sampled(std::complex* _dest, unsigned int _prn, signed int _fs, unsigned int _chip_shift) +void gps_l1_ca_code_gen_complex_sampled(std::complex* _dest, uint32_t _prn, int32_t _fs, uint32_t _chip_shift) { // This function is based on the GNU software GPS for MATLAB in the Kay Borre book std::complex _code[1023]; - signed int _samplesPerCode, _codeValueIndex; + int32_t _samplesPerCode, _codeValueIndex; float _ts; float _tc; float aux; - const signed int _codeFreqBasis = 1023000; //Hz - const signed int _codeLength = 1023; + const int32_t _codeFreqBasis = 1023000; //Hz + const int32_t _codeLength = 1023; //--- Find number of samples per spreading code ---------------------------- - _samplesPerCode = static_cast(static_cast(_fs) / static_cast(_codeFreqBasis / _codeLength)); + _samplesPerCode = static_cast(static_cast(_fs) / static_cast(_codeFreqBasis / _codeLength)); //--- Find time constants -------------------------------------------------- _ts = 1.0 / static_cast(_fs); // Sampling period in sec _tc = 1.0 / static_cast(_codeFreqBasis); // C/A chip period in sec gps_l1_ca_code_gen_complex(_code, _prn, _chip_shift); //generate C/A code 1 sample per chip - for (signed int i = 0; i < _samplesPerCode; i++) + for (int32_t i = 0; i < _samplesPerCode; i++) { //=== Digitizing ======================================================= diff --git a/src/algorithms/libs/gps_sdr_signal_processing.h b/src/algorithms/libs/gps_sdr_signal_processing.h index b65db9144..44bb815dd 100644 --- a/src/algorithms/libs/gps_sdr_signal_processing.h +++ b/src/algorithms/libs/gps_sdr_signal_processing.h @@ -34,20 +34,21 @@ #define GNSS_SDR_GPS_SDR_SIGNAL_PROCESSING_H_ #include +#include -//!Generates int GPS L1 C/A code for the desired SV ID and code shift -void gps_l1_ca_code_gen_int(int* _dest, signed int _prn, unsigned int _chip_shift); +//! Generates int GPS L1 C/A code for the desired SV ID and code shift +void gps_l1_ca_code_gen_int(int32_t* _dest, int32_t _prn, uint32_t _chip_shift); -//!Generates float GPS L1 C/A code for the desired SV ID and code shift -void gps_l1_ca_code_gen_float(float* _dest, signed int _prn, unsigned int _chip_shift); +//! Generates float GPS L1 C/A code for the desired SV ID and code shift +void gps_l1_ca_code_gen_float(float* _dest, int32_t _prn, uint32_t _chip_shift); -//!Generates complex GPS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency -void gps_l1_ca_code_gen_complex(std::complex* _dest, signed int _prn, unsigned int _chip_shift); +//! Generates complex GPS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency +void gps_l1_ca_code_gen_complex(std::complex* _dest, int32_t _prn, uint32_t _chip_shift); //! Generates N complex GPS L1 C/A codes for the desired SV ID and code shift -void gps_l1_ca_code_gen_complex_sampled(std::complex* _dest, unsigned int _prn, signed int _fs, unsigned int _chip_shift, unsigned int _ncodes); +void gps_l1_ca_code_gen_complex_sampled(std::complex* _dest, uint32_t _prn, int32_t _fs, uint32_t _chip_shift, uint32_t _ncodes); //! Generates complex GPS L1 C/A code for the desired SV ID and code shift -void gps_l1_ca_code_gen_complex_sampled(std::complex* _dest, unsigned int _prn, signed int _fs, unsigned int _chip_shift); +void gps_l1_ca_code_gen_complex_sampled(std::complex* _dest, uint32_t _prn, int32_t _fs, uint32_t _chip_shift); #endif /* GNSS_SDR_GPS_SDR_SIGNAL_PROCESSING_H_ */ diff --git a/src/algorithms/libs/rtklib/CMakeLists.txt b/src/algorithms/libs/rtklib/CMakeLists.txt index 6cb2441a9..882cd4a81 100644 --- a/src/algorithms/libs/rtklib/CMakeLists.txt +++ b/src/algorithms/libs/rtklib/CMakeLists.txt @@ -16,47 +16,69 @@ # along with GNSS-SDR. If not, see . # -add_definitions( -DGNSS_SDR_VERSION="${VERSION}" ) +add_definitions(-DGNSS_SDR_VERSION="${VERSION}") set(RTKLIB_LIB_SOURCES - rtklib_rtkcmn.cc - rtklib_ephemeris.cc - rtklib_preceph.cc - rtklib_sbas.cc - rtklib_ionex.cc - rtklib_pntpos.cc - rtklib_ppp.cc - rtklib_tides.cc - rtklib_lambda.cc - rtklib_rtkpos.cc - rtklib_conversions.cc - rtklib_stream.cc - rtklib_rtksvr.cc - rtklib_solution.cc - rtklib_rtcm.cc - rtklib_rtcm2.cc - rtklib_rtcm3.cc + rtklib_rtkcmn.cc + rtklib_ephemeris.cc + rtklib_preceph.cc + rtklib_sbas.cc + rtklib_ionex.cc + rtklib_pntpos.cc + rtklib_ppp.cc + rtklib_tides.cc + rtklib_lambda.cc + rtklib_rtkpos.cc + rtklib_conversions.cc + rtklib_stream.cc + rtklib_rtksvr.cc + rtklib_solution.cc + rtklib_rtcm.cc + rtklib_rtcm2.cc + rtklib_rtcm3.cc +) + +set(RTKLIB_LIB_HEADERS + rtklib_rtkcmn.h + rtklib_ephemeris.h + rtklib_preceph.h + rtklib_sbas.h + rtklib_ionex.h + rtklib_pntpos.h + rtklib_ppp.h + rtklib_tides.h + rtklib_lambda.h + rtklib_rtkpos.h + rtklib_conversions.h + rtklib_stream.h + rtklib_rtksvr.h + rtklib_solution.h + rtklib_rtcm.h + rtklib_rtcm2.h + rtklib_rtcm3.h + rtklib.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${Boost_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${Boost_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} ) -file(GLOB RTKLIB_LIB_HEADERS "*.h") list(SORT RTKLIB_LIB_HEADERS) +list(SORT RTKLIB_LIB_SOURCES) + add_library(rtklib_lib ${RTKLIB_LIB_SOURCES} ${RTKLIB_LIB_HEADERS}) source_group(Headers FILES ${RTKLIB_LIB_HEADERS}) add_dependencies(rtklib_lib glog-${glog_RELEASE}) if(OS_IS_MACOSX) set(MAC_LIBRARIES "-framework Accelerate") -endif(OS_IS_MACOSX) +endif() target_link_libraries( rtklib_lib diff --git a/src/algorithms/libs/rtklib/rtklib.h b/src/algorithms/libs/rtklib/rtklib.h index 88e8969e1..14d90b902 100644 --- a/src/algorithms/libs/rtklib/rtklib.h +++ b/src/algorithms/libs/rtklib/rtklib.h @@ -71,7 +71,6 @@ #define socket_t int #define closesocket close #define lock_t pthread_mutex_t -#define thread_t pthread_t #define initlock(f) pthread_mutex_init(f, NULL) #define rtk_lock(f) pthread_mutex_lock(f) #define rtk_unlock(f) pthread_mutex_unlock(f) @@ -201,7 +200,7 @@ const int NSATGLO = (MAXPRNGLO - MINPRNGLO + 1); //!< number of GLONASS satell const int NSYSGLO = 1; */ const int MINPRNGAL = 1; //!< min satellite PRN number of Galileo -const int MAXPRNGAL = 30; //!< max satellite PRN number of Galileo +const int MAXPRNGAL = 36; //!< max satellite PRN number of Galileo const int NSATGAL = (MAXPRNGAL - MINPRNGAL + 1); //!< number of Galileo satellites const int NSYSGAL = 1; @@ -452,27 +451,28 @@ typedef struct } alm_t; -typedef struct { /* GPS/QZS/GAL broadcast ephemeris type */ - int sat; /* satellite number */ - int iode,iodc; /* IODE,IODC */ - int sva; /* SV accuracy (URA index) */ - int svh; /* SV health (0:ok) */ - int week; /* GPS/QZS: gps week, GAL: galileo week */ - int code; /* GPS/QZS: code on L2, GAL/BDS: data sources */ - int flag; /* GPS/QZS: L2 P data flag, BDS: nav type */ - gtime_t toe,toc,ttr; /* Toe,Toc,T_trans */ - /* SV orbit parameters */ - double A,e,i0,OMG0,omg,M0,deln,OMGd,idot; - double crc,crs,cuc,cus,cic,cis; - double toes; /* Toe (s) in week */ - double fit; /* fit interval (h) */ - double f0,f1,f2; /* SV clock parameters (af0,af1,af2) */ - double tgd[4]; /* group delay parameters */ - /* GPS/QZS:tgd[0]=TGD */ - /* GAL :tgd[0]=BGD E5a/E1,tgd[1]=BGD E5b/E1 */ - /* BDS :tgd[0]=BGD1,tgd[1]=BGD2 */ - double isc[4]; /* GPS :isc[0]=ISCL1, isc[1]=ISCL2, isc[2]=ISCL5I, isc[3]=ISCL5Q */ - double Adot,ndot; /* Adot,ndot for CNAV */ +typedef struct +{ /* GPS/QZS/GAL broadcast ephemeris type */ + int sat; /* satellite number */ + int iode, iodc; /* IODE,IODC */ + int sva; /* SV accuracy (URA index) */ + int svh; /* SV health (0:ok) */ + int week; /* GPS/QZS: gps week, GAL: galileo week */ + int code; /* GPS/QZS: code on L2, GAL/BDS: data sources */ + int flag; /* GPS/QZS: L2 P data flag, BDS: nav type */ + gtime_t toe, toc, ttr; /* Toe,Toc,T_trans */ + /* SV orbit parameters */ + double A, e, i0, OMG0, omg, M0, deln, OMGd, idot; + double crc, crs, cuc, cus, cic, cis; + double toes; /* Toe (s) in week */ + double fit; /* fit interval (h) */ + double f0, f1, f2; /* SV clock parameters (af0,af1,af2) */ + double tgd[4]; /* group delay parameters */ + /* GPS/QZS:tgd[0]=TGD */ + /* GAL :tgd[0]=BGD E5a/E1,tgd[1]=BGD E5b/E1 */ + /* BDS :tgd[0]=BGD1,tgd[1]=BGD2 */ + double isc[4]; /* GPS :isc[0]=ISCL1, isc[1]=ISCL2, isc[2]=ISCL5I, isc[3]=ISCL5Q */ + double Adot, ndot; /* Adot,ndot for CNAV */ } eph_t; @@ -1210,7 +1210,7 @@ typedef struct char local[1024]; /* local file path */ int topts[4]; /* time options {poff,tint,toff,tretry} (s) */ gtime_t tnext; /* next retry time (gpst) */ - thread_t thread; /* download thread */ + pthread_t thread; /* download thread */ } ftp_t; @@ -1283,7 +1283,7 @@ typedef struct stream_t stream[8]; /* streams {rov,base,corr,sol1,sol2,logr,logb,logc} */ stream_t *moni; /* monitor stream */ unsigned int tick; /* start tick */ - thread_t thread; /* server thread */ + pthread_t thread; /* server thread */ int cputime; /* CPU time (ms) for a processing cycle */ int prcout; /* missing observation data count */ lock_t lock; /* lock flag */ diff --git a/src/algorithms/libs/rtklib/rtklib_conversions.cc b/src/algorithms/libs/rtklib/rtklib_conversions.cc index 7953509a2..4eb8d218f 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.cc +++ b/src/algorithms/libs/rtklib/rtklib_conversions.cc @@ -116,7 +116,7 @@ geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const Glona eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph) { eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0 }; + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0}; //Galileo is the third satellite system for RTKLIB, so, add the required offset to discriminate Galileo ephemeris rtklib_sat.sat = gal_eph.i_satellite_PRN + NSATGPS + NSATGLO; rtklib_sat.A = gal_eph.A_1 * gal_eph.A_1; @@ -174,7 +174,7 @@ eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph) eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph) { eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0 }; + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0}; rtklib_sat.sat = gps_eph.i_satellite_PRN; rtklib_sat.A = gps_eph.d_sqrt_A * gps_eph.d_sqrt_A; rtklib_sat.M0 = gps_eph.d_M_0; @@ -231,7 +231,7 @@ eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph) eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph) { eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0 }; + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0}; rtklib_sat.sat = gps_cnav_eph.i_satellite_PRN; const double A_REF = 26559710.0; // See IS-GPS-200H, pp. 170 rtklib_sat.A = A_REF + gps_cnav_eph.d_DELTA_A; @@ -291,3 +291,59 @@ eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph) return rtklib_sat; } + +alm_t alm_to_rtklib(const Gps_Almanac& gps_alm) +{ + alm_t rtklib_alm; + + rtklib_alm = {0, 0, 0, 0, {0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + rtklib_alm.sat = gps_alm.i_satellite_PRN; + rtklib_alm.svh = gps_alm.i_SV_health; + rtklib_alm.svconf = gps_alm.i_AS_status; + rtklib_alm.week = gps_alm.i_WNa; + gtime_t toa; + toa.time = gps_alm.i_Toa; + rtklib_alm.toa = toa; + rtklib_alm.A = gps_alm.d_sqrt_A * gps_alm.d_sqrt_A; + rtklib_alm.e = gps_alm.d_e_eccentricity; + rtklib_alm.i0 = (gps_alm.d_Delta_i + 0.3) * PI; + rtklib_alm.OMG0 = gps_alm.d_OMEGA0 * PI; + rtklib_alm.OMGd = gps_alm.d_OMEGA_DOT * PI; + rtklib_alm.omg = gps_alm.d_OMEGA * PI; + rtklib_alm.M0 = gps_alm.d_M_0 * PI; + rtklib_alm.f0 = gps_alm.d_A_f0; + rtklib_alm.f1 = gps_alm.d_A_f1; + rtklib_alm.toas = gps_alm.i_Toa; + + return rtklib_alm; +} + + +alm_t alm_to_rtklib(const Galileo_Almanac& gal_alm) +{ + alm_t rtklib_alm; + + rtklib_alm = {0, 0, 0, 0, {0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + rtklib_alm.sat = gal_alm.i_satellite_PRN + NSATGPS + NSATGLO; + rtklib_alm.svh = gal_alm.E1B_HS; + rtklib_alm.svconf = gal_alm.E1B_HS; + rtklib_alm.week = gal_alm.i_WNa; + gtime_t toa; + toa.time = gal_alm.i_Toa; + rtklib_alm.toa = toa; + rtklib_alm.A = 5440.588203494 + gal_alm.d_Delta_sqrt_A; + rtklib_alm.A = rtklib_alm.A * rtklib_alm.A; + rtklib_alm.e = gal_alm.d_e_eccentricity; + rtklib_alm.i0 = (gal_alm.d_Delta_i + 56.0 / 180.0) * PI; + rtklib_alm.OMG0 = gal_alm.d_OMEGA0 * PI; + rtklib_alm.OMGd = gal_alm.d_OMEGA_DOT * PI; + rtklib_alm.omg = gal_alm.d_OMEGA * PI; + rtklib_alm.M0 = gal_alm.d_M_0 * PI; + rtklib_alm.f0 = gal_alm.d_A_f0; + rtklib_alm.f1 = gal_alm.d_A_f1; + rtklib_alm.toas = gal_alm.i_Toa; + + return rtklib_alm; +} diff --git a/src/algorithms/libs/rtklib/rtklib_conversions.h b/src/algorithms/libs/rtklib/rtklib_conversions.h index 11f4208d1..dca5ec7be 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.h +++ b/src/algorithms/libs/rtklib/rtklib_conversions.h @@ -38,10 +38,16 @@ #include "gps_cnav_ephemeris.h" #include "glonass_gnav_ephemeris.h" #include "glonass_gnav_utc_model.h" +#include "gps_almanac.h" +#include "galileo_almanac.h" eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph); eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph); eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph); + +alm_t alm_to_rtklib(const Gps_Almanac& gps_alm); +alm_t alm_to_rtklib(const Galileo_Almanac& gal_alm); + /*! * \brief Transforms a Glonass_Gnav_Ephemeris to its RTKLIB counterpart * \param glonass_gnav_eph GLONASS GNAV Ephemeris structure diff --git a/src/algorithms/libs/rtklib/rtklib_pntpos.cc b/src/algorithms/libs/rtklib/rtklib_pntpos.cc index d4a10fe65..6473b98a0 100644 --- a/src/algorithms/libs/rtklib/rtklib_pntpos.cc +++ b/src/algorithms/libs/rtklib/rtklib_pntpos.cc @@ -246,7 +246,7 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel, else if (obs->code[i] != CODE_NONE and obs->code[j] == CODE_NONE) { P1 += P1_C1; /* C1->P1 */ - PC = P1 + P1_P2; + PC = P1 - P1_P2; } else if (obs->code[i] == CODE_NONE and obs->code[j] != CODE_NONE) { @@ -739,6 +739,7 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts, { double lam, rate, pos[3], E[9], a[3], e[3], vs[3], cosel; int i, j, nv = 0; + int band = 0; trace(3, "resdop : n=%d\n", n); @@ -747,9 +748,12 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts, for (i = 0; i < n && i < MAXOBS; i++) { - lam = nav->lam[obs[i].sat - 1][0]; + if (obs[i].code[0] != CODE_NONE) band = 0; + if (obs[i].code[1] != CODE_NONE) band = 1; + if (obs[i].code[2] != CODE_NONE) band = 2; + lam = nav->lam[obs[i].sat - 1][band]; - if (obs[i].D[0] == 0.0 || lam == 0.0 || !vsat[i] || norm_rtk(rs + 3 + i * 6, 3) <= 0.0) + if (obs[i].D[band] == 0.0 || lam == 0.0 || !vsat[i] || norm_rtk(rs + 3 + i * 6, 3) <= 0.0) { continue; } @@ -767,7 +771,7 @@ int resdop(const obsd_t *obs, int n, const double *rs, const double *dts, rate = dot(vs, e, 3) + DEFAULT_OMEGA_EARTH_DOT / SPEED_OF_LIGHT * (rs[4 + i * 6] * rr[0] + rs[1 + i * 6] * x[0] - rs[3 + i * 6] * rr[1] - rs[i * 6] * x[1]); /* doppler residual */ - v[nv] = -lam * obs[i].D[0] - (rate + x[3] - SPEED_OF_LIGHT * dts[1 + i * 2]); + v[nv] = -lam * obs[i].D[band] - (rate + x[3] - SPEED_OF_LIGHT * dts[1 + i * 2]); /* design matrix */ for (j = 0; j < 4; j++) H[j + nv * 4] = j < 3 ? -e[j] : 1.0; diff --git a/src/algorithms/libs/rtklib/rtklib_ppp.cc b/src/algorithms/libs/rtklib/rtklib_ppp.cc index b60d627c9..7ac193643 100644 --- a/src/algorithms/libs/rtklib/rtklib_ppp.cc +++ b/src/algorithms/libs/rtklib/rtklib_ppp.cc @@ -673,277 +673,6 @@ void pppoutsolstat(rtk_t *rtk, int level, FILE *fp) } -/* solar/lunar tides (ref [2] 7) ---------------------------------------------*/ -void tide_pl(const double *eu, const double *rp, double GMp, - const double *pos, double *dr) -{ - const double H3 = 0.292, L3 = 0.015; - double r, ep[3], latp, lonp, p, K2, K3, a, H2, L2, dp, du, cosp, sinl, cosl; - int i; - - trace(4, "tide_pl : pos=%.3f %.3f\n", pos[0] * R2D, pos[1] * R2D); - - if ((r = norm_rtk(rp, 3)) <= 0.0) return; - - for (i = 0; i < 3; i++) ep[i] = rp[i] / r; - - K2 = GMp / GME * std::pow(RE_WGS84, 2.0) * std::pow(RE_WGS84, 2.0) / (r * r * r); - K3 = K2 * RE_WGS84 / r; - latp = asin(ep[2]); - lonp = atan2(ep[1], ep[0]); - cosp = cos(latp); - sinl = sin(pos[0]); - cosl = cos(pos[0]); - - /* step1 in phase (degree 2) */ - p = (3.0 * sinl * sinl - 1.0) / 2.0; - H2 = 0.6078 - 0.0006 * p; - L2 = 0.0847 + 0.0002 * p; - a = dot(ep, eu, 3); - dp = K2 * 3.0 * L2 * a; - du = K2 * (H2 * (1.5 * a * a - 0.5) - 3.0 * L2 * a * a); - - /* step1 in phase (degree 3) */ - dp += K3 * L3 * (7.5 * a * a - 1.5); - du += K3 * (H3 * (2.5 * a * a * a - 1.5 * a) - L3 * (7.5 * a * a - 1.5) * a); - - /* step1 out-of-phase (only radial) */ - du += 3.0 / 4.0 * 0.0025 * K2 * sin(2.0 * latp) * sin(2.0 * pos[0]) * sin(pos[1] - lonp); - du += 3.0 / 4.0 * 0.0022 * K2 * cosp * cosp * cosl * cosl * sin(2.0 * (pos[1] - lonp)); - - dr[0] = dp * ep[0] + du * eu[0]; - dr[1] = dp * ep[1] + du * eu[1]; - dr[2] = dp * ep[2] + du * eu[2]; - - trace(5, "tide_pl : dr=%.3f %.3f %.3f\n", dr[0], dr[1], dr[2]); -} - - -/* displacement by solid earth tide (ref [2] 7) ------------------------------*/ -void tide_solid(const double *rsun, const double *rmoon, - const double *pos, const double *E, double gmst, int opt, - double *dr) -{ - double dr1[3], dr2[3], eu[3], du, dn, sinl, sin2l; - - trace(3, "tide_solid: pos=%.3f %.3f opt=%d\n", pos[0] * R2D, pos[1] * R2D, opt); - - /* step1: time domain */ - eu[0] = E[2]; - eu[1] = E[5]; - eu[2] = E[8]; - tide_pl(eu, rsun, GMS, pos, dr1); - tide_pl(eu, rmoon, GMM, pos, dr2); - - /* step2: frequency domain, only K1 radial */ - sin2l = sin(2.0 * pos[0]); - du = -0.012 * sin2l * sin(gmst + pos[1]); - - dr[0] = dr1[0] + dr2[0] + du * E[2]; - dr[1] = dr1[1] + dr2[1] + du * E[5]; - dr[2] = dr1[2] + dr2[2] + du * E[8]; - - /* eliminate permanent deformation */ - if (opt & 8) - { - sinl = sin(pos[0]); - du = 0.1196 * (1.5 * sinl * sinl - 0.5); - dn = 0.0247 * sin2l; - dr[0] += du * E[2] + dn * E[1]; - dr[1] += du * E[5] + dn * E[4]; - dr[2] += du * E[8] + dn * E[7]; - } - trace(5, "tide_solid: dr=%.3f %.3f %.3f\n", dr[0], dr[1], dr[2]); -} - - -/* displacement by ocean tide loading (ref [2] 7) ----------------------------*/ -void tide_oload(gtime_t tut, const double *odisp, double *denu) -{ - const double args[][5] = { - {1.40519E-4, 2.0, -2.0, 0.0, 0.00}, /* M2 */ - {1.45444E-4, 0.0, 0.0, 0.0, 0.00}, /* S2 */ - {1.37880E-4, 2.0, -3.0, 1.0, 0.00}, /* N2 */ - {1.45842E-4, 2.0, 0.0, 0.0, 0.00}, /* K2 */ - {0.72921E-4, 1.0, 0.0, 0.0, 0.25}, /* K1 */ - {0.67598E-4, 1.0, -2.0, 0.0, -0.25}, /* O1 */ - {0.72523E-4, -1.0, 0.0, 0.0, -0.25}, /* P1 */ - {0.64959E-4, 1.0, -3.0, 1.0, -0.25}, /* Q1 */ - {0.53234E-5, 0.0, 2.0, 0.0, 0.00}, /* Mf */ - {0.26392E-5, 0.0, 1.0, -1.0, 0.00}, /* Mm */ - {0.03982E-5, 2.0, 0.0, 0.0, 0.00} /* Ssa */ - }; - const double ep1975[] = {1975, 1, 1, 0, 0, 0}; - double ep[6], fday, days, t, t2, t3, a[5], ang, dp[3] = {0}; - int i, j; - - trace(3, "tide_oload:\n"); - - /* angular argument: see subroutine arg.f for reference [1] */ - time2epoch(tut, ep); - fday = ep[3] * 3600.0 + ep[4] * 60.0 + ep[5]; - ep[3] = ep[4] = ep[5] = 0.0; - days = timediff(epoch2time(ep), epoch2time(ep1975)) / 86400.0; - t = (27392.500528 + 1.000000035 * days) / 36525.0; - t2 = t * t; - t3 = t2 * t; - - a[0] = fday; - a[1] = (279.69668 + 36000.768930485 * t + 3.03E-4 * t2) * D2R; /* H0 */ - a[2] = (270.434358 + 481267.88314137 * t - 0.001133 * t2 + 1.9E-6 * t3) * D2R; /* S0 */ - a[3] = (334.329653 + 4069.0340329577 * t - 0.010325 * t2 - 1.2E-5 * t3) * D2R; /* P0 */ - a[4] = 2.0 * PI; - - /* displacements by 11 constituents */ - for (i = 0; i < 11; i++) - { - ang = 0.0; - for (j = 0; j < 5; j++) ang += a[j] * args[i][j]; - for (j = 0; j < 3; j++) dp[j] += odisp[j + i * 6] * cos(ang - odisp[j + 3 + i * 6] * D2R); - } - denu[0] = -dp[1]; - denu[1] = -dp[2]; - denu[2] = dp[0]; - - trace(5, "tide_oload: denu=%.3f %.3f %.3f\n", denu[0], denu[1], denu[2]); -} - - -/* iers mean pole (ref [7] eq.7.25) ------------------------------------------*/ -void iers_mean_pole(gtime_t tut, double *xp_bar, double *yp_bar) -{ - const double ep2000[] = {2000, 1, 1, 0, 0, 0}; - double y, y2, y3; - - y = timediff(tut, epoch2time(ep2000)) / 86400.0 / 365.25; - - if (y < 3653.0 / 365.25) - { /* until 2010.0 */ - y2 = y * y; - y3 = y2 * y; - *xp_bar = 55.974 + 1.8243 * y + 0.18413 * y2 + 0.007024 * y3; /* (mas) */ - *yp_bar = 346.346 + 1.7896 * y - 0.10729 * y2 - 0.000908 * y3; - } - else - { /* after 2010.0 */ - *xp_bar = 23.513 + 7.6141 * y; /* (mas) */ - *yp_bar = 358.891 - 0.6287 * y; - } -} - - -/* displacement by pole tide (ref [7] eq.7.26) --------------------------------*/ -void tide_pole(gtime_t tut, const double *pos, const double *erpv, - double *denu) -{ - double xp_bar, yp_bar, m1, m2, cosl, sinl; - - trace(3, "tide_pole: pos=%.3f %.3f\n", pos[0] * R2D, pos[1] * R2D); - - /* iers mean pole (mas) */ - iers_mean_pole(tut, &xp_bar, &yp_bar); - - /* ref [7] eq.7.24 */ - m1 = erpv[0] / AS2R - xp_bar * 1E-3; /* (as) */ - m2 = -erpv[1] / AS2R + yp_bar * 1E-3; - - /* sin(2*theta) = sin(2*phi), cos(2*theta)=-cos(2*phi) */ - cosl = cos(pos[1]); - sinl = sin(pos[1]); - denu[0] = 9E-3 * sin(pos[0]) * (m1 * sinl - m2 * cosl); /* de= Slambda (m) */ - denu[1] = -9E-3 * cos(2.0 * pos[0]) * (m1 * cosl + m2 * sinl); /* dn=-Stheta (m) */ - denu[2] = -33E-3 * sin(2.0 * pos[0]) * (m1 * cosl + m2 * sinl); /* du= Sr (m) */ - - trace(5, "tide_pole : denu=%.3f %.3f %.3f\n", denu[0], denu[1], denu[2]); -} - - -/* tidal displacement ---------------------------------------------------------- - * displacements by earth tides - * args : gtime_t tutc I time in utc - * double *rr I site position (ecef) (m) - * int opt I options (or of the followings) - * 1: solid earth tide - * 2: ocean tide loading - * 4: pole tide - * 8: elimate permanent deformation - * double *erp I earth rotation parameters (NULL: not used) - * double *odisp I ocean loading parameters (NULL: not used) - * odisp[0+i*6]: consituent i amplitude radial(m) - * odisp[1+i*6]: consituent i amplitude west (m) - * odisp[2+i*6]: consituent i amplitude south (m) - * odisp[3+i*6]: consituent i phase radial (deg) - * odisp[4+i*6]: consituent i phase west (deg) - * odisp[5+i*6]: consituent i phase south (deg) - * (i=0:M2,1:S2,2:N2,3:K2,4:K1,5:O1,6:P1,7:Q1, - * 8:Mf,9:Mm,10:Ssa) - * double *dr O displacement by earth tides (ecef) (m) - * return : none - * notes : see ref [1], [2] chap 7 - * see ref [4] 5.2.1, 5.2.2, 5.2.3 - * ver.2.4.0 does not use ocean loading and pole tide corrections - *-----------------------------------------------------------------------------*/ -void tidedisp(gtime_t tutc, const double *rr, int opt, const erp_t *erp, - const double *odisp, double *dr) -{ - gtime_t tut; - double pos[2], E[9], drt[3], denu[3], rs[3], rm[3], gmst, erpv[5] = {0}; - int i; -#ifdef IERS_MODEL - double ep[6], fhr; - int year, mon, day; -#endif - - trace(3, "tidedisp: tutc=%s\n", time_str(tutc, 0)); - - if (erp) geterp(erp, tutc, erpv); - - tut = timeadd(tutc, erpv[2]); - - dr[0] = dr[1] = dr[2] = 0.0; - - if (norm_rtk(rr, 3) <= 0.0) return; - - pos[0] = asin(rr[2] / norm_rtk(rr, 3)); - pos[1] = atan2(rr[1], rr[0]); - xyz2enu(pos, E); - - if (opt & 1) - { /* solid earth tides */ - - /* sun and moon position in ecef */ - sunmoonpos(tutc, erpv, rs, rm, &gmst); - -#ifdef IERS_MODEL - time2epoch(tutc, ep); - year = (int)ep[0]; - mon = (int)ep[1]; - day = (int)ep[2]; - fhr = ep[3] + ep[4] / 60.0 + ep[5] / 3600.0; - - /* call DEHANTTIDEINEL */ - dehanttideinel_((double *)rr, &year, &mon, &day, &fhr, rs, rm, drt); -#else - tide_solid(rs, rm, pos, E, gmst, opt, drt); -#endif - for (i = 0; i < 3; i++) dr[i] += drt[i]; - } - if ((opt & 2) && odisp) - { /* ocean tide loading */ - tide_oload(tut, odisp, denu); - matmul("TN", 3, 1, 3, 1.0, E, denu, 0.0, drt); - for (i = 0; i < 3; i++) dr[i] += drt[i]; - } - if ((opt & 4) && erp) - { /* pole tide */ - tide_pole(tut, pos, erpv, denu); - matmul("TN", 3, 1, 3, 1.0, E, denu, 0.0, drt); - for (i = 0; i < 3; i++) dr[i] += drt[i]; - } - trace(5, "tidedisp: dr=%.3f %.3f %.3f\n", dr[0], dr[1], dr[2]); -} - - /* exclude meas of eclipsing satellite (block IIA) ---------------------------*/ void testeclipse(const obsd_t *obs, int n, const nav_t *nav, double *rs) { diff --git a/src/algorithms/libs/rtklib/rtklib_ppp.h b/src/algorithms/libs/rtklib/rtklib_ppp.h index 8d90c3b3e..cd8449e1a 100644 --- a/src/algorithms/libs/rtklib/rtklib_ppp.h +++ b/src/algorithms/libs/rtklib/rtklib_ppp.h @@ -129,21 +129,6 @@ int pppamb(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav, const double /* functions originally included in RTKLIB/src/ppp.c v2.4.2 */ void pppoutsolstat(rtk_t *rtk, int level, FILE *fp); -void tide_pl(const double *eu, const double *rp, double GMp, const double *pos, double *dr); - -void tide_solid(const double *rsun, const double *rmoon, - const double *pos, const double *E, double gmst, int opt, - double *dr); - -void tide_oload(gtime_t tut, const double *odisp, double *denu); - -void iers_mean_pole(gtime_t tut, double *xp_bar, double *yp_bar); - -void tide_pole(gtime_t tut, const double *pos, const double *erpv, double *denu); - -void tidedisp(gtime_t tutc, const double *rr, int opt, const erp_t *erp, - const double *odisp, double *dr); - void testeclipse(const obsd_t *obs, int n, const nav_t *nav, double *rs); double varerr(int sat, int sys, double el, int type, const prcopt_t *opt); diff --git a/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc b/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc index 88cc2ca38..f7e4e76c5 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc @@ -89,38 +89,6 @@ double leaps[MAXLEAPS + 1][7] = {/* leap seconds (y,m,d,h,m,s,utc-gpst) */ {}}; -const prcopt_t prcopt_default = { /* defaults processing options */ - PMODE_SINGLE, 0, 2, SYS_GPS, /* mode, soltype, nf, navsys */ - 15.0 * D2R, {{}, {{}, {}}}, /* elmin, snrmask */ - 0, 1, 1, 1, /* sateph, modear, glomodear, bdsmodear */ - 5, 0, 10, 1, /* maxout, minlock, minfix, armaxiter */ - 0, 0, 0, 0, /* estion, esttrop, dynamics, tidecorr */ - 1, 0, 0, 0, 0, /* niter, codesmooth, intpref, sbascorr, sbassatsel */ - 0, 0, /* rovpos, refpos */ - {100.0, 100.0, 100.0}, /* eratio[] */ - {100.0, 0.003, 0.003, 0.0, 1.0}, /* err[] */ - {30.0, 0.03, 0.3}, /* std[] */ - {1e-4, 1e-3, 1e-4, 1e-1, 1e-2, 0.0}, /* prn[] */ - 5E-12, /* sclkstab */ - {3.0, 0.9999, 0.25, 0.1, 0.05, 0, 0, 0}, /* thresar */ - 0.0, 0.0, 0.05, /* elmaskar, almaskhold, thresslip */ - 30.0, 30.0, 30.0, /* maxtdif, maxinno, maxgdop */ - {}, {}, {}, /* baseline, ru, rb */ - {"", ""}, /* anttype */ - {}, {}, {}, /* antdel, pcv, exsats */ - 0, 0, 0, {"", ""}, {}, 0, {{}, {}}, {{}, {{}, {}}, {{}, {}}, {}, {}}, 0, {}}; - - -const solopt_t solopt_default = { - /* defaults solution output options */ - SOLF_LLH, TIMES_GPST, 1, 3, /* posf, times, timef, timeu */ - 0, 1, 0, 0, 0, 0, /* degf, outhead, outopt, datum, height, geoid */ - 0, 0, 0, /* solstatic, sstat, trace */ - {0.0, 0.0}, /* nmeaintv */ - " ", "", 0 /* separator/program name */ -}; - - const char *formatstrs[32] = {/* stream format strings */ "RTCM 2", /* 0 */ "RTCM 3", /* 1 */ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt index 13a2ee40c..59a8d1ff7 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt @@ -44,37 +44,37 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # retrieve the compiler's version from it string(REGEX MATCH "clang version [0-9.]+" CLANG_OTHER_VERSION ${_err}) string(REGEX MATCH "[0-9.]+" CLANG_VERSION ${CLANG_OTHER_VERSION}) - else("${IS_APPLE}" STREQUAL "") + else() set(MIN_VERSION ${GNSSSDR_APPLECLANG_MIN_VERSION}) set(APPLE_STR "Apple ") # retrieve the compiler's version from it string(REGEX MATCH "(clang-[0-9.]+)" CLANG_APPLE_VERSION ${_err}) string(REGEX MATCH "[0-9.]+" CLANG_VERSION ${CLANG_APPLE_VERSION}) - endif("${IS_APPLE}" STREQUAL "") + endif() if(${CLANG_VERSION} VERSION_LESS "${MIN_VERSION}") message(WARNING "\nThe compiler selected to build VOLK-GNSSSDR (${APPLE_STR}Clang version ${CLANG_VERSION} : ${CMAKE_CXX_COMPILER}) is older than that officially supported (${MIN_VERSION} minimum). This build may or not work. We highly recommend using Apple Clang version ${APPLECLANG_MIN_VERSION} or more recent, or Clang version ${CLANG_MIN_VERSION} or more recent.") - endif(${CLANG_VERSION} VERSION_LESS "${MIN_VERSION}") - else(${_res} STREQUAL "0") + endif() + else() message(WARNING "\nCannot determine the version of the compiler selected to build VOLK-GNSSSDR (${APPLE_STR}Clang : ${CMAKE_CXX_COMPILER}). This build may or not work. We highly recommend using Apple Clang version ${APPLECLANG_MIN_VERSION} or more recent, or Clang version ${CLANG_MIN_VERSION} or more recent.") - endif(${_res} STREQUAL "0") -endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + endif() +endif() # Enable C++17 support in GCC >= 8.0.0 # Enable C++14 support in 8.0.0 > GCC >= 6.1.1 # Fallback to C++11 when using GCC < 6.1.1 -if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) +if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.1.1") set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++11") - else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.1.1") + else() if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0.0") set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++14") - else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0.0") + else() set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++17") - endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0.0") - endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.1.1") + endif() + endif() set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -Wall -Wextra") #Add warning flags: For "-Wall" see http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html -endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) +endif() # Enable C++17 support in Clang >= 6.0.0 # Enable C++14 support in 6.0.0 > Clang >= 3.5.0 or AppleClang >= 600 @@ -84,28 +84,28 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # See https://trac.macports.org/wiki/XcodeVersionInfo for Apple Clang version equivalences if(CLANG_VERSION VERSION_LESS "600") set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++11") - else(CLANG_VERSION VERSION_LESS "600") + else() set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++14") - endif(CLANG_VERSION VERSION_LESS "600") - else(CMAKE_SYSTEM_NAME MATCHES "Darwin") + endif() + else() if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.5.0") set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++11") - else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.5.0") + else() if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0.0") set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++14") - else(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0.0") + else() set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -std=c++17") - endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0.0") - endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.5.0") - endif(CMAKE_SYSTEM_NAME MATCHES "Darwin") -endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + endif() + endif() + endif() +endif() -if(NOT (CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) +if(NOT ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) if(NOT (CMAKE_VERSION VERSION_LESS "3.1")) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 11) - endif(NOT (CMAKE_VERSION VERSION_LESS "3.1")) -endif(NOT (CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) + endif() +endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_CXX_FLAGS} -Wall") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") @@ -113,9 +113,9 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") if(CMAKE_VERSION VERSION_GREATER "3.0") cmake_policy(SET CMP0042 NEW) if(CMAKE_VERSION VERSION_GREATER "3.9") - cmake_policy(SET CMP0068 NEW) - endif(CMAKE_VERSION VERSION_GREATER "3.9") -endif(CMAKE_VERSION VERSION_GREATER "3.0") + cmake_policy(SET CMP0068 NEW) + endif() +endif() option(ENABLE_STRIP "Create a stripped volk_gnsssdr_profile binary (without shared libraries)" OFF) @@ -129,7 +129,7 @@ if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") message(STATUS "Build type not specified: defaulting to release.") endif() -VOLK_CHECK_BUILD_TYPE(${CMAKE_BUILD_TYPE}) +volk_check_build_type(${CMAKE_BUILD_TYPE}) set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.") @@ -144,14 +144,14 @@ include(VolkVersion) #setup version info ######################################################################## # Environment setup ######################################################################## -IF(NOT DEFINED BOOST_ROOT AND NOT DEFINED ENV{BOOST_ROOT}) - SET(BOOST_ROOT ${CMAKE_INSTALL_PREFIX}) -ENDIF() +if(NOT DEFINED BOOST_ROOT AND NOT DEFINED ENV{BOOST_ROOT}) + set(BOOST_ROOT ${CMAKE_INSTALL_PREFIX}) +endif() -IF(NOT DEFINED CROSSCOMPILE_MULTILIB) - SET(CROSSCOMPILE_MULTILIB "") -ENDIF() -SET(CROSSCOMPILE_MULTILIB ${CROSSCOMPILE_MULTILIB} CACHE STRING "Define \"true\" if you have and want to use multiple C development libs installed for cross compile") +if(NOT DEFINED CROSSCOMPILE_MULTILIB) + set(CROSSCOMPILE_MULTILIB "") +endif() +set(CROSSCOMPILE_MULTILIB ${CROSSCOMPILE_MULTILIB} CACHE STRING "Define \"true\" if you have and want to use multiple C development libs installed for cross compile") if(MSVC) add_definitions(-D_USE_MATH_DEFINES) #enables math constants on all supported versions of MSVC @@ -160,16 +160,16 @@ if(MSVC) add_compile_options(/wd4752) add_compile_options(/wo4273) add_compile_options(/wo4838) -endif(MSVC) +endif() # allow 'large' files in 32 bit builds if(UNIX) - add_definitions( -D_LARGEFILE_SOURCE - -D_FILE_OFFSET_BITS=64 - -D_LARGE_FILES - -D_FORTIFY_SOURCE=2 - ) -endif(UNIX) + add_definitions(-D_LARGEFILE_SOURCE + -D_FILE_OFFSET_BITS=64 + -D_LARGE_FILES + -D_FORTIFY_SOURCE=2 + ) +endif() ######################################################################## @@ -178,9 +178,9 @@ endif(UNIX) # Python include(VolkPython) #sets PYTHON_EXECUTABLE and PYTHON_DASH_B -VOLK_PYTHON_CHECK_MODULE("python >= 2.7" sys "sys.version.split()[0] >= '2.7'" PYTHON_MIN_VER_FOUND) -VOLK_PYTHON_CHECK_MODULE("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND) -VOLK_PYTHON_CHECK_MODULE("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) +volk_python_check_module("python >= 2.7" sys "sys.version.split()[0] >= '2.7'" PYTHON_MIN_VER_FOUND) +volk_python_check_module("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND) +volk_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) if(NOT PYTHON_MIN_VER_FOUND) @@ -199,16 +199,16 @@ endif() # Boost if(MSVC) - if (NOT DEFINED BOOST_ALL_DYN_LINK) + if(NOT DEFINED BOOST_ALL_DYN_LINK) set(BOOST_ALL_DYN_LINK TRUE) endif() set(BOOST_ALL_DYN_LINK "${BOOST_ALL_DYN_LINK}" CACHE BOOL "boost enable dynamic linking") if(BOOST_ALL_DYN_LINK) add_definitions(-DBOOST_ALL_DYN_LINK) #setup boost auto-linking in msvc - else(BOOST_ALL_DYN_LINK) + else() unset(BOOST_REQUIRED_COMPONENTS) #empty components list for static link - endif(BOOST_ALL_DYN_LINK) -endif(MSVC) + endif() +endif() include(VolkBoost) @@ -220,9 +220,9 @@ endif() option(ENABLE_ORC "Enable Orc" True) if(ENABLE_ORC) find_package(ORC) -else(ENABLE_ORC) +else() message(STATUS "Disabling use of ORC") -endif(ENABLE_ORC) +endif() ######################################################################## @@ -240,7 +240,7 @@ if(DOXYGEN_FOUND) WORKING_DIRECTORY ${PROJECT_BINARY_DIR} COMMENT "Generating documentation with Doxygen" VERBATIM ) -endif(DOXYGEN_FOUND) +endif() ######################################################################## @@ -255,7 +255,8 @@ set(includedir "\${prefix}/include") configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/volk_gnsssdr.pc.in ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr.pc -@ONLY) + @ONLY +) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr.pc @@ -304,17 +305,17 @@ if(APPLE) set(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/${VOLK_LIBRARY_DIR} CACHE PATH "Library Install Name Destination Directory" FORCE) - endif(NOT CMAKE_INSTALL_NAME_DIR) + endif() if(NOT CMAKE_INSTALL_RPATH) set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${VOLK_LIBRARY_DIR} CACHE PATH "Library Install RPath" FORCE) - endif(NOT CMAKE_INSTALL_RPATH) + endif() if(NOT CMAKE_BUILD_WITH_INSTALL_RPATH) set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "Do Build Using Library Install RPath" FORCE) - endif(NOT CMAKE_BUILD_WITH_INSTALL_RPATH) -endif(APPLE) + endif() +endif() ######################################################################## @@ -358,7 +359,7 @@ configure_file( if(NOT CMAKE_MODULES_DIR) set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake) -endif(NOT CMAKE_MODULES_DIR) +endif() install( FILES @@ -371,7 +372,7 @@ install( ######################################################################## # Option to enable QA testing, on by default ######################################################################## -OPTION(ENABLE_TESTING "Enable QA testing" ON) +option(ENABLE_TESTING "Enable QA testing" ON) if(ENABLE_TESTING) message(STATUS "QA Testing is enabled.") else() @@ -383,7 +384,7 @@ message(STATUS " Modify using: -DENABLE_TESTING=ON/OFF") ######################################################################## # Option to enable post-build profiling using volk_profile, off by default ######################################################################## -OPTION(ENABLE_PROFILING "Launch system profiler after build" OFF) +option(ENABLE_PROFILING "Launch system profiler after build" OFF) if(ENABLE_PROFILING) set(ENABLE_STATIC_LIBS ON) if(DEFINED VOLK_CONFIGPATH) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/CMakeLists.txt index c95967d70..b1afa4ed0 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/CMakeLists.txt @@ -22,7 +22,7 @@ ######################################################################## if(MSVC) include_directories(${PROJECT_SOURCE_DIR}/cmake/msvc) -endif(MSVC) +endif() include_directories( ${CMAKE_CURRENT_SOURCE_DIR} @@ -37,26 +37,26 @@ include_directories( set(Clang_required_link "") if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(Clang_required_link "c++") - endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") -endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set(Clang_required_link "c++") + endif() +endif() if(ORC_FOUND) set(orc_lib ${ORC_LIBRARIES}) -elseif(ORC_FOUND) +else() set(orc_lib "") -endif(ORC_FOUND) +endif() # allow 'large' files in 32 bit builds if(UNIX) - add_definitions( -D_LARGEFILE_SOURCE - -D_FILE_OFFSET_BITS=64 - -D_LARGE_FILES - ) -endif(UNIX) + add_definitions(-D_LARGEFILE_SOURCE + -D_FILE_OFFSET_BITS=64 + -D_LARGE_FILES + ) +endif() # MAKE volk_gnsssdr_profile @@ -68,18 +68,18 @@ add_executable(volk_gnsssdr_profile if(ENABLE_STATIC_LIBS) target_link_libraries(volk_gnsssdr_profile volk_gnsssdr_static ${Boost_LIBRARIES} ${Clang_required_link} ${orc_lib}) -else(ENABLE_STATIC_LIBS) +else() target_link_libraries(volk_gnsssdr_profile volk_gnsssdr ${Boost_LIBRARIES} ${Clang_required_link} ${orc_lib}) add_dependencies(volk_gnsssdr_profile volk_gnsssdr) -endif(ENABLE_STATIC_LIBS) +endif() if(ENABLE_STRIP) - if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) + if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) set_target_properties(volk_gnsssdr_profile - PROPERTIES LINK_FLAGS "-s") - endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) -endif(ENABLE_STRIP) + PROPERTIES LINK_FLAGS "-s") + endif() +endif() install( @@ -92,18 +92,18 @@ install( # MAKE volk_gnsssdr-config-info add_executable(volk_gnsssdr-config-info volk_gnsssdr-config-info.cc ${CMAKE_CURRENT_SOURCE_DIR}/volk_gnsssdr_option_helpers.cc) if(ENABLE_STATIC_LIBS) - target_link_libraries(volk_gnsssdr-config-info volk_gnsssdr_static ${Clang_required_link} ${orc_lib}) -else(ENABLE_STATIC_LIBS) - target_link_libraries(volk_gnsssdr-config-info volk_gnsssdr ${Clang_required_link} ${orc_lib}) - add_dependencies(volk_gnsssdr-config-info volk_gnsssdr) -endif(ENABLE_STATIC_LIBS) + target_link_libraries(volk_gnsssdr-config-info volk_gnsssdr_static ${Clang_required_link} ${orc_lib}) +else() + target_link_libraries(volk_gnsssdr-config-info volk_gnsssdr ${Clang_required_link} ${orc_lib}) + add_dependencies(volk_gnsssdr-config-info volk_gnsssdr) +endif() if(ENABLE_STRIP) - if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) + if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) set_target_properties(volk_gnsssdr-config-info - PROPERTIES LINK_FLAGS "-s") - endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) -endif(ENABLE_STRIP) + PROPERTIES LINK_FLAGS "-s") + endif() +endif() install( TARGETS volk_gnsssdr-config-info @@ -114,17 +114,14 @@ install( # Launch volk_gnsssdr_profile if requested to do so if(ENABLE_PROFILING) - if(DEFINED VOLK_CONFIGPATH) + if(DEFINED VOLK_CONFIGPATH) set( VOLK_CONFIG_ARG "-p${VOLK_CONFIGPATH}" ) set( VOLK_CONFIG "${VOLK_CONFIGPATH}/volk_gnsssdr_config" ) - endif() - add_custom_command(OUTPUT ${VOLK_CONFIG} + endif() + add_custom_command(OUTPUT ${VOLK_CONFIG} COMMAND volk_gnsssdr_profile "${VOLK_CONFIG_ARG}" DEPENDS volk_gnsssdr_profile COMMENT "Launching profiler, this may take a few minutes..." ) add_custom_target(volk-gnsssdr-profile-run ALL DEPENDS ${VOLK_CONFIG}) endif() - - - diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindORC.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindORC.cmake index 0341d3f7b..1154d2e7a 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindORC.cmake +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindORC.cmake @@ -16,52 +16,56 @@ # along with GNSS-SDR. If not, see . -FIND_PACKAGE(PkgConfig) -PKG_CHECK_MODULES(PC_ORC "orc-0.4 > 0.4.22") +find_package(PkgConfig) +pkg_check_modules(PC_ORC "orc-0.4 > 0.4.22") -FIND_PROGRAM(ORCC_EXECUTABLE orcc - HINTS ${PC_ORC_TOOLSDIR} - PATHS ${ORC_ROOT}/bin ${CMAKE_INSTALL_PREFIX}/bin) +find_program(ORCC_EXECUTABLE orcc + HINTS ${PC_ORC_TOOLSDIR} + PATHS ${ORC_ROOT}/bin ${CMAKE_INSTALL_PREFIX}/bin +) -FIND_PATH(ORC_INCLUDE_DIR NAMES orc/orc.h - HINTS ${PC_ORC_INCLUDEDIR} - PATHS ${ORC_ROOT}/include/orc-0.4 ${CMAKE_INSTALL_PREFIX}/include/orc-0.4) - - -FIND_PATH(ORC_LIBRARY_DIR NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}orc-0.4${CMAKE_SHARED_LIBRARY_SUFFIX} - HINTS ${PC_ORC_LIBDIR} - /usr/local/lib - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib64 - /usr/lib - PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) - -FIND_LIBRARY(ORC_LIB orc-0.4 - HINTS ${PC_ORC_LIBRARY_DIRS} - PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) - -LIST(APPEND ORC_LIBRARY - ${ORC_LIB} +find_path(ORC_INCLUDE_DIR NAMES orc/orc.h + HINTS ${PC_ORC_INCLUDEDIR} + PATHS ${ORC_ROOT}/include/orc-0.4 ${CMAKE_INSTALL_PREFIX}/include/orc-0.4 ) -SET(ORC_INCLUDE_DIRS ${ORC_INCLUDE_DIR}) -SET(ORC_LIBRARIES ${ORC_LIBRARY}) -SET(ORC_LIBRARY_DIRS ${ORC_LIBRARY_DIR}) +find_path(ORC_LIBRARY_DIR + NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}orc-0.4${CMAKE_SHARED_LIBRARY_SUFFIX} + HINTS ${PC_ORC_LIBDIR} + /usr/local/lib + /usr/lib/x86_64-linux-gnu + /usr/lib/i386-linux-gnu + /usr/lib/arm-linux-gnueabihf + /usr/lib/arm-linux-gnueabi + /usr/lib/aarch64-linux-gnu + /usr/lib/mipsel-linux-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/powerpc-linux-gnu + /usr/lib/powerpc64-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/hppa-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/lib64 + /usr/lib + PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX} +) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(ORC "orc files" ORC_LIBRARY ORC_INCLUDE_DIR ORCC_EXECUTABLE) +find_library(ORC_LIB orc-0.4 + HINTS ${PC_ORC_LIBRARY_DIRS} + PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) + +list(APPEND ORC_LIBRARY + ${ORC_LIB} +) + + +set(ORC_INCLUDE_DIRS ${ORC_INCLUDE_DIR}) +set(ORC_LIBRARIES ${ORC_LIBRARY}) +set(ORC_LIBRARY_DIRS ${ORC_LIBRARY_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ORC "orc files" ORC_LIBRARY ORC_INCLUDE_DIR ORCC_EXECUTABLE) mark_as_advanced(ORC_INCLUDE_DIR ORC_LIBRARY ORCC_EXECUTABLE) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkAddTest.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkAddTest.cmake index b01a99594..a2097046e 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkAddTest.cmake +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkAddTest.cmake @@ -30,7 +30,7 @@ set(__INCLUDED_VOLK_ADD_TEST TRUE) function(VOLK_GEN_TEST executable_name) include(CMakeParseArgumentsCopy) - CMAKE_PARSE_ARGUMENTS(VOLK_TEST "" "" "SOURCES;TARGET_DEPS;EXTRA_LIB_DIRS;ENVIRONS;ARGS" ${ARGN}) + cmake_parse_arguments(VOLK_TEST "" "" "SOURCES;TARGET_DEPS;EXTRA_LIB_DIRS;ENVIRONS;ARGS" ${ARGN}) add_executable(${executable_name} ${VOLK_TEST_SOURCES}) target_link_libraries(${executable_name} ${VOLK_TEST_TARGET_DEPS}) endfunction() @@ -53,7 +53,7 @@ function(VOLK_ADD_TEST test_name executable_name) #parse the arguments for component names include(CMakeParseArgumentsCopy) - CMAKE_PARSE_ARGUMENTS(VOLK_TEST "" "" "TARGET_DEPS;EXTRA_LIB_DIRS;ENVIRONS;ARGS" ${ARGN}) + cmake_parse_arguments(VOLK_TEST "" "" "TARGET_DEPS;EXTRA_LIB_DIRS;ENVIRONS;ARGS" ${ARGN}) #set the initial environs to use set(environs ${VOLK_TEST_ENVIRONS}) @@ -146,7 +146,7 @@ function(VOLK_ADD_TEST test_name executable_name) #each line sets an environment variable foreach(environ ${environs}) file(APPEND ${sh_file} "export ${environ}\n") - endforeach(environ) + endforeach() set(VOLK_TEST_ARGS "${test_name}") @@ -166,7 +166,7 @@ function(VOLK_ADD_TEST test_name executable_name) COMMAND ${SHELL} ${sh_file} ${TARGET_DIR_LIST} ) - endif(UNIX) + endif() if(WIN32) #In the land of windows, all libraries must be in the PATH. Since @@ -199,7 +199,7 @@ function(VOLK_ADD_TEST test_name executable_name) #each line sets an environment variable foreach(environ ${environs}) file(APPEND ${bat_file} "SET ${environ}\n") - endforeach(environ) + endforeach() set(VOLK_TEST_ARGS "${test_name}") @@ -213,7 +213,7 @@ function(VOLK_ADD_TEST test_name executable_name) add_test(NAME qa_${test_name} COMMAND ${bat_file} ${TARGET_DIR_LIST} ) - endif(WIN32) + endif() -endfunction(VOLK_ADD_TEST) +endfunction() diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkBoost.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkBoost.cmake index 074b7003e..2aea96b2a 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkBoost.cmake +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkBoost.cmake @@ -31,21 +31,21 @@ set(BOOST_REQUIRED_COMPONENTS if(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64") list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix -endif(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64") +endif() if(MSVC) set(BOOST_REQUIRED_COMPONENTS ${BOOST_REQUIRED_COMPONENTS} chrono) - if (NOT DEFINED BOOST_ALL_DYN_LINK) + if(NOT DEFINED BOOST_ALL_DYN_LINK) set(BOOST_ALL_DYN_LINK TRUE) endif() set(BOOST_ALL_DYN_LINK "${BOOST_ALL_DYN_LINK}" CACHE BOOL "boost enable dynamic linking") if(BOOST_ALL_DYN_LINK) add_definitions(-DBOOST_ALL_DYN_LINK) #setup boost auto-linking in msvc - else(BOOST_ALL_DYN_LINK) + else() unset(BOOST_REQUIRED_COMPONENTS) #empty components list for static link - endif(BOOST_ALL_DYN_LINK) -endif(MSVC) + endif() +endif() find_package(Boost "1.35" COMPONENTS ${BOOST_REQUIRED_COMPONENTS}) @@ -61,15 +61,17 @@ set(Boost_ADDITIONAL_VERSIONS "1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59" "1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64" "1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69" + "1.70.0" "1.70" "1.71.0" "1.71" "1.72.0" "1.72" "1.73.0" "1.73" "1.74.0" "1.74" + "1.75.0" "1.75" "1.76.0" "1.76" "1.77.0" "1.77" "1.78.0" "1.78" "1.79.0" "1.79" ) # Boost 1.52 disabled, see https://svn.boost.org/trac/boost/ticket/7669 # Similar problems with Boost 1.46 and 1.47. -OPTION(ENABLE_BAD_BOOST "Enable known bad versions of Boost" OFF) +option(ENABLE_BAD_BOOST "Enable known bad versions of Boost" OFF) if(ENABLE_BAD_BOOST) - MESSAGE(STATUS "Enabling use of known bad versions of Boost.") -endif(ENABLE_BAD_BOOST) + message(STATUS "Enabling use of known bad versions of Boost.") +endif() # For any unsuitable Boost version, add the version number below in # the following format: XXYYZZ @@ -78,17 +80,17 @@ endif(ENABLE_BAD_BOOST) # YY is the minor version number ('46' for 1.46) # ZZ is the patcher version number (typically just '00') set(Boost_NOGO_VERSIONS - 104600 104601 104700 105200 - ) + 104600 104601 104700 105200 +) foreach(ver ${Boost_NOGO_VERSIONS}) - if("${Boost_VERSION}" STREQUAL "${ver}") - if(NOT ENABLE_BAD_BOOST) - MESSAGE(STATUS "WARNING: Found a known bad version of Boost (v${Boost_VERSION}). Disabling.") - set(Boost_FOUND FALSE) - else(NOT ENABLE_BAD_BOOST) - MESSAGE(STATUS "WARNING: Found a known bad version of Boost (v${Boost_VERSION}). Continuing anyway.") - set(Boost_FOUND TRUE) - endif(NOT ENABLE_BAD_BOOST) - endif("${Boost_VERSION}" STREQUAL "${ver}") -endforeach(ver) + if("${Boost_VERSION}" STREQUAL "${ver}") + if(NOT ENABLE_BAD_BOOST) + message(STATUS "WARNING: Found a known bad version of Boost (v${Boost_VERSION}). Disabling.") + set(Boost_FOUND FALSE) + else() + message(STATUS "WARNING: Found a known bad version of Boost (v${Boost_VERSION}). Continuing anyway.") + set(Boost_FOUND TRUE) + endif() + endif() +endforeach() diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkBuildTypes.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkBuildTypes.cmake index 53e47ddbf..6f45f1683 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkBuildTypes.cmake +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkBuildTypes.cmake @@ -38,6 +38,7 @@ set(__INCLUDED_VOLK_BUILD_TYPES_CMAKE TRUE) list(APPEND AVAIL_BUILDTYPES None Debug Release RelWithDebInfo MinSizeRel DebugParanoid NoOptWithASM O2WithASM O3WithASM + ASAN ) ######################################################################## @@ -52,16 +53,16 @@ list(APPEND AVAIL_BUILDTYPES # the avialable build types. ######################################################################## function(VOLK_CHECK_BUILD_TYPE settype) - STRING(TOUPPER ${settype} _settype) + string(TOUPPER ${settype} _settype) foreach(btype ${AVAIL_BUILDTYPES}) - STRING(TOUPPER ${btype} _btype) + string(TOUPPER ${btype} _btype) if(${_settype} STREQUAL ${_btype}) return() # found it; exit cleanly - endif(${_settype} STREQUAL ${_btype}) - endforeach(btype) + endif() + endforeach() # Build type not found; error out message(FATAL_ERROR "Build type '${settype}' not valid, must be one of: ${AVAIL_BUILDTYPES}") -endfunction(VOLK_CHECK_BUILD_TYPE) +endfunction() ######################################################################## # For GCC and Clang, we can set a build type: @@ -73,23 +74,23 @@ endfunction(VOLK_CHECK_BUILD_TYPE) # NOTE: This is not defined on Windows systems. ######################################################################## if(NOT WIN32) - SET(CMAKE_CXX_FLAGS_DEBUGPARANOID "-Wall -Wextra -g -O0" CACHE STRING + set(CMAKE_CXX_FLAGS_DEBUGPARANOID "-Wall -Wextra -g -O0" CACHE STRING "Flags used by the C++ compiler during DebugParanoid builds." FORCE) - SET(CMAKE_C_FLAGS_DEBUGPARANOID "-Wall -Wextra -g -O0" CACHE STRING + set(CMAKE_C_FLAGS_DEBUGPARANOID "-Wall -Wextra -g -O0" CACHE STRING "Flags used by the C compiler during DebugParanoid builds." FORCE) - SET(CMAKE_EXE_LINKER_FLAGS_DEBUGPARANOID + set(CMAKE_EXE_LINKER_FLAGS_DEBUGPARANOID "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING "Flags used for linking binaries during NoOptWithASM builds." FORCE) - SET(CMAKE_SHARED_LINKER_FLAGS_DEBUGPARANOID + set(CMAKE_SHARED_LINKER_FLAGS_DEBUGPARANOID "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING "Flags used by the shared lib linker during NoOptWithASM builds." FORCE) - MARK_AS_ADVANCED( + mark_as_advanced( CMAKE_CXX_FLAGS_DEBUGPARANOID CMAKE_C_FLAGS_DEBUGPARANOID CMAKE_EXE_LINKER_FLAGS_DEBUGPARANOID CMAKE_SHARED_LINKER_DEBUGPARANOID) -endif(NOT WIN32) +endif() ######################################################################## @@ -104,23 +105,23 @@ endif(NOT WIN32) # NOTE: This is not defined on Windows systems. ######################################################################## if(NOT WIN32) - SET(CMAKE_CXX_FLAGS_NOOPTWITHASM "-save-temps -g -O0" CACHE STRING + set(CMAKE_CXX_FLAGS_NOOPTWITHASM "-save-temps -g -O0" CACHE STRING "Flags used by the C++ compiler during NoOptWithASM builds." FORCE) - SET(CMAKE_C_FLAGS_NOOPTWITHASM "-save-temps -g -O0" CACHE STRING + set(CMAKE_C_FLAGS_NOOPTWITHASM "-save-temps -g -O0" CACHE STRING "Flags used by the C compiler during NoOptWithASM builds." FORCE) - SET(CMAKE_EXE_LINKER_FLAGS_NOOPTWITHASM + set(CMAKE_EXE_LINKER_FLAGS_NOOPTWITHASM "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING "Flags used for linking binaries during NoOptWithASM builds." FORCE) - SET(CMAKE_SHARED_LINKER_FLAGS_NOOPTWITHASM + set(CMAKE_SHARED_LINKER_FLAGS_NOOPTWITHASM "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING "Flags used by the shared lib linker during NoOptWithASM builds." FORCE) - MARK_AS_ADVANCED( + mark_as_advanced( CMAKE_CXX_FLAGS_NOOPTWITHASM CMAKE_C_FLAGS_NOOPTWITHASM CMAKE_EXE_LINKER_FLAGS_NOOPTWITHASM CMAKE_SHARED_LINKER_FLAGS_NOOPTWITHASM) -endif(NOT WIN32) +endif() ######################################################################## @@ -136,23 +137,23 @@ endif(NOT WIN32) ######################################################################## if(NOT WIN32) - SET(CMAKE_CXX_FLAGS_O2WITHASM "-save-temps -g -O2" CACHE STRING + set(CMAKE_CXX_FLAGS_O2WITHASM "-save-temps -g -O2" CACHE STRING "Flags used by the C++ compiler during O2WithASM builds." FORCE) - SET(CMAKE_C_FLAGS_O2WITHASM "-save-temps -g -O2" CACHE STRING + set(CMAKE_C_FLAGS_O2WITHASM "-save-temps -g -O2" CACHE STRING "Flags used by the C compiler during O2WithASM builds." FORCE) - SET(CMAKE_EXE_LINKER_FLAGS_O2WITHASM + set(CMAKE_EXE_LINKER_FLAGS_O2WITHASM "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING "Flags used for linking binaries during O2WithASM builds." FORCE) - SET(CMAKE_SHARED_LINKER_FLAGS_O2WITHASM + set(CMAKE_SHARED_LINKER_FLAGS_O2WITHASM "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING "Flags used by the shared lib linker during O2WithASM builds." FORCE) - MARK_AS_ADVANCED( + mark_as_advanced( CMAKE_CXX_FLAGS_O2WITHASM CMAKE_C_FLAGS_O2WITHASM CMAKE_EXE_LINKER_FLAGS_O2WITHASM CMAKE_SHARED_LINKER_FLAGS_O2WITHASM) -endif(NOT WIN32) +endif() ######################################################################## @@ -168,20 +169,42 @@ endif(NOT WIN32) ######################################################################## if(NOT WIN32) - SET(CMAKE_CXX_FLAGS_O3WITHASM "-save-temps -g -O3" CACHE STRING + set(CMAKE_CXX_FLAGS_O3WITHASM "-save-temps -g -O3" CACHE STRING "Flags used by the C++ compiler during O3WithASM builds." FORCE) - SET(CMAKE_C_FLAGS_O3WITHASM "-save-temps -g -O3" CACHE STRING + set(CMAKE_C_FLAGS_O3WITHASM "-save-temps -g -O3" CACHE STRING "Flags used by the C compiler during O3WithASM builds." FORCE) - SET(CMAKE_EXE_LINKER_FLAGS_O3WITHASM + set(CMAKE_EXE_LINKER_FLAGS_O3WITHASM "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING "Flags used for linking binaries during O3WithASM builds." FORCE) - SET(CMAKE_SHARED_LINKER_FLAGS_O3WITHASM + set(CMAKE_SHARED_LINKER_FLAGS_O3WITHASM "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING "Flags used by the shared lib linker during O3WithASM builds." FORCE) - MARK_AS_ADVANCED( + mark_as_advanced( CMAKE_CXX_FLAGS_O3WITHASM CMAKE_C_FLAGS_O3WITHASM CMAKE_EXE_LINKER_FLAGS_O3WITHASM CMAKE_SHARED_LINKER_FLAGS_O3WITHASM) -endif(NOT WIN32) +endif() + +######################################################################## +# For GCC and Clang, we can set a build type: +# +# -DCMAKE_BUILD_TYPE=ASAN +# +# This type creates an address sanitized build (-fsanitize=address) +# and defaults to the DebugParanoid linker flags. +# NOTE: This is not defined on Windows systems. +######################################################################## +if(NOT WIN32) + set(CMAKE_CXX_FLAGS_ASAN "-Wall -Wextra -g -O2 -fsanitize=address -fno-omit-frame-pointer" CACHE STRING + "Flags used by the C++ compiler during Address Sanitized builds." FORCE) + set(CMAKE_C_FLAGS_ASAN "-Wall -Wextra -g -O2 -fsanitize=address -fno-omit-frame-pointer" CACHE STRING + "Flags used by the C compiler during Address Sanitized builds." FORCE) + mark_as_advanced( + CMAKE_CXX_FLAGS_ASAN + CMAKE_C_FLAGS_ASAN + CMAKE_EXE_LINKER_FLAGS_DEBUGPARANOID + CMAKE_SHARED_LINKER_DEBUGPARANOID) +endif() + diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkGnsssdrConfig.cmake.in b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkGnsssdrConfig.cmake.in index 4838f13c0..af9e75169 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkGnsssdrConfig.cmake.in +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkGnsssdrConfig.cmake.in @@ -15,33 +15,33 @@ # You should have received a copy of the GNU General Public License # along with GNSS-SDR. If not, see . -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_VOLK_GNSSSDR volk_gnsssdr) +include(FindPkgConfig) +pkg_check_modules(PC_VOLK_GNSSSDR volk_gnsssdr) -FIND_PATH( +find_path( VOLK_GNSSSDR_INCLUDE_DIRS NAMES volk_gnsssdr/volk_gnsssdr.h HINTS $ENV{VOLK_DIR}/include ${PC_VOLK_INCLUDEDIR} PATHS /usr/local/include - /usr/include - /opt/local/include - "@CMAKE_INSTALL_PREFIX@/include" + /usr/include + /opt/local/include + "@CMAKE_INSTALL_PREFIX@/include" ) -FIND_LIBRARY( +find_library( VOLK_GNSSSDR_LIBRARIES NAMES volk_gnsssdr HINTS $ENV{VOLK_DIR}/lib ${PC_VOLK_LIBDIR} PATHS /usr/local/lib - /usr/local/lib64 - /usr/lib - /usr/lib64 - /opt/local/lib - "@CMAKE_INSTALL_PREFIX@/lib" + /usr/local/lib64 + /usr/lib + /usr/lib64 + /opt/local/lib + "@CMAKE_INSTALL_PREFIX@/lib" ) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(VOLK_GNSSSDR DEFAULT_MSG VOLK_GNSSSDR_LIBRARIES VOLK_GNSSSDR_INCLUDE_DIRS) -MARK_AS_ADVANCED(VOLK_GNSSSDR_LIBRARIES VOLK_GNSSSDR_INCLUDE_DIRS) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(VOLKGNSSSDR DEFAULT_MSG VOLK_GNSSSDR_LIBRARIES VOLK_GNSSSDR_INCLUDE_DIRS) +mark_as_advanced(VOLK_GNSSSDR_LIBRARIES VOLK_GNSSSDR_INCLUDE_DIRS) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkGnsssdrConfigVersion.cmake.in b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkGnsssdrConfigVersion.cmake.in index d7694fdb9..7808c7dbe 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkGnsssdrConfigVersion.cmake.in +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkGnsssdrConfigVersion.cmake.in @@ -27,6 +27,6 @@ if(${PACKAGE_FIND_VERSION_MAJOR} EQUAL ${MAJOR_VERSION}) if(NOT ${PACKAGE_FIND_VERSION_PATCH} GREATER ${MAINT_VERSION}) set(PACKAGE_VERSION_EXACT 1) # exact match for API version set(PACKAGE_VERSION_COMPATIBLE 1) # compat for minor/patch version - endif(NOT ${PACKAGE_FIND_VERSION_PATCH} GREATER ${MAINT_VERSION}) - endif(${PACKAGE_FIND_VERSION_MINOR} EQUAL ${MINOR_VERSION}) -endif(${PACKAGE_FIND_VERSION_MAJOR} EQUAL ${MAJOR_VERSION}) + endif() + endif() +endif() diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkPython.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkPython.cmake index 085a32030..06c51883c 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkPython.cmake +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkPython.cmake @@ -25,42 +25,39 @@ set(__INCLUDED_VOLK_PYTHON_CMAKE TRUE) # This allows the user to specify a specific interpreter, # or finds the interpreter via the built-in cmake module. ######################################################################## -#this allows the user to override PYTHON_EXECUTABLE -if(PYTHON_EXECUTABLE) +set(VOLK_PYTHON_MIN_VERSION "2.7") +set(VOLK_PYTHON3_MIN_VERSION "3.4") - set(PYTHONINTERP_FOUND TRUE) - -#otherwise if not set, try to automatically find it -else(PYTHON_EXECUTABLE) - - #use the built-in find script - set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6) - find_package(PythonInterp 2) - - #and if that fails use the find program routine - if(NOT PYTHONINTERP_FOUND) - find_program(PYTHON_EXECUTABLE NAMES python python2 python2.7 python3) - if(PYTHON_EXECUTABLE) - set(PYTHONINTERP_FOUND TRUE) - endif(PYTHON_EXECUTABLE) - endif(NOT PYTHONINTERP_FOUND) - -endif(PYTHON_EXECUTABLE) - -#make the path to the executable appear in the cmake gui -set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter") - -#make sure we can use -B with python (introduced in 2.6) -if(PYTHON_EXECUTABLE) - execute_process( - COMMAND ${PYTHON_EXECUTABLE} -B -c "" - OUTPUT_QUIET ERROR_QUIET - RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT - ) - if(PYTHON_HAS_DASH_B_RESULT EQUAL 0) - set(PYTHON_DASH_B "-B") +if(CMAKE_VERSION VERSION_LESS 3.12) + if(PYTHON_EXECUTABLE) + message(STATUS "User set python executable ${PYTHON_EXECUTABLE}") + find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION} REQUIRED) + else() + message(STATUS "PYTHON_EXECUTABLE not set - using default python2") + message(STATUS "Use -DPYTHON_EXECUTABLE=/path/to/python3 to build for python3.") + find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION}) + if(NOT PYTHONINTERP_FOUND) + message(STATUS "python2 not found - using python3") + find_package(PythonInterp ${VOLK_PYTHON3_MIN_VERSION} REQUIRED) + endif() endif() -endif(PYTHON_EXECUTABLE) + find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT) +else() + if(PYTHON_EXECUTABLE) + message(STATUS "User set python executable ${PYTHON_EXECUTABLE}") + find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION} REQUIRED) + else() + find_package(Python COMPONENTS Interpreter) + set(PYTHON_VERSION_MAJOR ${Python_VERSION_MAJOR}) + set(PYTHON_EXECUTABLE ${Python_EXECUTABLE}) + endif() +endif() + +if(${PYTHON_VERSION_MAJOR} VERSION_EQUAL 3) + set(PYTHON3 TRUE) +endif() + + ######################################################################## # Check for the existence of a python module: @@ -69,37 +66,45 @@ endif(PYTHON_EXECUTABLE) # - cmd an additional command to run # - have the result variable to set ######################################################################## -macro(VOLK_PYTHON_CHECK_MODULE desc mod cmd have) - message(STATUS "") - message(STATUS "Python checking for ${desc}") +macro(VOLK_PYTHON_CHECK_MODULE_RAW desc python_code have) execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c " -######################################### -try: import ${mod} -except: - try: ${mod} - except: exit(-1) -try: assert ${cmd} -except: exit(-1) -#########################################" - RESULT_VARIABLE ${have} + COMMAND ${PYTHON_EXECUTABLE} -c "${python_code}" + OUTPUT_QUIET ERROR_QUIET + RESULT_VARIABLE return_code ) - if(${have} EQUAL 0) + if(return_code EQUAL 0) message(STATUS "Python checking for ${desc} - found") set(${have} TRUE) - else(${have} EQUAL 0) + else() message(STATUS "Python checking for ${desc} - not found") set(${have} FALSE) - endif(${have} EQUAL 0) -endmacro(VOLK_PYTHON_CHECK_MODULE) + endif() +endmacro() + +macro(VOLK_PYTHON_CHECK_MODULE desc mod cmd have) + VOLK_PYTHON_CHECK_MODULE_RAW( + "${desc}" " +######################################### +try: + import ${mod} + assert ${cmd} +except (ImportError, AssertionError): exit(-1) +except: pass +#########################################" + "${have}") +endmacro() ######################################################################## # Sets the python installation directory VOLK_PYTHON_DIR ######################################################################## if(NOT DEFINED VOLK_PYTHON_DIR) execute_process(COMMAND ${PYTHON_EXECUTABLE} -c " -from distutils import sysconfig -print(sysconfig.get_python_lib(plat_specific=True, prefix='')) +import os +import sys +if os.name == 'posix': + print(os.path.join('lib', 'python' + sys.version[:3], 'dist-packages')) +if os.name == 'nt': + print(os.path.join('Lib', 'site-packages')) " OUTPUT_VARIABLE VOLK_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE ) endif() @@ -116,14 +121,14 @@ unique = hashlib.md5(b'${reldir}${ARGN}').hexdigest()[:5] print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))" OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE) add_custom_target(${_target} ALL DEPENDS ${ARGN}) -endfunction(VOLK_UNIQUE_TARGET) +endfunction() ######################################################################## # Install python sources (also builds and installs byte-compiled python) ######################################################################## function(VOLK_PYTHON_INSTALL) include(CMakeParseArgumentsCopy) - CMAKE_PARSE_ARGUMENTS(VOLK_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN}) + cmake_parse_arguments(VOLK_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN}) #################################################################### if(VOLK_PYTHON_INSTALL_FILES) @@ -157,7 +162,7 @@ function(VOLK_PYTHON_INSTALL) get_filename_component(pygen_path ${pygenfile} PATH) file(MAKE_DIRECTORY ${pygen_path}) - endforeach(pyfile) + endforeach() #the command to generate the pyc files add_custom_command( @@ -184,8 +189,8 @@ function(VOLK_PYTHON_INSTALL) #################################################################### file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native) - if (CMAKE_CROSSCOMPILING) - set(pyexe_native "/usr/bin/env python") + if(CMAKE_CROSSCOMPILING) + set(pyexe_native "/usr/bin/env python") endif() foreach(pyfile ${VOLK_PYTHON_INSTALL_PROGRAMS}) @@ -200,7 +205,7 @@ function(VOLK_PYTHON_INSTALL) add_custom_command( OUTPUT ${pyexefile} DEPENDS ${pyfile} COMMAND ${PYTHON_EXECUTABLE} -c - "open('${pyexefile}','w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())" + "open('${pyexefile}','w').write(r'\#!${pyexe_native}'+'\\n'+open('${pyfile}').read())" COMMENT "Shebangin ${pyfile_name}" VERBATIM ) @@ -215,13 +220,13 @@ function(VOLK_PYTHON_INSTALL) DESTINATION ${VOLK_PYTHON_INSTALL_DESTINATION} COMPONENT ${VOLK_PYTHON_INSTALL_COMPONENT} ) - endforeach(pyfile) + endforeach() endif() - VOLK_UNIQUE_TARGET("pygen" ${python_install_gen_targets}) + volk_unique_target("pygen" ${python_install_gen_targets}) -endfunction(VOLK_PYTHON_INSTALL) +endfunction() ######################################################################## # Write the python helper script that generates byte code files diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/cmake_uninstall.cmake.in b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/cmake_uninstall.cmake.in index a6191a104..d026a667a 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/cmake_uninstall.cmake.in +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/cmake_uninstall.cmake.in @@ -25,10 +25,10 @@ string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - exec_program( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + execute_process( + COMMAND @CMAKE_COMMAND@ -E remove \"$ENV{DESTDIR}${file}\" OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval + RESULT_VARIABLE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml index a8bee46a2..1f741ac02 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml @@ -238,4 +238,48 @@ 32 + + + + 7 + 0 + 1 + 16 + + + + 2 + 0x00000001 + 27 + + + + -mavx512f + -mavx512f + /arch:AVX512F + 64 + + + + + + 7 + 0 + 1 + 28 + + + + 2 + 0x00000001 + 27 + + + + -mavx512cd + -mavx512cd + /arch:AVX512CD + 64 + + diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/machines.xml b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/machines.xml index e7c6eaf20..d787a6b14 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/machines.xml +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/machines.xml @@ -51,4 +51,14 @@ generic 32|64| mmx| sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount avx fma avx2 orc| + + +generic 32|64| mmx| sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount avx fma avx2 avx512f orc| + + + + +generic 32|64| mmx| sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount avx fma avx2 avx512f avx512cd orc| + + diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_arch_defs.py b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_arch_defs.py index 1a1248ad2..f639ae767 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_arch_defs.py +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_arch_defs.py @@ -25,7 +25,7 @@ import six archs = list() arch_dict = dict() -class arch_class: +class arch_class(object): def __init__(self, flags, checks, **kwargs): for key, cast, failval in ( ('name', str, None), diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_kernel_defs.py b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_kernel_defs.py index 9daddda73..fb1ae58f9 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_kernel_defs.py +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_kernel_defs.py @@ -118,10 +118,10 @@ def flatten_section_text(sections): ######################################################################## # Extract kernel info from section, represent as an implementation ######################################################################## -class impl_class: +class impl_class(object): def __init__(self, kern_name, header, body): #extract LV_HAVE_* - self.deps = set(map(str.lower, re.findall('LV_HAVE_(\w+)', header))) + self.deps = set(res.lower() for res in re.findall('LV_HAVE_(\w+)', header)) #extract function suffix and args body = flatten_section_text(body) try: @@ -153,18 +153,18 @@ def extract_lv_haves(code): haves = list() for line in code.splitlines(): if not line.strip().startswith('#'): continue - have_set = set(map(str.lower, re.findall('LV_HAVE_(\w+)', line))) + have_set = set(res.lower() for res in re.findall('LV_HAVE_(\w+)', line)) if have_set: haves.append(have_set) return haves ######################################################################## # Represent a processing kernel, parse from file ######################################################################## -class kernel_class: +class kernel_class(object): def __init__(self, kernel_file): self.name = os.path.splitext(os.path.basename(kernel_file))[0] self.pname = self.name.replace('volk_gnsssdr_', 'p_') - code = open(kernel_file, 'r').read() + code = open(kernel_file, 'rb').read().decode("utf-8") code = comment_remover(code) sections = split_into_nested_ifdef_sections(code) self._impls = list() diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_machine_defs.py b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_machine_defs.py index 26e77ec5e..8eb7e5472 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_machine_defs.py +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/volk_gnsssdr_machine_defs.py @@ -26,7 +26,7 @@ from volk_gnsssdr_arch_defs import arch_dict machines = list() machine_dict = dict() -class machine_class: +class machine_class(object): def __init__(self, name, archs): self.name = name self.archs = list() @@ -36,7 +36,7 @@ class machine_class: arch = arch_dict[arch_name] self.archs.append(arch) self.arch_names.append(arch_name) - self.alignment = max(map(lambda a: a.alignment, self.archs)) + self.alignment = max([a.alignment for a in self.archs]) def __repr__(self): return self.name diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16i_resamplerxnpuppet_16i.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16i_resamplerxnpuppet_16i.h index 9fb835bd6..440ed4ace 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16i_resamplerxnpuppet_16i.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16i_resamplerxnpuppet_16i.h @@ -47,7 +47,7 @@ static inline void volk_gnsssdr_16i_resamplerxnpuppet_16i_generic(int16_t* resul int code_length_chips = 2046; float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; - unsigned int n; + int n; float rem_code_phase_chips = -0.234; float shifts_chips[3] = {-0.1, 0.0, 0.1}; int16_t** result_aux = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -77,7 +77,7 @@ static inline void volk_gnsssdr_16i_resamplerxnpuppet_16i_a_sse3(int16_t* result float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; int16_t** result_aux = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -106,7 +106,7 @@ static inline void volk_gnsssdr_16i_resamplerxnpuppet_16i_u_sse3(int16_t* result float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; int16_t** result_aux = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -136,7 +136,7 @@ static inline void volk_gnsssdr_16i_resamplerxnpuppet_16i_u_sse4_1(int16_t* resu float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; int16_t** result_aux = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -166,7 +166,7 @@ static inline void volk_gnsssdr_16i_resamplerxnpuppet_16i_a_sse4_1(int16_t* resu float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; int16_t** result_aux = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -196,7 +196,7 @@ static inline void volk_gnsssdr_16i_resamplerxnpuppet_16i_u_avx(int16_t* result, float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; int16_t** result_aux = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -226,7 +226,7 @@ static inline void volk_gnsssdr_16i_resamplerxnpuppet_16i_a_avx(int16_t* result, float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; int16_t** result_aux = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -256,7 +256,7 @@ static inline void volk_gnsssdr_16i_resamplerxnpuppet_16i_neon(int16_t* result, float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; int16_t** result_aux = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16i_xn_resampler_16i_xn.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16i_xn_resampler_16i_xn.h index 6413265b2..5324bf725 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16i_xn_resampler_16i_xn.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16i_xn_resampler_16i_xn.h @@ -77,7 +77,7 @@ static inline void volk_gnsssdr_16i_xn_resampler_16i_xn_generic(int16_t** result { int local_code_chip_index; int current_correlator_tap; - int n; + unsigned int n; for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) { for (n = 0; n < num_points; n++) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic.h index ddefa24dc..6d6c88702 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic.h @@ -50,7 +50,7 @@ static inline void volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic_generic(lv phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; int16_t** in_a = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -80,7 +80,7 @@ static inline void volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic_generic_re phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; int16_t** in_a = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -110,7 +110,7 @@ static inline void volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic_a_sse3(lv_ phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; int16_t** in_a = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -141,7 +141,7 @@ static inline void volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic_a_sse3(lv_ //phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); //lv_32fc_t phase_inc[1]; //phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); -//unsigned int n; +//int n; //int num_a_vectors = 3; //int16_t** in_a = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); //for(n = 0; n < num_a_vectors; n++) @@ -172,7 +172,7 @@ static inline void volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic_u_sse3(lv_ phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; int16_t** in_a = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -203,7 +203,7 @@ static inline void volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic_a_avx2(lv_ phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; int16_t** in_a = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -234,7 +234,7 @@ static inline void volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic_a_avx2(lv_ //phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); //lv_32fc_t phase_inc[1]; //phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); -//unsigned int n; +//int n; //int num_a_vectors = 3; //int16_t** in_a = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); //for(n = 0; n < num_a_vectors; n++) @@ -265,7 +265,7 @@ static inline void volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic_u_avx2(lv_ phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; int16_t** in_a = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -296,7 +296,7 @@ static inline void volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic_u_avx2(lv_ //phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); //lv_32fc_t phase_inc[1]; //phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); -//unsigned int n; +//int n; //int num_a_vectors = 3; //int16_t** in_a = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); //for(n = 0; n < num_a_vectors; n++) @@ -327,7 +327,7 @@ static inline void volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic_u_avx2(lv_ //phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); //lv_32fc_t phase_inc[1]; //phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); -//unsigned int n; +//int n; //int num_a_vectors = 3; //int16_t** in_a = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); //for(n = 0; n < num_a_vectors; n++) @@ -358,7 +358,7 @@ static inline void volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic_u_avx2(lv_ //phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); //lv_32fc_t phase_inc[1]; //phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); -//unsigned int n; +//int n; //int num_a_vectors = 3; //int16_t** in_a = (int16_t**)volk_gnsssdr_malloc(sizeof(int16_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); //for(n = 0; n < num_a_vectors; n++) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_convert_32fc.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_convert_32fc.h index 5e2bf1c0a..57d76874c 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_convert_32fc.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_convert_32fc.h @@ -179,6 +179,73 @@ static inline void volk_gnsssdr_16ic_convert_32fc_a_axv(lv_32fc_t* outputVector, } #endif /* LV_HAVE_AVX */ +#ifdef LV_HAVE_AVX2 +#include + +static inline void volk_gnsssdr_16ic_convert_32fc_a_avx2(lv_32fc_t* outputVector, const lv_16sc_t* inputVector, unsigned int num_points) +{ + const unsigned int avx_iters = num_points / 8; + unsigned int number = 0; + const int16_t* complexVectorPtr = (int16_t*)inputVector; + float* outputVectorPtr = (float*)outputVector; + __m256 outVal; + __m256i outValInt; + __m128i cplxValue; + + for (number = 0; number < avx_iters; number++) + { + cplxValue = _mm_load_si128((__m128i*)complexVectorPtr); + complexVectorPtr += 8; + + outValInt = _mm256_cvtepi16_epi32(cplxValue); + outVal = _mm256_cvtepi32_ps(outValInt); + _mm256_store_ps((float*)outputVectorPtr, outVal); + + outputVectorPtr += 8; + } + + number = avx_iters * 8; + for (; number < num_points * 2; number++) + { + *outputVectorPtr++ = (float)*complexVectorPtr++; + } +} + +#endif /* LV_HAVE_AVX2 */ + +#ifdef LV_HAVE_AVX2 +#include + +static inline void volk_gnsssdr_16ic_convert_32fc_u_avx2(lv_32fc_t* outputVector, const lv_16sc_t* inputVector, unsigned int num_points) +{ + const unsigned int avx_iters = num_points / 8; + unsigned int number = 0; + const int16_t* complexVectorPtr = (int16_t*)inputVector; + float* outputVectorPtr = (float*)outputVector; + __m256 outVal; + __m256i outValInt; + __m128i cplxValue; + + for (number = 0; number < avx_iters; number++) + { + cplxValue = _mm_loadu_si128((__m128i*)complexVectorPtr); + complexVectorPtr += 8; + + outValInt = _mm256_cvtepi16_epi32(cplxValue); + outVal = _mm256_cvtepi32_ps(outValInt); + _mm256_storeu_ps((float*)outputVectorPtr, outVal); + + outputVectorPtr += 8; + } + + number = avx_iters * 8; + for (; number < num_points * 2; number++) + { + *outputVectorPtr++ = (float)*complexVectorPtr++; + } +} + +#endif /* LV_HAVE_AVX2 */ #ifdef LV_HAVE_NEONV7 #include diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_resamplerfastxnpuppet_16ic.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_resamplerfastxnpuppet_16ic.h index 8355d1f67..5ecd8c641 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_resamplerfastxnpuppet_16ic.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_resamplerfastxnpuppet_16ic.h @@ -47,7 +47,7 @@ static inline void volk_gnsssdr_16ic_resamplerfastxnpuppet_16ic_generic(lv_16sc_ float code_phase_step_chips = 0.1; int code_length_chips = 2046; int num_out_vectors = 3; - unsigned int n; + int n; float* rem_code_phase_chips = (float*)volk_gnsssdr_malloc(sizeof(float) * num_out_vectors, volk_gnsssdr_get_alignment()); lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -76,7 +76,7 @@ static inline void volk_gnsssdr_16ic_resamplerfastxnpuppet_16ic_a_sse2(lv_16sc_t float code_phase_step_chips = 0.1; int code_length_chips = 2046; int num_out_vectors = 3; - unsigned int n; + int n; float* rem_code_phase_chips = (float*)volk_gnsssdr_malloc(sizeof(float) * num_out_vectors, volk_gnsssdr_get_alignment()); lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -105,7 +105,7 @@ static inline void volk_gnsssdr_16ic_resamplerfastxnpuppet_16ic_u_sse2(lv_16sc_t float code_phase_step_chips = 0.1; int code_length_chips = 2046; int num_out_vectors = 3; - unsigned int n; + int n; float* rem_code_phase_chips = (float*)volk_gnsssdr_malloc(sizeof(float) * num_out_vectors, volk_gnsssdr_get_alignment()); lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -134,7 +134,7 @@ static inline void volk_gnsssdr_16ic_resamplerfastxnpuppet_16ic_neon(lv_16sc_t* float code_phase_step_chips = 0.1; int code_length_chips = 2046; int num_out_vectors = 3; - unsigned int n; + int n; float* rem_code_phase_chips = (float*)volk_gnsssdr_malloc(sizeof(float) * num_out_vectors, volk_gnsssdr_get_alignment()); lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_resamplerxnpuppet_16ic.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_resamplerxnpuppet_16ic.h index 3bc7aa0bc..b0885924a 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_resamplerxnpuppet_16ic.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_resamplerxnpuppet_16ic.h @@ -47,7 +47,7 @@ static inline void volk_gnsssdr_16ic_resamplerxnpuppet_16ic_generic(lv_16sc_t* r int code_length_chips = 2046; float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; - unsigned int n; + int n; float rem_code_phase_chips = -0.234; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -78,7 +78,7 @@ static inline void volk_gnsssdr_16ic_resamplerxnpuppet_16ic_a_sse3(lv_16sc_t* re float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -107,7 +107,7 @@ static inline void volk_gnsssdr_16ic_resamplerxnpuppet_16ic_u_sse3(lv_16sc_t* re float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -137,7 +137,7 @@ static inline void volk_gnsssdr_16ic_resamplerxnpuppet_16ic_u_sse4_1(lv_16sc_t* float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -167,7 +167,7 @@ static inline void volk_gnsssdr_16ic_resamplerxnpuppet_16ic_a_sse4_1(lv_16sc_t* float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -197,7 +197,7 @@ static inline void volk_gnsssdr_16ic_resamplerxnpuppet_16ic_u_avx(lv_16sc_t* res float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -227,7 +227,7 @@ static inline void volk_gnsssdr_16ic_resamplerxnpuppet_16ic_a_avx(lv_16sc_t* res float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -257,7 +257,7 @@ static inline void volk_gnsssdr_16ic_resamplerxnpuppet_16ic_neon(lv_16sc_t* resu float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_16sc_t** result_aux = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic.h index eeec91a59..abec05bb0 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic.h @@ -46,7 +46,7 @@ static inline void volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic_generic(lv_16sc_t* { int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); - unsigned int n; + int n; for (n = 0; n < num_a_vectors; n++) { in_a[n] = (lv_16sc_t*)volk_gnsssdr_malloc(sizeof(lv_16sc_t) * num_points, volk_gnsssdr_get_alignment()); @@ -70,7 +70,7 @@ static inline void volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic_generic_sat(lv_16sc { int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); - unsigned int n; + int n; for (n = 0; n < num_a_vectors; n++) { in_a[n] = (lv_16sc_t*)volk_gnsssdr_malloc(sizeof(lv_16sc_t) * num_points, volk_gnsssdr_get_alignment()); @@ -94,7 +94,7 @@ static inline void volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic_a_sse2(lv_16sc_t* r { int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); - unsigned int n; + int n; for (n = 0; n < num_a_vectors; n++) { in_a[n] = (lv_16sc_t*)volk_gnsssdr_malloc(sizeof(lv_16sc_t) * num_points, volk_gnsssdr_get_alignment()); @@ -119,7 +119,7 @@ static inline void volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic_u_sse2(lv_16sc_t* r { int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); - unsigned int n; + int n; for (n = 0; n < num_a_vectors; n++) { in_a[n] = (lv_16sc_t*)volk_gnsssdr_malloc(sizeof(lv_16sc_t) * num_points, volk_gnsssdr_get_alignment()); @@ -144,7 +144,7 @@ static inline void volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic_a_avx2(lv_16sc_t* r { int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); - unsigned int n; + int n; for (n = 0; n < num_a_vectors; n++) { in_a[n] = (lv_16sc_t*)volk_gnsssdr_malloc(sizeof(lv_16sc_t) * num_points, volk_gnsssdr_get_alignment()); @@ -169,7 +169,7 @@ static inline void volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic_u_avx2(lv_16sc_t* r { int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); - unsigned int n; + int n; for (n = 0; n < num_a_vectors; n++) { in_a[n] = (lv_16sc_t*)volk_gnsssdr_malloc(sizeof(lv_16sc_t) * num_points, volk_gnsssdr_get_alignment()); @@ -194,7 +194,7 @@ static inline void volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic_neon(lv_16sc_t* res { int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); - unsigned int n; + int n; for (n = 0; n < num_a_vectors; n++) { in_a[n] = (lv_16sc_t*)volk_gnsssdr_malloc(sizeof(lv_16sc_t) * num_points, volk_gnsssdr_get_alignment()); @@ -219,7 +219,7 @@ static inline void volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic_neon_vma(lv_16sc_t* { int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); - unsigned int n; + int n; for (n = 0; n < num_a_vectors; n++) { in_a[n] = (lv_16sc_t*)volk_gnsssdr_malloc(sizeof(lv_16sc_t) * num_points, volk_gnsssdr_get_alignment()); @@ -243,7 +243,7 @@ static inline void volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic_neon_optvma(lv_16sc { int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); - unsigned int n; + int n; for (n = 0; n < num_a_vectors; n++) { in_a[n] = (lv_16sc_t*)volk_gnsssdr_malloc(sizeof(lv_16sc_t) * num_points, volk_gnsssdr_get_alignment()); diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic.h index 610d7a884..9339b00be 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic.h @@ -50,7 +50,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic_generic(lv_ phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -80,7 +80,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic_generic_rel phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -110,7 +110,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic_a_sse3(lv_1 phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -141,7 +141,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic_a_sse3_relo phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -172,7 +172,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic_u_sse3(lv_1 phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -203,7 +203,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic_a_avx2(lv_1 phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -234,7 +234,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic_a_avx2_relo phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -265,7 +265,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic_u_avx2(lv_1 phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -296,7 +296,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic_u_avx2_relo phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -327,7 +327,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic_neon(lv_16s phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -358,7 +358,7 @@ static inline void volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic_neon_vma(lv phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_16sc_t** in_a = (lv_16sc_t**)volk_gnsssdr_malloc(sizeof(lv_16sc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_xn_resampler_16ic_xn.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_xn_resampler_16ic_xn.h index 8e60443b0..430f27962 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_xn_resampler_16ic_xn.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_xn_resampler_16ic_xn.h @@ -75,8 +75,8 @@ static inline void volk_gnsssdr_16ic_xn_resampler_16ic_xn_generic(lv_16sc_t** re { int local_code_chip_index; int current_correlator_tap; - int n; - for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) + unsigned int n; + for (current_correlator_tap = 0U; current_correlator_tap < num_out_vectors; current_correlator_tap++) { for (n = 0; n < num_points; n++) { diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_xn_resampler_fast_16ic_xn.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_xn_resampler_fast_16ic_xn.h index 36c5089b6..2830f691d 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_xn_resampler_fast_16ic_xn.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16ic_xn_resampler_fast_16ic_xn.h @@ -83,7 +83,7 @@ static inline void volk_gnsssdr_16ic_xn_resampler_fast_16ic_xn_generic(lv_16sc_t // resample code for current tap local_code_chip_index = round(code_phase_step_chips * (float)(n) + rem_code_phase_chips[current_vector] - 0.5f); if (local_code_chip_index < 0.0) local_code_chip_index += code_length_chips; - if (local_code_chip_index > (code_length_chips - 1)) local_code_chip_index -= code_length_chips; + if (local_code_chip_index > ((int)code_length_chips - 1)) local_code_chip_index -= code_length_chips; result[current_vector][n] = local_code[local_code_chip_index]; } } @@ -180,7 +180,7 @@ static inline void volk_gnsssdr_16ic_xn_resampler_fast_16ic_xn_a_sse2(lv_16sc_t* { local_code_chip_index[0] = (int)(code_phase_step_chips * (float)(number) + rem_code_phase_chips[current_vector]); if (local_code_chip_index[0] < 0.0) local_code_chip_index[0] += code_length_chips - 1; - if (local_code_chip_index[0] > (code_length_chips - 1)) local_code_chip_index[0] -= code_length_chips; + if (local_code_chip_index[0] > ((int)code_length_chips - 1)) local_code_chip_index[0] -= code_length_chips; _result[current_vector][number] = local_code[local_code_chip_index[0]]; } } @@ -276,7 +276,7 @@ static inline void volk_gnsssdr_16ic_xn_resampler_fast_16ic_xn_u_sse2(lv_16sc_t* { local_code_chip_index[0] = (int)(code_phase_step_chips * (float)(number) + rem_code_phase_chips[current_vector]); if (local_code_chip_index[0] < 0.0) local_code_chip_index[0] += code_length_chips - 1; - if (local_code_chip_index[0] > (code_length_chips - 1)) local_code_chip_index[0] -= code_length_chips; + if (local_code_chip_index[0] > ((int)code_length_chips - 1)) local_code_chip_index[0] -= code_length_chips; _result[current_vector][number] = local_code[local_code_chip_index[0]]; } } @@ -378,7 +378,7 @@ static inline void volk_gnsssdr_16ic_xn_resampler_fast_16ic_xn_neon(lv_16sc_t** { local_code_chip_index[0] = (int)(code_phase_step_chips * (float)(number) + rem_code_phase_chips[current_vector]); if (local_code_chip_index[0] < 0.0) local_code_chip_index[0] += code_length_chips - 1; - if (local_code_chip_index[0] > (code_length_chips - 1)) local_code_chip_index[0] -= code_length_chips; + if (local_code_chip_index[0] > ((int)code_length_chips - 1)) local_code_chip_index[0] -= code_length_chips; _result[current_vector][number] = local_code[local_code_chip_index[0]]; } } diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f.h new file mode 100644 index 000000000..c6705adca --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f.h @@ -0,0 +1,288 @@ +/*! + * \file volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f.h + * \brief VOLK_GNSSSDR puppet for the multiple 32-bit float vector high dynamics resampler kernel. + * \authors
        + *
      • Cillian O'Driscoll 2017 cillian.odriscoll at gmail dot com + *
      • Javier Arribas, 2018. javiarribas(at)gmail.com + *
      + * + * VOLK_GNSSSDR puppet for integrating the multiple resampler into the test system + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef INCLUDED_volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_H +#define INCLUDED_volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_H + +#include "volk_gnsssdr/volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn.h" +#include +#include +#include +#include + + +#ifdef LV_HAVE_GENERIC +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_generic(float* result, const float* local_code, unsigned int num_points) +{ + int code_length_chips = 2046; + float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); + int num_out_vectors = 3; + float rem_code_phase_chips = -0.8234; + float code_phase_rate_step_chips = 1.0 / powf(2.0, 33.0); + int n; + float shifts_chips[3] = {-0.1, 0.0, 0.1}; + + float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); + for (n = 0; n < num_out_vectors; n++) + { + result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); + } + + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_generic(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + + memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); + + for (n = 0; n < num_out_vectors; n++) + { + volk_gnsssdr_free(result_aux[n]); + } + volk_gnsssdr_free(result_aux); +} + +#endif /* LV_HAVE_GENERIC */ + + +#ifdef LV_HAVE_SSE3 +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_a_sse3(float* result, const float* local_code, unsigned int num_points) +{ + int code_length_chips = 2046; + float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); + int num_out_vectors = 3; + float rem_code_phase_chips = -0.8234; + float code_phase_rate_step_chips = 1.0 / powf(2.0, 33.0); + int n; + float shifts_chips[3] = {-0.1, 0.0, 0.1}; + + float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); + for (n = 0; n < num_out_vectors; n++) + { + result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); + } + + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_sse3(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + + memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); + + for (n = 0; n < num_out_vectors; n++) + { + volk_gnsssdr_free(result_aux[n]); + } + volk_gnsssdr_free(result_aux); +} + +#endif + + +#ifdef LV_HAVE_SSE3 +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_u_sse3(float* result, const float* local_code, unsigned int num_points) +{ + int code_length_chips = 2046; + float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); + int num_out_vectors = 3; + float rem_code_phase_chips = -0.8234; + float code_phase_rate_step_chips = 1.0 / powf(2.0, 33.0); + int n; + float shifts_chips[3] = {-0.1, 0.0, 0.1}; + + float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); + for (n = 0; n < num_out_vectors; n++) + { + result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); + } + + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_sse3(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + + memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); + + for (n = 0; n < num_out_vectors; n++) + { + volk_gnsssdr_free(result_aux[n]); + } + volk_gnsssdr_free(result_aux); +} + +#endif + + +#ifdef LV_HAVE_SSE4_1 +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_u_sse4_1(float* result, const float* local_code, unsigned int num_points) +{ + int code_length_chips = 2046; + float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); + int num_out_vectors = 3; + float rem_code_phase_chips = -0.8234; + float code_phase_rate_step_chips = 1.0 / powf(2.0, 33.0); + int n; + float shifts_chips[3] = {-0.1, 0.0, 0.1}; + + float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); + for (n = 0; n < num_out_vectors; n++) + { + result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); + } + + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_sse4_1(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + + memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); + + for (n = 0; n < num_out_vectors; n++) + { + volk_gnsssdr_free(result_aux[n]); + } + volk_gnsssdr_free(result_aux); +} + +#endif + + +#ifdef LV_HAVE_SSE4_1 +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_a_sse4_1(float* result, const float* local_code, unsigned int num_points) +{ + int code_length_chips = 2046; + float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); + int num_out_vectors = 3; + float rem_code_phase_chips = -0.8234; + float code_phase_rate_step_chips = 1.0 / powf(2.0, 33.0); + int n; + float shifts_chips[3] = {-0.1, 0.0, 0.1}; + + float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); + for (n = 0; n < num_out_vectors; n++) + { + result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); + } + + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_sse4_1(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + + memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); + + for (n = 0; n < num_out_vectors; n++) + { + volk_gnsssdr_free(result_aux[n]); + } + volk_gnsssdr_free(result_aux); +} + +#endif + + +#ifdef LV_HAVE_AVX +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_a_avx(float* result, const float* local_code, unsigned int num_points) +{ + int code_length_chips = 2046; + float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); + int num_out_vectors = 3; + float rem_code_phase_chips = -0.8234; + float code_phase_rate_step_chips = 1.0 / powf(2.0, 33.0); + int n; + float shifts_chips[3] = {-0.1, 0.0, 0.1}; + + float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); + for (n = 0; n < num_out_vectors; n++) + { + result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); + } + + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_avx(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + + memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); + + for (n = 0; n < num_out_vectors; n++) + { + volk_gnsssdr_free(result_aux[n]); + } + volk_gnsssdr_free(result_aux); +} +#endif + + +#ifdef LV_HAVE_AVX +static inline void volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f_u_avx(float* result, const float* local_code, unsigned int num_points) +{ + int code_length_chips = 2046; + float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); + int num_out_vectors = 3; + float rem_code_phase_chips = -0.8234; + float code_phase_rate_step_chips = 1.0 / powf(2.0, 33.0); + int n; + float shifts_chips[3] = {-0.1, 0.0, 0.1}; + + float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); + for (n = 0; n < num_out_vectors; n++) + { + result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); + } + + volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_avx(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); + + memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); + + for (n = 0; n < num_out_vectors; n++) + { + volk_gnsssdr_free(result_aux[n]); + } + volk_gnsssdr_free(result_aux); +} +#endif +// +//#ifdef LV_HAVE_NEONV7 +//static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_neon(float* result, const float* local_code, unsigned int num_points) +//{ +// int code_length_chips = 2046; +// float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); +// int num_out_vectors = 3; +// float rem_code_phase_chips = -0.234; +// int n; +// float shifts_chips[3] = {-0.1, 0.0, 0.1}; +// +// float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); +// for (n = 0; n < num_out_vectors; n++) +// { +// result_aux[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); +// } +// +// volk_gnsssdr_32f_xn_resampler_32f_xn_neon(result_aux, local_code, rem_code_phase_chips, code_phase_step_chips, shifts_chips, code_length_chips, num_out_vectors, num_points); +// +// memcpy((float*)result, (float*)result_aux[0], sizeof(float) * num_points); +// +// for (n = 0; n < num_out_vectors; n++) +// { +// volk_gnsssdr_free(result_aux[n]); +// } +// volk_gnsssdr_free(result_aux); +//} +//#endif + +#endif // INCLUDED_volk_gnsssdr_32f_high_dynamics_resamplerpuppet_32f_H diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_resamplerxnpuppet_32f.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_resamplerxnpuppet_32f.h index 1ee4f64cb..106dfecdc 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_resamplerxnpuppet_32f.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_resamplerxnpuppet_32f.h @@ -49,7 +49,7 @@ static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_generic(float* result, float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -79,7 +79,7 @@ static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_a_sse3(float* result, float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -108,7 +108,7 @@ static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_u_sse3(float* result, float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -138,7 +138,7 @@ static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_u_sse4_1(float* result float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -167,7 +167,7 @@ static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_a_sse4_1(float* result float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -196,7 +196,7 @@ static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_a_avx(float* result, c float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -225,7 +225,7 @@ static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_u_avx(float* result, c float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -253,7 +253,7 @@ static inline void volk_gnsssdr_32f_resamplerxnpuppet_32f_neon(float* result, co float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; float** result_aux = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_out_vectors, volk_gnsssdr_get_alignment()); diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn.h new file mode 100644 index 000000000..8b666908b --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn.h @@ -0,0 +1,707 @@ +/*! + * \file volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn.h + * \brief VOLK_GNSSSDR kernel: Resamples 1 complex 32-bit float vectors using zero hold resample algorithm + * and produces the delayed replicas by copying and rotating the resulting resampled signal. + * \authors
        + *
      • Cillian O'Driscoll, 2017. cillian.odirscoll(at)gmail.com + *
      • Javier Arribas, 2018. javiarribas(at)gmail.com + *
      + * + * VOLK_GNSSSDR kernel that resamples N 32-bit float vectors using zero hold resample algorithm. + * It is optimized to resample a single GNSS local code signal replica into 1 vector fractional-resampled and fractional-delayed + * and produces the delayed replicas by copying and rotating the resulting resampled signal. + * (i.e. it creates the Early, Prompt, and Late code replicas) + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +/*! + * \page volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn + * + * \b Overview + * + * Resamples a 32-bit floating point vector , providing \p num_out_vectors outputs. + * + * Dispatcher Prototype + * \code + * void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) + * \endcode + * + * \b Inputs + * \li local_code: Vector to be resampled. + * \li rem_code_phase_chips: Remnant code phase [chips]. + * \li code_phase_step_chips: Phase increment per sample [chips/sample]. + * \li code_phase_rate_step_chips: Phase rate increment per sample [chips/sample^2]. + * \li shifts_chips: Vector of floats that defines the spacing (in chips) between the replicas of \p local_code + * \li code_length_chips: Code length in chips. + * \li num_out_vectors Number of output vectors. + * \li num_points: The number of data values to be in the resampled vector. + * + * \b Outputs + * \li result: Pointer to a vector of pointers where the results will be stored. + * + */ + +#ifndef INCLUDED_volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_H +#define INCLUDED_volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_H + +#include +#include +#include /* abs */ +#include /* int64_t */ +#include +#include +#include + + +#ifdef LV_HAVE_GENERIC + +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_generic(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +{ + int local_code_chip_index; + int current_correlator_tap; + unsigned int n; + //first correlator + for (n = 0; n < num_points; n++) + { + // resample code for first tap + local_code_chip_index = (int)floor(code_phase_step_chips * (float)n + code_phase_rate_step_chips * (float)(n * n) + shifts_chips[0] - rem_code_phase_chips); + // Take into account that in multitap correlators, the shifts can be negative! + if (local_code_chip_index < 0) local_code_chip_index += (int)code_length_chips * (abs(local_code_chip_index) / code_length_chips + 1); + local_code_chip_index = local_code_chip_index % code_length_chips; + result[0][n] = local_code[local_code_chip_index]; + } + + //adjacent correlators + unsigned int shift_samples = 0; + for (current_correlator_tap = 1; current_correlator_tap < num_out_vectors; current_correlator_tap++) + { + shift_samples += (int)round((shifts_chips[current_correlator_tap] - shifts_chips[current_correlator_tap - 1]) / code_phase_step_chips); + memcpy(&result[current_correlator_tap][0], &result[0][shift_samples], (num_points - shift_samples) * sizeof(float)); + memcpy(&result[current_correlator_tap][num_points - shift_samples], &result[0][0], shift_samples * sizeof(float)); + } +} + +#endif /*LV_HAVE_GENERIC*/ + + +#ifdef LV_HAVE_SSE3 +#include +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_sse3(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +{ + float** _result = result; + const unsigned int quarterPoints = num_points / 4; + // int current_correlator_tap; + unsigned int n; + unsigned int k; + int current_correlator_tap; + const __m128 ones = _mm_set1_ps(1.0f); + const __m128 fours = _mm_set1_ps(4.0f); + const __m128 rem_code_phase_chips_reg = _mm_set_ps1(rem_code_phase_chips); + const __m128 code_phase_step_chips_reg = _mm_set_ps1(code_phase_step_chips); + const __m128 code_phase_rate_step_chips_reg = _mm_set_ps1(code_phase_rate_step_chips); + + __VOLK_ATTR_ALIGNED(16) + int local_code_chip_index[4]; + int local_code_chip_index_; + const __m128i zeros = _mm_setzero_si128(); + const __m128 code_length_chips_reg_f = _mm_set_ps1((float)code_length_chips); + const __m128i code_length_chips_reg_i = _mm_set1_epi32((int)code_length_chips); + __m128i local_code_chip_index_reg, aux_i, negatives, i; + __m128 aux, aux2, aux3, indexnn, shifts_chips_reg, fi, igx, j, c, cTrunc, base; + __m128 indexn = _mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f); + + shifts_chips_reg = _mm_set_ps1((float)shifts_chips[0]); + aux2 = _mm_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); + + for (n = 0; n < quarterPoints; n++) + { + aux = _mm_mul_ps(code_phase_step_chips_reg, indexn); + indexnn = _mm_mul_ps(indexn, indexn); + aux3 = _mm_mul_ps(code_phase_rate_step_chips_reg, indexnn); + aux = _mm_add_ps(aux, aux3); + aux = _mm_add_ps(aux, aux2); + // floor + i = _mm_cvttps_epi32(aux); + fi = _mm_cvtepi32_ps(i); + igx = _mm_cmpgt_ps(fi, aux); + j = _mm_and_ps(igx, ones); + aux = _mm_sub_ps(fi, j); + + // Correct negative shift + c = _mm_div_ps(aux, code_length_chips_reg_f); + aux3 = _mm_add_ps(c, ones); + i = _mm_cvttps_epi32(aux3); + cTrunc = _mm_cvtepi32_ps(i); + base = _mm_mul_ps(cTrunc, code_length_chips_reg_f); + local_code_chip_index_reg = _mm_cvtps_epi32(_mm_sub_ps(aux, base)); + negatives = _mm_cmplt_epi32(local_code_chip_index_reg, zeros); + aux_i = _mm_and_si128(code_length_chips_reg_i, negatives); + local_code_chip_index_reg = _mm_add_epi32(local_code_chip_index_reg, aux_i); + + _mm_store_si128((__m128i*)local_code_chip_index, local_code_chip_index_reg); + + for (k = 0; k < 4; ++k) + { + _result[0][n * 4 + k] = local_code[local_code_chip_index[k]]; + } + indexn = _mm_add_ps(indexn, fours); + } + + for (n = quarterPoints * 4; n < num_points; n++) + { + // resample code for first tap + local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + code_phase_rate_step_chips * (float)(n * n) + shifts_chips[0] - rem_code_phase_chips); + // Take into account that in multitap correlators, the shifts can be negative! + if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); + local_code_chip_index_ = local_code_chip_index_ % code_length_chips; + _result[0][n] = local_code[local_code_chip_index_]; + } + + // adjacent correlators + unsigned int shift_samples = 0; + for (current_correlator_tap = 1; current_correlator_tap < num_out_vectors; current_correlator_tap++) + { + shift_samples += (int)round((shifts_chips[current_correlator_tap] - shifts_chips[current_correlator_tap - 1]) / code_phase_step_chips); + memcpy(&_result[current_correlator_tap][0], &_result[0][shift_samples], (num_points - shift_samples) * sizeof(float)); + memcpy(&_result[current_correlator_tap][num_points - shift_samples], &_result[0][0], shift_samples * sizeof(float)); + } +} +#endif + + +#ifdef LV_HAVE_SSE3 +#include +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_sse3(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +{ + float** _result = result; + const unsigned int quarterPoints = num_points / 4; + // int current_correlator_tap; + unsigned int n; + unsigned int k; + int current_correlator_tap; + const __m128 ones = _mm_set1_ps(1.0f); + const __m128 fours = _mm_set1_ps(4.0f); + const __m128 rem_code_phase_chips_reg = _mm_set_ps1(rem_code_phase_chips); + const __m128 code_phase_step_chips_reg = _mm_set_ps1(code_phase_step_chips); + const __m128 code_phase_rate_step_chips_reg = _mm_set_ps1(code_phase_rate_step_chips); + + __VOLK_ATTR_ALIGNED(16) + int local_code_chip_index[4]; + int local_code_chip_index_; + const __m128i zeros = _mm_setzero_si128(); + const __m128 code_length_chips_reg_f = _mm_set_ps1((float)code_length_chips); + const __m128i code_length_chips_reg_i = _mm_set1_epi32((int)code_length_chips); + __m128i local_code_chip_index_reg, aux_i, negatives, i; + __m128 aux, aux2, aux3, indexnn, shifts_chips_reg, fi, igx, j, c, cTrunc, base; + __m128 indexn = _mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f); + + shifts_chips_reg = _mm_set_ps1((float)shifts_chips[0]); + aux2 = _mm_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); + + for (n = 0; n < quarterPoints; n++) + { + aux = _mm_mul_ps(code_phase_step_chips_reg, indexn); + indexnn = _mm_mul_ps(indexn, indexn); + aux3 = _mm_mul_ps(code_phase_rate_step_chips_reg, indexnn); + aux = _mm_add_ps(aux, aux3); + aux = _mm_add_ps(aux, aux2); + // floor + i = _mm_cvttps_epi32(aux); + fi = _mm_cvtepi32_ps(i); + igx = _mm_cmpgt_ps(fi, aux); + j = _mm_and_ps(igx, ones); + aux = _mm_sub_ps(fi, j); + + // Correct negative shift + c = _mm_div_ps(aux, code_length_chips_reg_f); + aux3 = _mm_add_ps(c, ones); + i = _mm_cvttps_epi32(aux3); + cTrunc = _mm_cvtepi32_ps(i); + base = _mm_mul_ps(cTrunc, code_length_chips_reg_f); + local_code_chip_index_reg = _mm_cvtps_epi32(_mm_sub_ps(aux, base)); + negatives = _mm_cmplt_epi32(local_code_chip_index_reg, zeros); + aux_i = _mm_and_si128(code_length_chips_reg_i, negatives); + local_code_chip_index_reg = _mm_add_epi32(local_code_chip_index_reg, aux_i); + + _mm_store_si128((__m128i*)local_code_chip_index, local_code_chip_index_reg); + + for (k = 0; k < 4; ++k) + { + _result[0][n * 4 + k] = local_code[local_code_chip_index[k]]; + } + indexn = _mm_add_ps(indexn, fours); + } + + for (n = quarterPoints * 4; n < num_points; n++) + { + // resample code for first tap + local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + code_phase_rate_step_chips * (float)(n * n) + shifts_chips[0] - rem_code_phase_chips); + // Take into account that in multitap correlators, the shifts can be negative! + if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); + local_code_chip_index_ = local_code_chip_index_ % code_length_chips; + _result[0][n] = local_code[local_code_chip_index_]; + } + + // adjacent correlators + unsigned int shift_samples = 0; + for (current_correlator_tap = 1; current_correlator_tap < num_out_vectors; current_correlator_tap++) + { + shift_samples += (int)round((shifts_chips[current_correlator_tap] - shifts_chips[current_correlator_tap - 1]) / code_phase_step_chips); + memcpy(&_result[current_correlator_tap][0], &_result[0][shift_samples], (num_points - shift_samples) * sizeof(float)); + memcpy(&_result[current_correlator_tap][num_points - shift_samples], &_result[0][0], shift_samples * sizeof(float)); + } +} + +#endif + + +#ifdef LV_HAVE_SSE4_1 +#include +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_sse4_1(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +{ + float** _result = result; + const unsigned int quarterPoints = num_points / 4; + // int current_correlator_tap; + unsigned int n; + unsigned int k; + int current_correlator_tap; + const __m128 ones = _mm_set1_ps(1.0f); + const __m128 fours = _mm_set1_ps(4.0f); + const __m128 rem_code_phase_chips_reg = _mm_set_ps1(rem_code_phase_chips); + const __m128 code_phase_step_chips_reg = _mm_set_ps1(code_phase_step_chips); + const __m128 code_phase_rate_step_chips_reg = _mm_set_ps1(code_phase_rate_step_chips); + + __VOLK_ATTR_ALIGNED(16) + int local_code_chip_index[4]; + int local_code_chip_index_; + const __m128i zeros = _mm_setzero_si128(); + const __m128 code_length_chips_reg_f = _mm_set_ps1((float)code_length_chips); + const __m128i code_length_chips_reg_i = _mm_set1_epi32((int)code_length_chips); + __m128i local_code_chip_index_reg, aux_i, negatives, i; + __m128 aux, aux2, aux3, indexnn, shifts_chips_reg, c, cTrunc, base; + __m128 indexn = _mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f); + + shifts_chips_reg = _mm_set_ps1((float)shifts_chips[0]); + aux2 = _mm_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); + + for (n = 0; n < quarterPoints; n++) + { + aux = _mm_mul_ps(code_phase_step_chips_reg, indexn); + indexnn = _mm_mul_ps(indexn, indexn); + aux3 = _mm_mul_ps(code_phase_rate_step_chips_reg, indexnn); + aux = _mm_add_ps(aux, aux3); + aux = _mm_add_ps(aux, aux2); + // floor + aux = _mm_floor_ps(aux); + + // Correct negative shift + c = _mm_div_ps(aux, code_length_chips_reg_f); + aux3 = _mm_add_ps(c, ones); + i = _mm_cvttps_epi32(aux3); + cTrunc = _mm_cvtepi32_ps(i); + base = _mm_mul_ps(cTrunc, code_length_chips_reg_f); + local_code_chip_index_reg = _mm_cvtps_epi32(_mm_sub_ps(aux, base)); + negatives = _mm_cmplt_epi32(local_code_chip_index_reg, zeros); + aux_i = _mm_and_si128(code_length_chips_reg_i, negatives); + local_code_chip_index_reg = _mm_add_epi32(local_code_chip_index_reg, aux_i); + + _mm_store_si128((__m128i*)local_code_chip_index, local_code_chip_index_reg); + + for (k = 0; k < 4; ++k) + { + _result[0][n * 4 + k] = local_code[local_code_chip_index[k]]; + } + indexn = _mm_add_ps(indexn, fours); + } + + for (n = quarterPoints * 4; n < num_points; n++) + { + // resample code for first tap + local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + code_phase_rate_step_chips * (float)(n * n) + shifts_chips[0] - rem_code_phase_chips); + // Take into account that in multitap correlators, the shifts can be negative! + if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); + local_code_chip_index_ = local_code_chip_index_ % code_length_chips; + _result[0][n] = local_code[local_code_chip_index_]; + } + + // adjacent correlators + unsigned int shift_samples = 0; + for (current_correlator_tap = 1; current_correlator_tap < num_out_vectors; current_correlator_tap++) + { + shift_samples += (int)round((shifts_chips[current_correlator_tap] - shifts_chips[current_correlator_tap - 1]) / code_phase_step_chips); + memcpy(&_result[current_correlator_tap][0], &_result[0][shift_samples], (num_points - shift_samples) * sizeof(float)); + memcpy(&_result[current_correlator_tap][num_points - shift_samples], &_result[0][0], shift_samples * sizeof(float)); + } +} + +#endif + + +#ifdef LV_HAVE_SSE4_1 +#include +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_sse4_1(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +{ + float** _result = result; + const unsigned int quarterPoints = num_points / 4; + // int current_correlator_tap; + unsigned int n; + unsigned int k; + int current_correlator_tap; + const __m128 ones = _mm_set1_ps(1.0f); + const __m128 fours = _mm_set1_ps(4.0f); + const __m128 rem_code_phase_chips_reg = _mm_set_ps1(rem_code_phase_chips); + const __m128 code_phase_step_chips_reg = _mm_set_ps1(code_phase_step_chips); + const __m128 code_phase_rate_step_chips_reg = _mm_set_ps1(code_phase_rate_step_chips); + + __VOLK_ATTR_ALIGNED(16) + int local_code_chip_index[4]; + int local_code_chip_index_; + const __m128i zeros = _mm_setzero_si128(); + const __m128 code_length_chips_reg_f = _mm_set_ps1((float)code_length_chips); + const __m128i code_length_chips_reg_i = _mm_set1_epi32((int)code_length_chips); + __m128i local_code_chip_index_reg, aux_i, negatives, i; + __m128 aux, aux2, aux3, indexnn, shifts_chips_reg, c, cTrunc, base; + __m128 indexn = _mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f); + + shifts_chips_reg = _mm_set_ps1((float)shifts_chips[0]); + aux2 = _mm_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); + + for (n = 0; n < quarterPoints; n++) + { + aux = _mm_mul_ps(code_phase_step_chips_reg, indexn); + indexnn = _mm_mul_ps(indexn, indexn); + aux3 = _mm_mul_ps(code_phase_rate_step_chips_reg, indexnn); + aux = _mm_add_ps(aux, aux3); + aux = _mm_add_ps(aux, aux2); + // floor + aux = _mm_floor_ps(aux); + + // Correct negative shift + c = _mm_div_ps(aux, code_length_chips_reg_f); + aux3 = _mm_add_ps(c, ones); + i = _mm_cvttps_epi32(aux3); + cTrunc = _mm_cvtepi32_ps(i); + base = _mm_mul_ps(cTrunc, code_length_chips_reg_f); + local_code_chip_index_reg = _mm_cvtps_epi32(_mm_sub_ps(aux, base)); + negatives = _mm_cmplt_epi32(local_code_chip_index_reg, zeros); + aux_i = _mm_and_si128(code_length_chips_reg_i, negatives); + local_code_chip_index_reg = _mm_add_epi32(local_code_chip_index_reg, aux_i); + + _mm_store_si128((__m128i*)local_code_chip_index, local_code_chip_index_reg); + + for (k = 0; k < 4; ++k) + { + _result[0][n * 4 + k] = local_code[local_code_chip_index[k]]; + } + indexn = _mm_add_ps(indexn, fours); + } + + for (n = quarterPoints * 4; n < num_points; n++) + { + // resample code for first tap + local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + code_phase_rate_step_chips * (float)(n * n) + shifts_chips[0] - rem_code_phase_chips); + // Take into account that in multitap correlators, the shifts can be negative! + if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); + local_code_chip_index_ = local_code_chip_index_ % code_length_chips; + _result[0][n] = local_code[local_code_chip_index_]; + } + + // adjacent correlators + unsigned int shift_samples = 0; + for (current_correlator_tap = 1; current_correlator_tap < num_out_vectors; current_correlator_tap++) + { + shift_samples += (int)round((shifts_chips[current_correlator_tap] - shifts_chips[current_correlator_tap - 1]) / code_phase_step_chips); + memcpy(&_result[current_correlator_tap][0], &_result[0][shift_samples], (num_points - shift_samples) * sizeof(float)); + memcpy(&_result[current_correlator_tap][num_points - shift_samples], &_result[0][0], shift_samples * sizeof(float)); + } +} + +#endif + + +#ifdef LV_HAVE_AVX +#include +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_a_avx(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +{ + float** _result = result; + const unsigned int avx_iters = num_points / 8; + int current_correlator_tap; + unsigned int n; + unsigned int k; + const __m256 eights = _mm256_set1_ps(8.0f); + const __m256 ones = _mm256_set1_ps(1.0f); + const __m256 rem_code_phase_chips_reg = _mm256_set1_ps(rem_code_phase_chips); + const __m256 code_phase_step_chips_reg = _mm256_set1_ps(code_phase_step_chips); + const __m256 code_phase_rate_step_chips_reg = _mm256_set1_ps(code_phase_rate_step_chips); + + __VOLK_ATTR_ALIGNED(32) + int local_code_chip_index[8]; + int local_code_chip_index_; + + const __m256 zeros = _mm256_setzero_ps(); + const __m256 code_length_chips_reg_f = _mm256_set1_ps((float)code_length_chips); + const __m256 n0 = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); + + __m256i local_code_chip_index_reg, i; + __m256 aux, aux2, aux3, shifts_chips_reg, c, cTrunc, base, negatives, indexn, indexnn; + + shifts_chips_reg = _mm256_set1_ps((float)shifts_chips[0]); + aux2 = _mm256_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); + indexn = n0; + for (n = 0; n < avx_iters; n++) + { + __VOLK_GNSSSDR_PREFETCH_LOCALITY(&_result[0][8 * n + 7], 1, 0); + __VOLK_GNSSSDR_PREFETCH_LOCALITY(&local_code_chip_index[8], 1, 3); + aux = _mm256_mul_ps(code_phase_step_chips_reg, indexn); + indexnn = _mm256_mul_ps(indexn, indexn); + aux3 = _mm256_mul_ps(code_phase_rate_step_chips_reg, indexnn); + aux = _mm256_add_ps(aux, aux3); + aux = _mm256_add_ps(aux, aux2); + // floor + aux = _mm256_floor_ps(aux); + + // Correct negative shift + c = _mm256_div_ps(aux, code_length_chips_reg_f); + aux3 = _mm256_add_ps(c, ones); + i = _mm256_cvttps_epi32(aux3); + cTrunc = _mm256_cvtepi32_ps(i); + base = _mm256_mul_ps(cTrunc, code_length_chips_reg_f); + local_code_chip_index_reg = _mm256_cvttps_epi32(_mm256_sub_ps(aux, base)); + + c = _mm256_cvtepi32_ps(local_code_chip_index_reg); + negatives = _mm256_cmp_ps(c, zeros, 0x01); + aux3 = _mm256_and_ps(code_length_chips_reg_f, negatives); + aux = _mm256_add_ps(c, aux3); + local_code_chip_index_reg = _mm256_cvttps_epi32(aux); + + _mm256_store_si256((__m256i*)local_code_chip_index, local_code_chip_index_reg); + for (k = 0; k < 8; ++k) + { + _result[0][n * 8 + k] = local_code[local_code_chip_index[k]]; + } + indexn = _mm256_add_ps(indexn, eights); + } + + _mm256_zeroupper(); + + for (n = avx_iters * 8; n < num_points; n++) + { + // resample code for first tap + local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + code_phase_rate_step_chips * (float)(n * n) + shifts_chips[0] - rem_code_phase_chips); + // Take into account that in multitap correlators, the shifts can be negative! + if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); + local_code_chip_index_ = local_code_chip_index_ % code_length_chips; + _result[0][n] = local_code[local_code_chip_index_]; + } + + // adjacent correlators + unsigned int shift_samples = 0; + for (current_correlator_tap = 1; current_correlator_tap < num_out_vectors; current_correlator_tap++) + { + shift_samples += (int)round((shifts_chips[current_correlator_tap] - shifts_chips[current_correlator_tap - 1]) / code_phase_step_chips); + memcpy(&_result[current_correlator_tap][0], &_result[0][shift_samples], (num_points - shift_samples) * sizeof(float)); + memcpy(&_result[current_correlator_tap][num_points - shift_samples], &_result[0][0], shift_samples * sizeof(float)); + } +} + +#endif + + +#ifdef LV_HAVE_AVX +#include +static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_u_avx(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +{ + float** _result = result; + const unsigned int avx_iters = num_points / 8; + int current_correlator_tap; + unsigned int n; + unsigned int k; + const __m256 eights = _mm256_set1_ps(8.0f); + const __m256 ones = _mm256_set1_ps(1.0f); + const __m256 rem_code_phase_chips_reg = _mm256_set1_ps(rem_code_phase_chips); + const __m256 code_phase_step_chips_reg = _mm256_set1_ps(code_phase_step_chips); + const __m256 code_phase_rate_step_chips_reg = _mm256_set1_ps(code_phase_rate_step_chips); + + __VOLK_ATTR_ALIGNED(32) + int local_code_chip_index[8]; + int local_code_chip_index_; + + const __m256 zeros = _mm256_setzero_ps(); + const __m256 code_length_chips_reg_f = _mm256_set1_ps((float)code_length_chips); + const __m256 n0 = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); + + __m256i local_code_chip_index_reg, i; + __m256 aux, aux2, aux3, shifts_chips_reg, c, cTrunc, base, negatives, indexn, indexnn; + + shifts_chips_reg = _mm256_set1_ps((float)shifts_chips[0]); + aux2 = _mm256_sub_ps(shifts_chips_reg, rem_code_phase_chips_reg); + indexn = n0; + for (n = 0; n < avx_iters; n++) + { + __VOLK_GNSSSDR_PREFETCH_LOCALITY(&_result[0][8 * n + 7], 1, 0); + __VOLK_GNSSSDR_PREFETCH_LOCALITY(&local_code_chip_index[8], 1, 3); + aux = _mm256_mul_ps(code_phase_step_chips_reg, indexn); + indexnn = _mm256_mul_ps(indexn, indexn); + aux3 = _mm256_mul_ps(code_phase_rate_step_chips_reg, indexnn); + aux = _mm256_add_ps(aux, aux3); + aux = _mm256_add_ps(aux, aux2); + // floor + aux = _mm256_floor_ps(aux); + + // Correct negative shift + c = _mm256_div_ps(aux, code_length_chips_reg_f); + aux3 = _mm256_add_ps(c, ones); + i = _mm256_cvttps_epi32(aux3); + cTrunc = _mm256_cvtepi32_ps(i); + base = _mm256_mul_ps(cTrunc, code_length_chips_reg_f); + local_code_chip_index_reg = _mm256_cvttps_epi32(_mm256_sub_ps(aux, base)); + + c = _mm256_cvtepi32_ps(local_code_chip_index_reg); + negatives = _mm256_cmp_ps(c, zeros, 0x01); + aux3 = _mm256_and_ps(code_length_chips_reg_f, negatives); + aux = _mm256_add_ps(c, aux3); + local_code_chip_index_reg = _mm256_cvttps_epi32(aux); + + _mm256_store_si256((__m256i*)local_code_chip_index, local_code_chip_index_reg); + for (k = 0; k < 8; ++k) + { + _result[0][n * 8 + k] = local_code[local_code_chip_index[k]]; + } + indexn = _mm256_add_ps(indexn, eights); + } + + _mm256_zeroupper(); + + for (n = avx_iters * 8; n < num_points; n++) + { + // resample code for first tap + local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + code_phase_rate_step_chips * (float)(n * n) + shifts_chips[0] - rem_code_phase_chips); + // Take into account that in multitap correlators, the shifts can be negative! + if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); + local_code_chip_index_ = local_code_chip_index_ % code_length_chips; + _result[0][n] = local_code[local_code_chip_index_]; + } + + // adjacent correlators + unsigned int shift_samples = 0; + for (current_correlator_tap = 1; current_correlator_tap < num_out_vectors; current_correlator_tap++) + { + shift_samples += (int)round((shifts_chips[current_correlator_tap] - shifts_chips[current_correlator_tap - 1]) / code_phase_step_chips); + memcpy(&_result[current_correlator_tap][0], &_result[0][shift_samples], (num_points - shift_samples) * sizeof(float)); + memcpy(&_result[current_correlator_tap][num_points - shift_samples], &_result[0][0], shift_samples * sizeof(float)); + } +} + +#endif +// +// +//#ifdef LV_HAVE_NEONV7 +//#include +// +//static inline void volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_neon(float** result, const float* local_code, float rem_code_phase_chips, float code_phase_step_chips, float* shifts_chips, unsigned int code_length_chips, int num_out_vectors, unsigned int num_points) +//{ +// float** _result = result; +// const unsigned int neon_iters = num_points / 4; +// int current_correlator_tap; +// unsigned int n; +// unsigned int k; +// const int32x4_t ones = vdupq_n_s32(1); +// const float32x4_t fours = vdupq_n_f32(4.0f); +// const float32x4_t rem_code_phase_chips_reg = vdupq_n_f32(rem_code_phase_chips); +// const float32x4_t code_phase_step_chips_reg = vdupq_n_f32(code_phase_step_chips); +// +// __VOLK_ATTR_ALIGNED(16) +// int32_t local_code_chip_index[4]; +// int32_t local_code_chip_index_; +// +// const int32x4_t zeros = vdupq_n_s32(0); +// const float32x4_t code_length_chips_reg_f = vdupq_n_f32((float)code_length_chips); +// const int32x4_t code_length_chips_reg_i = vdupq_n_s32((int32_t)code_length_chips); +// int32x4_t local_code_chip_index_reg, aux_i, negatives, i; +// float32x4_t aux, aux2, shifts_chips_reg, fi, c, j, cTrunc, base, indexn, reciprocal; +// __VOLK_ATTR_ALIGNED(16) +// const float vec[4] = {0.0f, 1.0f, 2.0f, 3.0f}; +// uint32x4_t igx; +// reciprocal = vrecpeq_f32(code_length_chips_reg_f); +// reciprocal = vmulq_f32(vrecpsq_f32(code_length_chips_reg_f, reciprocal), reciprocal); +// reciprocal = vmulq_f32(vrecpsq_f32(code_length_chips_reg_f, reciprocal), reciprocal); // this refinement is required! +// float32x4_t n0 = vld1q_f32((float*)vec); +// +// for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) +// { +// shifts_chips_reg = vdupq_n_f32((float)shifts_chips[current_correlator_tap]); +// aux2 = vsubq_f32(shifts_chips_reg, rem_code_phase_chips_reg); +// indexn = n0; +// for (n = 0; n < neon_iters; n++) +// { +// __VOLK_GNSSSDR_PREFETCH_LOCALITY(&_result[current_correlator_tap][4 * n + 3], 1, 0); +// __VOLK_GNSSSDR_PREFETCH(&local_code_chip_index[4]); +// aux = vmulq_f32(code_phase_step_chips_reg, indexn); +// aux = vaddq_f32(aux, aux2); +// +// //floor +// i = vcvtq_s32_f32(aux); +// fi = vcvtq_f32_s32(i); +// igx = vcgtq_f32(fi, aux); +// j = vcvtq_f32_s32(vandq_s32(vreinterpretq_s32_u32(igx), ones)); +// aux = vsubq_f32(fi, j); +// +// // fmod +// c = vmulq_f32(aux, reciprocal); +// i = vcvtq_s32_f32(c); +// cTrunc = vcvtq_f32_s32(i); +// base = vmulq_f32(cTrunc, code_length_chips_reg_f); +// aux = vsubq_f32(aux, base); +// local_code_chip_index_reg = vcvtq_s32_f32(aux); +// +// negatives = vreinterpretq_s32_u32(vcltq_s32(local_code_chip_index_reg, zeros)); +// aux_i = vandq_s32(code_length_chips_reg_i, negatives); +// local_code_chip_index_reg = vaddq_s32(local_code_chip_index_reg, aux_i); +// +// vst1q_s32((int32_t*)local_code_chip_index, local_code_chip_index_reg); +// +// for (k = 0; k < 4; ++k) +// { +// _result[current_correlator_tap][n * 4 + k] = local_code[local_code_chip_index[k]]; +// } +// indexn = vaddq_f32(indexn, fours); +// } +// for (n = neon_iters * 4; n < num_points; n++) +// { +// __VOLK_GNSSSDR_PREFETCH_LOCALITY(&_result[current_correlator_tap][n], 1, 0); +// // resample code for current tap +// local_code_chip_index_ = (int)floor(code_phase_step_chips * (float)n + shifts_chips[current_correlator_tap] - rem_code_phase_chips); +// //Take into account that in multitap correlators, the shifts can be negative! +// if (local_code_chip_index_ < 0) local_code_chip_index_ += (int)code_length_chips * (abs(local_code_chip_index_) / code_length_chips + 1); +// local_code_chip_index_ = local_code_chip_index_ % code_length_chips; +// _result[current_correlator_tap][n] = local_code[local_code_chip_index_]; +// } +// } +//} +// +//#endif + +#endif /*INCLUDED_volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn_H*/ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_resampler_32f_xn.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_resampler_32f_xn.h index e28fd610d..e841feeb2 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_resampler_32f_xn.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_xn_resampler_32f_xn.h @@ -78,7 +78,7 @@ static inline void volk_gnsssdr_32f_xn_resampler_32f_xn_generic(float** result, { int local_code_chip_index; int current_correlator_tap; - int n; + unsigned int n; for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) { for (n = 0; n < num_points; n++) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn.h new file mode 100644 index 000000000..e20d229e3 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn.h @@ -0,0 +1,122 @@ +/*! + * \file volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn.h + * \brief VOLK_GNSSSDR kernel: multiplies N complex (32-bit float per component) vectors + * by a common vector, phase rotated and accumulates the results in N float complex outputs. + * \authors
        + *
      • Antonio Ramos 2018. antonio.ramosdet(at)gmail.com + *
      + * + * VOLK_GNSSSDR kernel that multiplies N 32 bits complex vectors by a common vector, which is + * phase-rotated by phase offset and phase increment, and accumulates the results + * in N 32 bits float complex outputs. + * It is optimized to perform the N tap correlation process in GNSS receivers. + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +/*! + * \page volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn + * + * \b Overview + * + * Rotates and multiplies the reference complex vector with an arbitrary number of other real vectors, + * accumulates the results and stores them in the output vector. + * The rotation is done at a fixed rate per sample, from an initial \p phase offset. + * This function can be used for Doppler wipe-off and multiple correlator. + * + * Dispatcher Prototype + * \code + * void volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, const lv_32fc_t phase_inc_rate, lv_32fc_t* phase, const float** in_a, int num_a_vectors, unsigned int num_points); + * \endcode + * + * \b Inputs + * \li in_common: Pointer to one of the vectors to be rotated, multiplied and accumulated (reference vector). + * \li phase_inc: Phase increment = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)) + * \li phase_inc_rate: Phase increment rate = lv_cmake(cos(phase_step_rate_rad), sin(phase_step_rate_rad)) + * \li phase: Initial phase = lv_cmake(cos(initial_phase_rad), sin(initial_phase_rad)) + * \li in_a: Pointer to an array of pointers to multiple vectors to be multiplied and accumulated. + * \li num_a_vectors: Number of vectors to be multiplied by the reference vector and accumulated. + * \li num_points: Number of complex values to be multiplied together, accumulated and stored into \p result. + * + * \b Outputs + * \li phase: Final phase. + * \li result: Vector of \p num_a_vectors components with the multiple vectors of \p in_a rotated, multiplied by \p in_common and accumulated. + * + */ + +#ifndef INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn_H +#define INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn_H + + +#include +#include +#include +#include +#include + +#ifdef LV_HAVE_GENERIC + +static inline void volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn_generic(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, const lv_32fc_t phase_inc_rate, lv_32fc_t* phase, const float** in_a, int num_a_vectors, unsigned int num_points) +{ + lv_32fc_t tmp32_1; +#ifdef __cplusplus + lv_32fc_t half_phase_inc_rate = std::sqrt(phase_inc_rate); +#else + lv_32fc_t half_phase_inc_rate = csqrtf(phase_inc_rate); +#endif + lv_32fc_t constant_rotation = phase_inc * half_phase_inc_rate; + lv_32fc_t delta_phase_rate = lv_cmake(1.0f, 0.0f); + int n_vec; + unsigned int n; + for (n_vec = 0; n_vec < num_a_vectors; n_vec++) + { + result[n_vec] = lv_cmake(0.0f, 0.0f); + } + for (n = 0; n < num_points; n++) + { + tmp32_1 = *in_common++ * (*phase); + // Regenerate phase + if (n % 256 == 0) + { +#ifdef __cplusplus + (*phase) /= std::abs((*phase)); + delta_phase_rate /= std::abs(delta_phase_rate); +#else + (*phase) /= hypotf(lv_creal(*phase), lv_cimag(*phase)); + delta_phase_rate /= hypotf(lv_creal(delta_phase_rate), lv_cimag(delta_phase_rate)); +#endif + } + (*phase) *= (constant_rotation * delta_phase_rate); + delta_phase_rate *= phase_inc_rate; + for (n_vec = 0; n_vec < num_a_vectors; n_vec++) + { + result[n_vec] += (tmp32_1 * in_a[n_vec][n]); + } + } +} + +#endif /*LV_HAVE_GENERIC*/ + +#endif /* INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn_H */ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc.h new file mode 100644 index 000000000..b2bc1b740 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc.h @@ -0,0 +1,163 @@ +/*! + * \file volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc.h + * \brief Volk puppet for the multiple 16-bit complex dot product kernel. + * \authors
        + *
      • Carles Fernandez Prades 2016 cfernandez at cttc dot cat + *
      + * + * Volk puppet for integrating the resampler into volk's test system + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc_H +#define INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc_H + +#include "volk_gnsssdr/volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn.h" +#include +#include +#include + +#ifdef LV_HAVE_GENERIC + +static inline void volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc_generic(lv_32fc_t* result, const lv_32fc_t* local_code, const float* in, unsigned int num_points) +{ + // phases must be normalized. Phase rotator expects a complex exponential input! + float rem_carrier_phase_in_rad = 0.25; + float phase_step_rad = 0.1; + lv_32fc_t phase[1]; + phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); + lv_32fc_t phase_inc[1]; + phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); + lv_32fc_t phase_inc_rate[1]; + phase_inc_rate[0] = lv_cmake(cos(phase_step_rad * 0.001), sin(phase_step_rad * 0.001)); + int n; + int num_a_vectors = 3; + float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment()); + for (n = 0; n < num_a_vectors; n++) + { + in_a[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); + memcpy((float*)in_a[n], (float*)in, sizeof(float) * num_points); + } + volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn_generic(result, local_code, phase_inc[0], phase_inc_rate[0], phase, (const float**)in_a, num_a_vectors, num_points); + + for (n = 0; n < num_a_vectors; n++) + { + volk_gnsssdr_free(in_a[n]); + } + volk_gnsssdr_free(in_a); +} +#endif // Generic + +// +//#ifdef LV_HAVE_GENERIC +//static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_generic_reload(lv_32fc_t* result, const lv_32fc_t* local_code, const float* in, unsigned int num_points) +//{ +// // phases must be normalized. Phase rotator expects a complex exponential input! +// float rem_carrier_phase_in_rad = 0.25; +// float phase_step_rad = 0.1; +// lv_32fc_t phase[1]; +// phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); +// lv_32fc_t phase_inc[1]; +// phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); +// int n; +// int num_a_vectors = 3; +// float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment()); +// for (n = 0; n < num_a_vectors; n++) +// { +// in_a[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); +// memcpy((float*)in_a[n], (float*)in, sizeof(float) * num_points); +// } +// volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_generic_reload(result, local_code, phase_inc[0], phase, (const float**)in_a, num_a_vectors, num_points); +// +// for (n = 0; n < num_a_vectors; n++) +// { +// volk_gnsssdr_free(in_a[n]); +// } +// volk_gnsssdr_free(in_a); +//} +// +//#endif // Generic +// +//#ifdef LV_HAVE_AVX +//static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_u_avx(lv_32fc_t* result, const lv_32fc_t* local_code, const float* in, unsigned int num_points) +//{ +// // phases must be normalized. Phase rotator expects a complex exponential input! +// float rem_carrier_phase_in_rad = 0.25; +// float phase_step_rad = 0.1; +// lv_32fc_t phase[1]; +// phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); +// lv_32fc_t phase_inc[1]; +// phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); +// int n; +// int num_a_vectors = 3; +// float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment()); +// for (n = 0; n < num_a_vectors; n++) +// { +// in_a[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); +// memcpy((float*)in_a[n], (float*)in, sizeof(float) * num_points); +// } +// volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(result, local_code, phase_inc[0], phase, (const float**)in_a, num_a_vectors, num_points); +// +// for (n = 0; n < num_a_vectors; n++) +// { +// volk_gnsssdr_free(in_a[n]); +// } +// volk_gnsssdr_free(in_a); +//} +// +//#endif // AVX +// +// +//#ifdef LV_HAVE_AVX +//static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_a_avx(lv_32fc_t* result, const lv_32fc_t* local_code, const float* in, unsigned int num_points) +//{ +// // phases must be normalized. Phase rotator expects a complex exponential input! +// float rem_carrier_phase_in_rad = 0.25; +// float phase_step_rad = 0.1; +// lv_32fc_t phase[1]; +// phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); +// lv_32fc_t phase_inc[1]; +// phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); +// int n; +// int num_a_vectors = 3; +// float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment()); +// for (n = 0; n < num_a_vectors; n++) +// { +// in_a[n] = (float*)volk_gnsssdr_malloc(sizeof(float) * num_points, volk_gnsssdr_get_alignment()); +// memcpy((float*)in_a[n], (float*)in, sizeof(float) * num_points); +// } +// volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_a_avx(result, local_code, phase_inc[0], phase, (const float**)in_a, num_a_vectors, num_points); +// +// for (n = 0; n < num_a_vectors; n++) +// { +// volk_gnsssdr_free(in_a[n]); +// } +// volk_gnsssdr_free(in_a); +//} +// +//#endif // AVX + +#endif // INCLUDED_volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc_H diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h index a87bad93e..08cb7a221 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h @@ -170,7 +170,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_generic_reload static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, lv_32fc_t* phase, const float** in_a, int num_a_vectors, unsigned int num_points) { unsigned int number = 0; - unsigned int vec_ind = 0; + int vec_ind = 0; unsigned int i = 0; const unsigned int sixteenthPoints = num_points / 16; @@ -334,7 +334,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_u_avx(lv_32fc_ static inline void volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn_a_avx(lv_32fc_t* result, const lv_32fc_t* in_common, const lv_32fc_t phase_inc, lv_32fc_t* phase, const float** in_a, int num_a_vectors, unsigned int num_points) { unsigned int number = 0; - unsigned int vec_ind = 0; + int vec_ind = 0; unsigned int i = 0; const unsigned int sixteenthPoints = num_points / 16; diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc.h index 69f948d45..9212c9327 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc.h @@ -51,7 +51,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_generic(lv phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -80,7 +80,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_generic_re phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -109,7 +109,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_u_avx(lv_3 phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -139,7 +139,7 @@ static inline void volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc_a_avx(lv_3 phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; float** in_a = (float**)volk_gnsssdr_malloc(sizeof(float*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_resamplerxnpuppet_32fc.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_resamplerxnpuppet_32fc.h index 0757c9776..9c595a226 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_resamplerxnpuppet_32fc.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_resamplerxnpuppet_32fc.h @@ -49,7 +49,7 @@ static inline void volk_gnsssdr_32fc_resamplerxnpuppet_32fc_generic(lv_32fc_t* r float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_32fc_t** result_aux = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -80,7 +80,7 @@ static inline void volk_gnsssdr_32fc_resamplerxnpuppet_32fc_a_sse3(lv_32fc_t* re float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_32fc_t** result_aux = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -109,7 +109,7 @@ static inline void volk_gnsssdr_32fc_resamplerxnpuppet_32fc_u_sse3(lv_32fc_t* re float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_32fc_t** result_aux = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -139,7 +139,7 @@ static inline void volk_gnsssdr_32fc_resamplerxnpuppet_32fc_u_sse4_1(lv_32fc_t* float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_32fc_t** result_aux = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -168,7 +168,7 @@ static inline void volk_gnsssdr_32fc_resamplerxnpuppet_32fc_a_sse4_1(lv_32fc_t* float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_32fc_t** result_aux = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -197,7 +197,7 @@ static inline void volk_gnsssdr_32fc_resamplerxnpuppet_32fc_a_avx(lv_32fc_t* res float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_32fc_t** result_aux = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -226,7 +226,7 @@ static inline void volk_gnsssdr_32fc_resamplerxnpuppet_32fc_u_avx(lv_32fc_t* res float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_32fc_t** result_aux = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -255,7 +255,7 @@ static inline void volk_gnsssdr_32fc_resamplerxnpuppet_32fc_a_avx2(lv_32fc_t* re float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_32fc_t** result_aux = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -284,7 +284,7 @@ static inline void volk_gnsssdr_32fc_resamplerxnpuppet_32fc_u_avx2(lv_32fc_t* re float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_32fc_t** result_aux = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); @@ -313,7 +313,7 @@ static inline void volk_gnsssdr_32fc_resamplerxnpuppet_32fc_neon(lv_32fc_t* resu float code_phase_step_chips = ((float)(code_length_chips) + 0.1) / ((float)num_points); int num_out_vectors = 3; float rem_code_phase_chips = -0.234; - unsigned int n; + int n; float shifts_chips[3] = {-0.1, 0.0, 0.1}; lv_32fc_t** result_aux = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_out_vectors, volk_gnsssdr_get_alignment()); diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc.h index 7eeb01dc7..6786f8821 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc.h @@ -50,7 +50,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc_generic(lv_ phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_32fc_t** in_a = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -80,7 +80,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc_generic_rel phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_32fc_t** in_a = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -110,7 +110,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc_u_sse3(lv_3 phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_32fc_t** in_a = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -140,7 +140,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc_a_sse3(lv_3 phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_32fc_t** in_a = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -170,7 +170,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc_u_avx(lv_32 phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_32fc_t** in_a = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -200,7 +200,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc_a_avx(lv_32 phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_32fc_t** in_a = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) @@ -230,7 +230,7 @@ static inline void volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc_neon(lv_32f phase[0] = lv_cmake(cos(rem_carrier_phase_in_rad), sin(rem_carrier_phase_in_rad)); lv_32fc_t phase_inc[1]; phase_inc[0] = lv_cmake(cos(phase_step_rad), sin(phase_step_rad)); - unsigned int n; + int n; int num_a_vectors = 3; lv_32fc_t** in_a = (lv_32fc_t**)volk_gnsssdr_malloc(sizeof(lv_32fc_t*) * num_a_vectors, volk_gnsssdr_get_alignment()); for (n = 0; n < num_a_vectors; n++) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_xn_resampler_32fc_xn.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_xn_resampler_32fc_xn.h index 98dba44cf..2a8e7ba1b 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_xn_resampler_32fc_xn.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_xn_resampler_32fc_xn.h @@ -75,7 +75,7 @@ static inline void volk_gnsssdr_32fc_xn_resampler_32fc_xn_generic(lv_32fc_t** re { int local_code_chip_index; int current_correlator_tap; - int n; + unsigned int n; for (current_correlator_tap = 0; current_correlator_tap < num_out_vectors; current_correlator_tap++) { for (n = 0; n < num_points; n++) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt index ec4d5ab2c..48c012c09 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt @@ -22,22 +22,22 @@ # header file detection ######################################################################## include(CheckIncludeFile) -CHECK_INCLUDE_FILE(cpuid.h HAVE_CPUID_H) +check_include_file(cpuid.h HAVE_CPUID_H) if(HAVE_CPUID_H) add_definitions(-DHAVE_CPUID_H) endif() -CHECK_INCLUDE_FILE(intrin.h HAVE_INTRIN_H) +check_include_file(intrin.h HAVE_INTRIN_H) if(HAVE_INTRIN_H) add_definitions(-DHAVE_INTRIN_H) endif() -CHECK_INCLUDE_FILE(fenv.h HAVE_FENV_H) +check_include_file(fenv.h HAVE_FENV_H) if(HAVE_FENV_H) add_definitions(-DHAVE_FENV_H) endif() -CHECK_INCLUDE_FILE(dlfcn.h HAVE_DLFCN_H) +check_include_file(dlfcn.h HAVE_DLFCN_H) if(HAVE_DLFCN_H) add_definitions(-DHAVE_DLFCN_H) list(APPEND volk_gnsssdr_libraries ${CMAKE_DL_LIBS}) @@ -62,7 +62,7 @@ endif() ######################################################################## if(COMPILER_NAME MATCHES "GNU") include(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG("-Werror=unused-command-line-argument" HAVE_WERROR_UNUSED_CMD_LINE_ARG) + check_cxx_compiler_flag("-Werror=unused-command-line-argument" HAVE_WERROR_UNUSED_CMD_LINE_ARG) if(HAVE_WERROR_UNUSED_CMD_LINE_ARG) set(VOLK_FLAG_CHECK_FLAGS "-Werror=unused-command-line-argument") endif() @@ -74,20 +74,20 @@ endif() ######################################################################## include(CheckSymbolExists) -CHECK_SYMBOL_EXISTS(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN) - +check_symbol_exists(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN) + if(HAVE_POSIX_MEMALIGN) add_definitions(-DHAVE_POSIX_MEMALIGN) -endif(HAVE_POSIX_MEMALIGN) +endif() if(NOT DEFINED _XOPEN_SOURCE) add_definitions(-D_XOPEN_SOURCE=700) -endif(NOT DEFINED _XOPEN_SOURCE) +endif() ######################################################################## # detect x86 flavor of CPU ######################################################################## -if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "^(i.86|x86|x86_64|amd64|AMD64)$") +if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^(i.86|x86|x86_64|amd64|AMD64)$") message(STATUS "x86* CPU detected") set(CPU_IS_x86 TRUE) endif() @@ -106,7 +106,7 @@ macro(check_arch arch_name) set(flags ${ARGN}) set(have_${arch_name} TRUE) foreach(flag ${flags}) - if (MSVC AND (${flag} STREQUAL "/arch:SSE2" OR ${flag} STREQUAL "/arch:SSE" )) + if(MSVC AND (${flag} STREQUAL "/arch:SSE2" OR ${flag} STREQUAL "/arch:SSE")) # SSE/SSE2 is supported in MSVC since VS 2005 but flag not available when compiling 64-bit so do not check else() include(CheckCXXCompilerFlag) @@ -119,27 +119,27 @@ macro(check_arch arch_name) if(VOLK_FLAG_CHECK_FLAGS) set(CMAKE_REQUIRED_FLAGS ${VOLK_FLAG_CHECK_FLAGS}) endif() - CHECK_CXX_COMPILER_FLAG(${flag} ${have_flag}) + check_cxx_compiler_flag(${flag} ${have_flag}) unset(CMAKE_REQUIRED_FLAGS) - if (NOT ${have_flag}) + if(NOT ${have_flag}) set(have_${arch_name} FALSE) endif() endif() endforeach() - if (have_${arch_name}) + if(have_${arch_name}) list(APPEND available_archs ${arch_name}) endif() -endmacro(check_arch) +endmacro() foreach(line ${arch_flag_lines}) string(REGEX REPLACE "," ";" arch_flags ${line}) check_arch(${arch_flags}) -endforeach(line) +endforeach() macro(OVERRULE_ARCH arch reason) message(STATUS "${reason}, Overruled arch ${arch}") list(REMOVE_ITEM available_archs ${arch}) -endmacro(OVERRULE_ARCH) +endmacro() ######################################################################## # eliminate AVX on if not on x86, or if the compiler does not accept @@ -150,25 +150,25 @@ set(HAVE_XGETBV 0) set(HAVE_AVX_CVTPI32_PS 0) if(CPU_IS_x86) # check to see if the compiler/linker works with xgetb instruction - if (NOT MSVC) + if(NOT MSVC) file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/test_xgetbv.c "unsigned long long _xgetbv(unsigned int index) { unsigned int eax, edx; __asm__ __volatile__(\"xgetbv\" : \"=a\"(eax), \"=d\"(edx) : \"c\"(index)); return ((unsigned long long)edx << 32) | eax; } int main (void) { (void) _xgetbv(0); return (0); }") - else (NOT MSVC) + else() #MSVC defines an intrinsic file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/test_xgetbv.c "#include \n #include \n int main() { int avxSupported = 0; \n#if (_MSC_FULL_VER >= 160040219) \nint cpuInfo[4]; __cpuid(cpuInfo, 1);\nif ((cpuInfo[2] & (1 << 27) || 0) && (cpuInfo[2] & (1 << 28) || 0)) \n{\nunsigned long long xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);\n avxSupported = (xcrFeatureMask & 0x6) == 6;}\n#endif \n return 1- avxSupported; }") - endif(NOT MSVC) + endif() execute_process(COMMAND ${CMAKE_C_COMPILER} -o ${CMAKE_CURRENT_BINARY_DIR}/test_xgetbv ${CMAKE_CURRENT_BINARY_DIR}/test_xgetbv.c OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE avx_compile_result) if(NOT ${avx_compile_result} EQUAL 0) - OVERRULE_ARCH(avx "Compiler or linker missing xgetbv instruction") + overrule_arch(avx "Compiler or linker missing xgetbv instruction") elseif(NOT CROSSCOMPILE_MULTILIB) execute_process(COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_xgetbv OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE avx_exe_result) if(NOT ${avx_exe_result} EQUAL 0) - OVERRULE_ARCH(avx "CPU missing xgetbv") + overrule_arch(avx "CPU missing xgetbv") else() set(HAVE_XGETBV 1) endif() @@ -184,7 +184,7 @@ if(CPU_IS_x86) ######################################################################### # check to see if the compiler/linker works with cvtpi32_ps instrinsic when using AVX - if (CMAKE_SIZEOF_VOID_P EQUAL 4) + if(CMAKE_SIZEOF_VOID_P EQUAL 4) file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/test_cvtpi32_ps.c "#include \nint main (void) {__m128 __a; __m64 __b; __m128 foo = _mm_cvtpi32_ps(__a, __b); return (0); }") execute_process(COMMAND ${CMAKE_C_COMPILER} -mavx -o ${CMAKE_CURRENT_BINARY_DIR}/test_cvtpi32_ps @@ -192,13 +192,13 @@ if(CPU_IS_x86) OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE avx_compile_result) if(NOT ${avx_compile_result} EQUAL 0) - OVERRULE_ARCH(avx "Compiler missing cvtpi32_ps instrinsic") + overrule_arch(avx "Compiler missing cvtpi32_ps instrinsic") elseif(NOT CROSSCOMPILE_MULTILIB) execute_process(COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_cvtpi32_ps OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE avx_exe_result) if(NOT ${avx_exe_result} EQUAL 0) - OVERRULE_ARCH(avx "CPU missing cvtpi32_ps") + overrule_arch(avx "CPU missing cvtpi32_ps") else() set(HAVE_AVX_CVTPI32_PS 1) endif() @@ -207,13 +207,13 @@ if(CPU_IS_x86) endif() file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test_cvtpi32_ps ${CMAKE_CURRENT_BINARY_DIR}/test_cvtpi32_ps.c) - else(CMAKE_SIZEOF_VOID_P EQUAL 4) - # 64-bit compilations won't need this command so don't overrule AVX - set(HAVE_AVX_CVTPI32_PS 0) - endif(CMAKE_SIZEOF_VOID_P EQUAL 4) + else() + # 64-bit compilations won't need this command so don't overrule AVX + set(HAVE_AVX_CVTPI32_PS 0) + endif() # Disable SSE4a if Clang is less than version 3.2 - if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") + if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") # Figure out the version of Clang if(CMAKE_VERSION VERSION_LESS "2.8.10") # Exctract the Clang version from the --version string. @@ -222,14 +222,14 @@ if(CPU_IS_x86) execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE clang_version) string(REGEX MATCH "[0-9].[0-9]" CMAKE_C_COMPILER_VERSION ${clang_version}) - endif(CMAKE_VERSION VERSION_LESS "2.8.10") + endif() if(CMAKE_C_COMPILER_VERSION VERSION_LESS "3.2") - OVERRULE_ARCH(sse4_a "Clang >= 3.2 required for SSE4a") - endif(CMAKE_C_COMPILER_VERSION VERSION_LESS "3.2") - endif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") + overrule_arch(sse4_a "Clang >= 3.2 required for SSE4a") + endif() + endif() -endif(CPU_IS_x86) +endif() if(${HAVE_XGETBV}) add_definitions(-DHAVE_XGETBV) @@ -244,17 +244,17 @@ endif() ######################################################################## if(NOT CPU_IS_x86) - OVERRULE_ARCH(3dnow "Architecture is not x86 or x86_64") - OVERRULE_ARCH(mmx "Architecture is not x86 or x86_64") - OVERRULE_ARCH(sse "Architecture is not x86 or x86_64") - OVERRULE_ARCH(sse2 "Architecture is not x86 or x86_64") - OVERRULE_ARCH(sse3 "Architecture is not x86 or x86_64") - OVERRULE_ARCH(ssse3 "Architecture is not x86 or x86_64") - OVERRULE_ARCH(sse4_a "Architecture is not x86 or x86_64") - OVERRULE_ARCH(sse4_1 "Architecture is not x86 or x86_64") - OVERRULE_ARCH(sse4_2 "Architecture is not x86 or x86_64") - OVERRULE_ARCH(avx "Architecture is not x86 or x86_64") -endif(NOT CPU_IS_x86) + overrule_arch(3dnow "Architecture is not x86 or x86_64") + overrule_arch(mmx "Architecture is not x86 or x86_64") + overrule_arch(sse "Architecture is not x86 or x86_64") + overrule_arch(sse2 "Architecture is not x86 or x86_64") + overrule_arch(sse3 "Architecture is not x86 or x86_64") + overrule_arch(ssse3 "Architecture is not x86 or x86_64") + overrule_arch(sse4_a "Architecture is not x86 or x86_64") + overrule_arch(sse4_1 "Architecture is not x86 or x86_64") + overrule_arch(sse4_2 "Architecture is not x86 or x86_64") + overrule_arch(avx "Architecture is not x86 or x86_64") +endif() ######################################################################## # Select neon based on ARM ISA version @@ -265,33 +265,33 @@ endif(NOT CPU_IS_x86) include(CheckCSourceCompiles) check_c_source_compiles("#include \nint main(){ uint8_t *dest; uint8x8_t res; vst1_u8(dest, res); }" - neon_compile_result) + neon_compile_result) if(neon_compile_result) check_c_source_compiles("int main(){asm volatile(\"vrev32.8 q0, q0\");}" - have_neonv7_result ) + have_neonv7_result) check_c_source_compiles("int main(){asm volatile(\"sub v1.4s,v1.4s,v1.4s\");}" - have_neonv8_result ) + have_neonv8_result) - if (have_neonv7_result) - OVERRULE_ARCH(neonv8 "CPU is armv7") + if(have_neonv7_result) + overrule_arch(neonv8 "CPU is armv7") endif() - if (have_neonv8_result) - OVERRULE_ARCH(neonv7 "CPU is armv8") + if(have_neonv8_result) + overrule_arch(neonv7 "CPU is armv8") endif() -else(neon_compile_result) - OVERRULE_ARCH(neon "Compiler doesn't support NEON") - OVERRULE_ARCH(neonv7 "Compiler doesn't support NEON") - OVERRULE_ARCH(neonv8 "Compiler doesn't support NEON") -endif(neon_compile_result) +else() + overrule_arch(neon "Compiler doesn't support NEON") + overrule_arch(neonv7 "Compiler doesn't support NEON") + overrule_arch(neonv8 "Compiler doesn't support NEON") +endif() ######################################################################## # implement overruling in the ORC case, # since ORC always passes flag detection ######################################################################## if(NOT ORC_FOUND) - OVERRULE_ARCH(orc "ORC support not found") + overrule_arch(orc "ORC support not found") endif() ######################################################################## @@ -301,16 +301,16 @@ endif() if(NOT CROSSCOMPILE_MULTILIB AND CPU_IS_x86) include(CheckTypeSize) check_type_size("void*[8]" SIZEOF_CPU BUILTIN_TYPES_ONLY) - if (${SIZEOF_CPU} EQUAL 64) - OVERRULE_ARCH(32 "CPU width is 64 bits") + if(${SIZEOF_CPU} EQUAL 64) + overrule_arch(32 "CPU width is 64 bits") endif() - if (${SIZEOF_CPU} EQUAL 32) - OVERRULE_ARCH(64 "CPU width is 32 bits") + if(${SIZEOF_CPU} EQUAL 32) + overrule_arch(64 "CPU width is 32 bits") endif() #MSVC 64 bit does not have MMX, overrule it - if (${SIZEOF_CPU} EQUAL 64 AND MSVC) - OVERRULE_ARCH(mmx "No MMX for Win64") + if(${SIZEOF_CPU} EQUAL 64 AND MSVC) + overrule_arch(mmx "No MMX for Win64") endif() endif() @@ -340,12 +340,12 @@ execute_process( foreach(arch mmx orc 64 32) foreach(machine_name ${available_machines}) string(REPLACE "_${arch}" "" machine_name_no_arch ${machine_name}) - if (${machine_name} STREQUAL ${machine_name_no_arch}) + if(${machine_name} STREQUAL ${machine_name_no_arch}) else() list(REMOVE_ITEM available_machines ${machine_name_no_arch}) endif() - endforeach(machine_name) -endforeach(arch) + endforeach() +endforeach() ######################################################################## # done overrules! print the result @@ -373,7 +373,7 @@ macro(gen_template tmpl output) ${PROJECT_SOURCE_DIR}/gen/volk_gnsssdr_tmpl_utils.py --input ${tmpl} --output ${output} ${ARGN} ) -endmacro(gen_template) +endmacro() file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/include/volk_gnsssdr) @@ -399,13 +399,13 @@ if(MSVC) elseif(MSVC11) #Visual Studio 11 set(cmake_c_compiler_version "Microsoft Visual Studio 11.0") elseif(MSVC12) #Visual Studio 12 - SET(cmake_c_compiler_version "Microsoft Visual Studio 12.0") + set(cmake_c_compiler_version "Microsoft Visual Studio 12.0") endif() else() execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE cmake_c_compiler_version) -endif(MSVC) -set(COMPILER_INFO "${CMAKE_C_COMPILER}:::${CMAKE_C_FLAGS_${GRCBTU}} ${CMAKE_C_FLAGS}\n${CMAKE_CXX_COMPILER}:::${CMAKE_CXX_FLAGS_${GRCBTU}} ${CMAKE_CXX_FLAGS}\n" ) +endif() +set(COMPILER_INFO "${CMAKE_C_COMPILER}:::${CMAKE_C_FLAGS_${GRCBTU}} ${CMAKE_C_FLAGS}\n${CMAKE_CXX_COMPILER}:::${CMAKE_CXX_FLAGS_${GRCBTU}} ${CMAKE_CXX_FLAGS}\n") foreach(machine_name ${available_machines}) #generate machine source @@ -419,8 +419,8 @@ foreach(machine_name ${available_machines}) --mode "machine_flags" --machine "${machine_name}" --compiler "${COMPILER_NAME}" OUTPUT_VARIABLE ${machine_name}_flags OUTPUT_STRIP_TRAILING_WHITESPACE ) - MESSAGE(STATUS "BUILD INFO ::: ${machine_name} ::: ${COMPILER_NAME} ::: ${CMAKE_C_FLAGS_${CBTU}} ${CMAKE_C_FLAGS} ${${machine_name}_flags}") - set(COMPILER_INFO "${COMPILER_INFO}${machine_name}:::${COMPILER_NAME}:::${CMAKE_C_FLAGS_${CBTU}} ${CMAKE_C_FLAGS} ${${machine_name}_flags}\n" ) + message(STATUS "BUILD INFO ::: ${machine_name} ::: ${COMPILER_NAME} ::: ${CMAKE_C_FLAGS_${CBTU}} ${CMAKE_C_FLAGS} ${${machine_name}_flags}") + set(COMPILER_INFO "${COMPILER_INFO}${machine_name}:::${COMPILER_NAME}:::${CMAKE_C_FLAGS_${CBTU}} ${CMAKE_C_FLAGS} ${${machine_name}_flags}\n") if(${machine_name}_flags AND NOT MSVC) set_source_files_properties(${machine_source} PROPERTIES COMPILE_FLAGS "${${machine_name}_flags}") endif() @@ -428,12 +428,12 @@ foreach(machine_name ${available_machines}) #add to available machine defs string(TOUPPER LV_MACHINE_${machine_name} machine_def) list(APPEND machine_defs ${machine_def}) -endforeach(machine_name) +endforeach() # Convert to a C string to compile and display properly string(STRIP "${cmake_c_compiler_version}" cmake_c_compiler_version) string(STRIP ${COMPILER_INFO} COMPILER_INFO) -MESSAGE(STATUS "Compiler Version: ${cmake_c_compiler_version}") +message(STATUS "Compiler Version: ${cmake_c_compiler_version}") string(REPLACE "\n" " \\n" cmake_c_compiler_version ${cmake_c_compiler_version}) string(REPLACE "\n" " \\n" COMPILER_INFO ${COMPILER_INFO}) @@ -462,7 +462,7 @@ if(${CMAKE_VERSION} VERSION_GREATER "2.8.9") # set up the assembler flags and include the source files foreach(ARCH ${ASM_ARCHS_AVAILABLE}) string(REGEX MATCH "${ARCH}" ASM_ARCH "${available_archs}") - if( ASM_ARCH STREQUAL "neonv7" ) + if(ASM_ARCH STREQUAL "neonv7") message(STATUS "---- Adding ASM files") # we always use ATT syntax message(STATUS "-- Detected neon architecture; enabling ASM") # setup architecture specific assembler flags @@ -474,23 +474,23 @@ if(${CMAKE_VERSION} VERSION_GREATER "2.8.9") foreach(asm_file ${asm_files}) list(APPEND volk_gnsssdr_sources ${asm_file}) message(STATUS "Adding source file: ${asm_file}") - endforeach(asm_file) + endforeach() endif() enable_language(ASM) set(CMAKE_ASM_FLAGS ${ARCH_ASM_FLAGS}) message(STATUS "c flags: ${FULL_C_FLAGS}") message(STATUS "asm flags: ${CMAKE_ASM_FLAGS}") - endforeach(ARCH) + endforeach() -else(${CMAKE_VERSION} VERSION_GREATER "2.8.9") +else() message(STATUS "Not enabling ASM support. CMake >= 2.8.10 required.") foreach(machine_name ${available_machines}) string(REGEX MATCH "neon" NEON_MACHINE ${machine_name}) - if( NEON_MACHINE STREQUAL "neon") + if(NEON_MACHINE STREQUAL "neon") message(FATAL_ERROR "CMake >= 2.8.10 is required for ARM NEON support") endif() endforeach() -endif(${CMAKE_VERSION} VERSION_GREATER "2.8.9") +endif() ######################################################################## # Handle orc support @@ -517,7 +517,7 @@ if(ORC_FOUND) ) list(APPEND volk_gnsssdr_sources ${orcc_gen}) - endforeach(orc_file) + endforeach() else() message(STATUS "Did not find liborc and orcc, disabling orc support...") endif() @@ -571,7 +571,7 @@ endif() if(CMAKE_VERSION VERSION_GREATER "2.8.7") #Create a volk_gnsssdr object library (requires cmake >= 2.8.8) add_library(volk_gnsssdr_obj OBJECT ${volk_gnsssdr_sources}) - + #Add dynamic library add_library(volk_gnsssdr SHARED $) target_link_libraries(volk_gnsssdr ${volk_gnsssdr_libraries} ${Boost_LIBRARIES}) @@ -597,7 +597,7 @@ if(CMAKE_VERSION VERSION_GREATER "2.8.7") install(TARGETS volk_gnsssdr_static ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT "volk_gnsssdr_devel" ) - endif(ENABLE_STATIC_LIBS) + endif() #Older cmake versions (slower to build when building dynamic/static libs) else() @@ -619,14 +619,14 @@ else() if(NOT WIN32) set_target_properties(volk_gnsssdr_static PROPERTIES OUTPUT_NAME volk_gnsssdr) - endif(NOT WIN32) + endif() install(TARGETS volk_gnsssdr_static ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT "volk_gnsssdr_devel" # .lib file ) - endif(ENABLE_STATIC_LIBS) + endif() +endif() -endif(CMAKE_VERSION VERSION_GREATER "2.8.7") ######################################################################## # Build the QA test application ######################################################################## @@ -641,7 +641,7 @@ if(ENABLE_TESTING) ) include(VolkAddTest) - VOLK_GEN_TEST("volk_gnsssdr_test_all" + volk_gen_test("volk_gnsssdr_test_all" SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/testqa.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_utils.cc TARGET_DEPS volk_gnsssdr @@ -649,9 +649,7 @@ if(ENABLE_TESTING) foreach(kernel ${h_files}) get_filename_component(kernel ${kernel} NAME) string(REPLACE ".h" "" kernel ${kernel}) - if(NOT ${kernel} MATCHES puppet*) - VOLK_ADD_TEST(${kernel} "volk_gnsssdr_test_all") - endif(NOT ${kernel} MATCHES puppet*) + volk_add_test(${kernel} "volk_gnsssdr_test_all") endforeach() -endif(ENABLE_TESTING) +endif() diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h index d9fca252a..51a96b171 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/kernel_tests.h @@ -93,11 +93,13 @@ std::vector init_test_list(volk_gnsssdr_test_params_t QA(VOLK_INIT_PUPP(volk_gnsssdr_16i_resamplerxnpuppet_16i, volk_gnsssdr_16i_xn_resampler_16i_xn, test_params)) QA(VOLK_INIT_PUPP(volk_gnsssdr_32fc_resamplerxnpuppet_32fc, volk_gnsssdr_32fc_xn_resampler_32fc_xn, test_params)) QA(VOLK_INIT_PUPP(volk_gnsssdr_32f_resamplerxnpuppet_32f, volk_gnsssdr_32f_xn_resampler_32f_xn, test_params)) + QA(VOLK_INIT_PUPP(volk_gnsssdr_32f_high_dynamics_resamplerxnpuppet_32f, volk_gnsssdr_32f_xn_high_dynamics_resampler_32f_xn, test_params)) QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_x2_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_x2_dot_prod_16ic_xn, test_params)) QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_x2_rotator_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_x2_rotator_dot_prod_16ic_xn, test_params_int16)) QA(VOLK_INIT_PUPP(volk_gnsssdr_16ic_16i_rotator_dotprodxnpuppet_16ic, volk_gnsssdr_16ic_16i_rotator_dot_prod_16ic_xn, test_params_int16)) QA(VOLK_INIT_PUPP(volk_gnsssdr_32fc_x2_rotator_dotprodxnpuppet_32fc, volk_gnsssdr_32fc_x2_rotator_dot_prod_32fc_xn, test_params_int1)) QA(VOLK_INIT_PUPP(volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc, volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn, test_params_int1)); + QA(VOLK_INIT_PUPP(volk_gnsssdr_32fc_32f_high_dynamic_rotator_dotprodxnpuppet_32fc, volk_gnsssdr_32fc_32f_high_dynamic_rotator_dot_prod_32fc_xn, test_params_int1)); return test_cases; } diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/testqa.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/testqa.cc index 113308e71..2dc11324e 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/testqa.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/testqa.cc @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) float def_tol = 1e-6; lv_32fc_t def_scalar = 327.0; int def_iter = 1; - int def_vlen = 131071; + int def_vlen = 8111; bool def_benchmark_mode = true; std::string def_kernel_regex = ""; diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/__init__.py b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/__init__.py index db03736dd..04e726c70 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/__init__.py +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/__init__.py @@ -19,5 +19,5 @@ # # -from cfg import volk_gnsssdr_modtool_config -from volk_gnsssdr_modtool_generate import volk_gnsssdr_modtool +from .cfg import volk_gnsssdr_modtool_config +from .volk_gnsssdr_modtool_generate import volk_gnsssdr_modtool diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/cfg.py b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/cfg.py index bb2f511d8..e4f12a62c 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/cfg.py +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/cfg.py @@ -21,14 +21,13 @@ from __future__ import print_function -import ConfigParser import sys import os -import exceptions import re +from six.moves import configparser, input -class volk_gnsssdr_modtool_config: +class volk_gnsssdr_modtool_config(object): def key_val_sub(self, num, stuff, section): return re.sub('\$' + 'k' + str(num), stuff[num][0], (re.sub('\$' + str(num), stuff[num][1], section[1][num]))); @@ -46,11 +45,11 @@ class volk_gnsssdr_modtool_config: try: val = eval(self.key_val_sub(i, stuff, section)) if val == False: - raise exceptions.ValueError + raise ValueError except ValueError: - raise exceptions.ValueError('Verification function returns False... key:%s, val:%s'%(stuff[i][0], stuff[i][1])) + raise ValueError('Verification function returns False... key:%s, val:%s'%(stuff[i][0], stuff[i][1])) except: - raise exceptions.IOError('bad configuration... key:%s, val:%s'%(stuff[i][0], stuff[i][1])) + raise IOError('bad configuration... key:%s, val:%s'%(stuff[i][0], stuff[i][1])) def __init__(self, cfg=None): @@ -66,7 +65,7 @@ class volk_gnsssdr_modtool_config: self.remapification = [(self.config_name, self.config_defaults_remap)] self.verification = [(self.config_name, self.config_defaults_verify)] default = os.path.join(os.getcwd(), 'volk_gnsssdr_modtool.cfg') - icfg = ConfigParser.RawConfigParser() + icfg = configparser.RawConfigParser() if cfg: icfg.read(cfg) elif os.path.exists(default): @@ -75,7 +74,7 @@ class volk_gnsssdr_modtool_config: print("Initializing config file...") icfg.add_section(self.config_name) for kn in self.config_defaults: - rv = raw_input("%s: "%(kn)) + rv = input("%s: "%(kn)) icfg.set(self.config_name, kn, rv) self.cfg = icfg self.remap() diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/volk_gnsssdr_modtool b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/volk_gnsssdr_modtool index 898a1f658..ded907fbe 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/volk_gnsssdr_modtool +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/volk_gnsssdr_modtool @@ -18,10 +18,10 @@ # along with GNSS-SDR. If not, see . # +from __future__ import print_function from volk_gnsssdr_modtool import volk_gnsssdr_modtool, volk_gnsssdr_modtool_config from optparse import OptionParser, OptionGroup -import exceptions import os import sys @@ -57,12 +57,12 @@ if __name__ == '__main__': parser.print_help() elif options.moo: - print " (__) " - print " (oo) " - print " /------\/ " - print " / | || " - print " * /\---/\ " - print " ~~ ~~ " + print(" (__) ") + print(" (oo) ") + print(" /------\/ ") + print(" / | || ") + print(" * /\---/\ ") + print(" ~~ ~~ ") else: my_cfg = volk_gnsssdr_modtool_config(options.config_file); @@ -77,7 +77,7 @@ if __name__ == '__main__': if options.add_kernel: if not options.kernel_name: - raise exceptions.IOError("This action requires the -n option."); + raise IOError("This action requires the -n option."); else: name = options.kernel_name; if options.base_path: @@ -88,7 +88,7 @@ if __name__ == '__main__': if options.remove_kernel: if not options.kernel_name: - raise exceptions.IOError("This action requires the -n option."); + raise IOError("This action requires the -n option."); else: name = options.kernel_name; my_modtool.remove_kernel(name); @@ -105,17 +105,17 @@ if __name__ == '__main__': if options.remote_list: if not options.base_path: - raise exceptions.IOError("This action requires the -b option. Try -l or -k for listing kernels in the base or the module.") + raise IOError("This action requires the -b option. Try -l or -k for listing kernels in the base or the module.") else: base = options.base_path; kernelset = my_modtool.get_current_kernels(base); for i in kernelset: - print i; + print(i); if options.list: kernelset = my_modtool.get_current_kernels(); for i in kernelset: - print i; + print(i); if options.kernels: dest = my_cfg.cfg.get(my_cfg.config_name, 'destination'); @@ -123,4 +123,4 @@ if __name__ == '__main__': base = os.path.join(dest, 'volk_gnsssdr_' + name); kernelset = my_modtool.get_current_kernels(base); for i in kernelset: - print i; + print(i); diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/volk_gnsssdr_modtool_generate.py b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/volk_gnsssdr_modtool_generate.py index 3384ecd91..df613a938 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/volk_gnsssdr_modtool_generate.py +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/python/volk_gnsssdr_modtool/volk_gnsssdr_modtool_generate.py @@ -21,15 +21,10 @@ from __future__ import print_function import os -import glob -import sys import re import glob -import shutil -import exceptions -from sets import Set -class volk_gnsssdr_modtool: +class volk_gnsssdr_modtool(object): def __init__(self, cfg): self.volk_gnsssdr = re.compile('volk_gnsssdr'); self.remove_after_underscore = re.compile("_.*"); @@ -96,7 +91,7 @@ class volk_gnsssdr_modtool: dest = os.path.join(self.my_dict['destination'], 'volk_gnsssdr_' + self.my_dict['name']) if os.path.exists(dest): - raise exceptions.IOError("Destination %s already exits!"%(dest)); + raise IOError("Destination %s already exits!" % (dest)); if not os.path.exists(os.path.join(self.my_dict['destination'], 'volk_gnsssdr_' + self.my_dict['name'], 'kernels/volk_gnsssdr_' + self.my_dict['name'])): os.makedirs(os.path.join(self.my_dict['destination'], 'volk_gnsssdr_' + self.my_dict['name'], 'kernels/volk_gnsssdr_' + self.my_dict['name'])) @@ -108,7 +103,7 @@ class volk_gnsssdr_modtool: for root, dirnames, filenames in os.walk(self.my_dict['base']): for name in filenames: - t_table = map(lambda a: re.search(a, name), current_kernel_names); + t_table = [re.search(a, name) for a in current_kernel_names] t_table = set(t_table); if t_table == set([None]): infile = os.path.join(root, name); @@ -188,16 +183,11 @@ class volk_gnsssdr_modtool: base = os.path.join(self.my_dict['destination'], top[:-1]) ; if not name in self.get_current_kernels(): - - raise exceptions.IOError("Requested kernel %s is not in module %s"%(name,base)); - - + raise IOError("Requested kernel %s is not in module %s" % (name,base)); inpath = os.path.abspath(base); - - kernel = re.compile(name) - search_kernels = Set([kernel]) + search_kernels = set([kernel]) profile = re.compile('^\s*VOLK_PROFILE') puppet = re.compile('^\s*VOLK_PUPPET') src_dest = os.path.join(inpath, 'apps/', top[:-1] + '_profile.cc'); @@ -253,7 +243,7 @@ class volk_gnsssdr_modtool: else: basename = self.get_basename(base); if not name in self.get_current_kernels(base): - raise exceptions.IOError("Requested kernel %s is not in module %s"%(name,base)); + raise IOError("Requested kernel %s is not in module %s" % (name, base)); inpath = os.path.abspath(base); if len(basename) > 0: @@ -265,7 +255,7 @@ class volk_gnsssdr_modtool: self.convert_kernel(oldvolk_gnsssdr, name, base, inpath, top); kernel = re.compile(name) - search_kernels = Set([kernel]) + search_kernels = set([kernel]) profile = re.compile('^\s*VOLK_PROFILE') puppet = re.compile('^\s*VOLK_PUPPET') diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c index 4aba13014..420b5c91d 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c @@ -123,6 +123,15 @@ static inline unsigned int get_avx2_enabled(void) #endif } +static inline unsigned int get_avx512_enabled(void) +{ +#if defined(VOLK_CPU_x86) + return __xgetbv() & 0xE6; //check for zmm, xmm and ymm regs +#else + return 0; +#endif +} + //neon detection is linux specific #if defined(__arm__) && defined(__linux__) #include diff --git a/src/algorithms/observables/CMakeLists.txt b/src/algorithms/observables/CMakeLists.txt index 64cb2a571..1841d3dfc 100644 --- a/src/algorithms/observables/CMakeLists.txt +++ b/src/algorithms/observables/CMakeLists.txt @@ -17,4 +17,4 @@ # add_subdirectory(adapters) -add_subdirectory(gnuradio_blocks) \ No newline at end of file +add_subdirectory(gnuradio_blocks) diff --git a/src/algorithms/observables/adapters/CMakeLists.txt b/src/algorithms/observables/adapters/CMakeLists.txt index d3cff285a..ef0df1d7d 100644 --- a/src/algorithms/observables/adapters/CMakeLists.txt +++ b/src/algorithms/observables/adapters/CMakeLists.txt @@ -17,24 +17,26 @@ # set(OBS_ADAPTER_SOURCES - hybrid_observables.cc + hybrid_observables.cc +) + +set(OBS_ADAPTER_HEADERS + hybrid_observables.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/observables/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/observables/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} ) -file(GLOB OBS_ADAPTER_HEADERS "*.h") -list(SORT OBS_ADAPTER_HEADERS) add_library(obs_adapters ${OBS_ADAPTER_SOURCES} ${OBS_ADAPTER_HEADERS}) source_group(Headers FILES ${OBS_ADAPTER_HEADERS}) target_link_libraries(obs_adapters obs_gr_blocks ${GNURADIO_RUNTIME_LIBRARIES}) diff --git a/src/algorithms/observables/adapters/hybrid_observables.cc b/src/algorithms/observables/adapters/hybrid_observables.cc index 4313edfee..cf03f2d2c 100644 --- a/src/algorithms/observables/adapters/hybrid_observables.cc +++ b/src/algorithms/observables/adapters/hybrid_observables.cc @@ -38,21 +38,22 @@ using google::LogMessage; HybridObservables::HybridObservables(ConfigurationInterface* configuration, - std::string role, unsigned int in_streams, unsigned int out_streams) : - role_(role), in_streams_(in_streams), out_streams_(out_streams) + std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { std::string default_dump_filename = "./observables.dat"; DLOG(INFO) << "role " << role; dump_ = configuration->property(role + ".dump", false); + dump_mat_ = configuration->property(role + ".dump_mat", true); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); - observables_ = hybrid_make_observables_cc(in_streams_, out_streams_, dump_, dump_filename_); + observables_ = hybrid_make_observables_cc(in_streams_, out_streams_, dump_, dump_mat_, dump_filename_); DLOG(INFO) << "Observables block ID (" << observables_->unique_id() << ")"; } HybridObservables::~HybridObservables() -{} +{ +} void HybridObservables::connect(gr::top_block_sptr top_block) diff --git a/src/algorithms/observables/adapters/hybrid_observables.h b/src/algorithms/observables/adapters/hybrid_observables.h index 57883374a..1beb968fa 100644 --- a/src/algorithms/observables/adapters/hybrid_observables.h +++ b/src/algorithms/observables/adapters/hybrid_observables.h @@ -83,6 +83,7 @@ public: private: hybrid_observables_cc_sptr observables_; bool dump_; + bool dump_mat_; std::string dump_filename_; std::string role_; unsigned int in_streams_; diff --git a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt index 276908208..e829c474d 100644 --- a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt @@ -16,31 +16,50 @@ # along with GNSS-SDR. If not, see . # -set(OBS_GR_BLOCKS_SOURCES - hybrid_observables_cc.cc +set(OBS_GR_BLOCKS_SOURCES + hybrid_observables_cc.cc +) + +set(OBS_GR_BLOCKS_HEADERS + hybrid_observables_cc.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${ARMADILLO_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${MATIO_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${ARMADILLO_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${MATIO_INCLUDE_DIRS} ) -file(GLOB OBS_GR_BLOCKS_HEADERS "*.h") -list(SORT OBS_GR_BLOCKS_HEADERS) add_library(obs_gr_blocks ${OBS_GR_BLOCKS_SOURCES} ${OBS_GR_BLOCKS_HEADERS}) + source_group(Headers FILES ${OBS_GR_BLOCKS_HEADERS}) + if(MATIO_FOUND) - add_dependencies(obs_gr_blocks gnss_sp_libs glog-${glog_RELEASE} armadillo-${armadillo_RELEASE}) -else(MATIO_FOUND) - add_dependencies(obs_gr_blocks gnss_sp_libs glog-${glog_RELEASE} armadillo-${armadillo_RELEASE} matio-${GNSSSDR_MATIO_LOCAL_VERSION}) -endif(MATIO_FOUND) -target_link_libraries(obs_gr_blocks gnss_sp_libs ${GNURADIO_RUNTIME_LIBRARIES} ${ARMADILLO_LIBRARIES} ${MATIO_LIBRARIES}) + add_dependencies(obs_gr_blocks + gnss_sp_libs + glog-${glog_RELEASE} + armadillo-${armadillo_RELEASE} + ) +else() + add_dependencies(obs_gr_blocks + gnss_sp_libs + glog-${glog_RELEASE} + armadillo-${armadillo_RELEASE} + matio-${GNSSSDR_MATIO_LOCAL_VERSION} + ) +endif() + +target_link_libraries(obs_gr_blocks + gnss_sp_libs + ${GNURADIO_RUNTIME_LIBRARIES} + ${ARMADILLO_LIBRARIES} + ${MATIO_LIBRARIES} +) diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc index 0e84dea54..ffd395462 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.cc @@ -32,12 +32,14 @@ #include "hybrid_observables_cc.h" #include "display.h" #include "GPS_L1_CA.h" -#include +#include "gnss_sdr_create_directory.h" +#include #include #include #include #include #include +#include #include #include @@ -45,50 +47,79 @@ using google::LogMessage; -hybrid_observables_cc_sptr hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, std::string dump_filename) +hybrid_observables_cc_sptr hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, bool dump_mat, std::string dump_filename) { - return hybrid_observables_cc_sptr(new hybrid_observables_cc(nchannels_in, nchannels_out, dump, dump_filename)); + return hybrid_observables_cc_sptr(new hybrid_observables_cc(nchannels_in, nchannels_out, dump, dump_mat, dump_filename)); } -hybrid_observables_cc::hybrid_observables_cc(unsigned int nchannels_in, - unsigned int nchannels_out, +hybrid_observables_cc::hybrid_observables_cc(uint32_t nchannels_in, + uint32_t nchannels_out, bool dump, + bool dump_mat, std::string dump_filename) : gr::block("hybrid_observables_cc", gr::io_signature::make(nchannels_in, nchannels_in, sizeof(Gnss_Synchro)), gr::io_signature::make(nchannels_out, nchannels_out, sizeof(Gnss_Synchro))) { d_dump = dump; - d_nchannels = nchannels_out; + d_dump_mat = dump_mat and d_dump; d_dump_filename = dump_filename; - T_rx_s = 0.0; - T_rx_step_ms = 1; // 1 ms - max_delta = 1.5; // 1.5 s - d_latency = 0.5; // 300 ms - valid_channels.resize(d_nchannels, false); - d_num_valid_channels = 0; - d_gnss_synchro_history = new Gnss_circular_deque(static_cast(max_delta * 1000.0), d_nchannels); + d_nchannels_out = nchannels_out; + d_nchannels_in = nchannels_in; + T_rx_clock_step_samples = 0U; + d_gnss_synchro_history = new Gnss_circular_deque(500, d_nchannels_out); // ############# ENABLE DATA FILE LOG ################# if (d_dump) { - if (!d_dump_file.is_open()) + std::string dump_path; + // Get path + if (d_dump_filename.find_last_of("/") != std::string::npos) { - try - { - d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "Exception opening observables dump file " << e.what(); - d_dump = false; - } + std::string dump_filename_ = d_dump_filename.substr(d_dump_filename.find_last_of("/") + 1); + dump_path = d_dump_filename.substr(0, d_dump_filename.find_last_of("/")); + d_dump_filename = dump_filename_; + } + else + { + dump_path = std::string("."); + } + if (d_dump_filename.empty()) + { + d_dump_filename = "observables.dat"; + } + // remove extension if any + if (d_dump_filename.substr(1).find_last_of(".") != std::string::npos) + { + d_dump_filename = d_dump_filename.substr(0, d_dump_filename.find_last_of(".")); + } + d_dump_filename.append(".dat"); + d_dump_filename = dump_path + boost::filesystem::path::preferred_separator + d_dump_filename; + // create directory + if (!gnss_sdr_create_directory(dump_path)) + { + std::cerr << "GNSS-SDR cannot create dump file for the Observables block. Wrong permissions?" << std::endl; + d_dump = false; + } + d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Observables dump enabled Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "Exception opening observables dump file " << e.what(); + d_dump = false; } } - T_rx_TOW_ms = 0; + T_rx_TOW_ms = 0U; + T_rx_TOW_offset_ms = 0U; T_rx_TOW_set = false; + + // rework + d_Rx_clock_buffer.resize(10); // 10*20 ms = 200 ms of data in buffer + d_Rx_clock_buffer.clear(); // Clear all the elements in the buffer } @@ -106,26 +137,26 @@ hybrid_observables_cc::~hybrid_observables_cc() LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); } } - if (d_dump) + if (d_dump_mat) { - std::cout << "Writing observables .mat files ..."; save_matfile(); - std::cout << " done." << std::endl; } } -int hybrid_observables_cc::save_matfile() +int32_t hybrid_observables_cc::save_matfile() { // READ DUMP FILE + std::string dump_filename = d_dump_filename; std::ifstream::pos_type size; - int number_of_double_vars = 7; - int epoch_size_bytes = sizeof(double) * number_of_double_vars * d_nchannels; + int32_t number_of_double_vars = 7; + int32_t epoch_size_bytes = sizeof(double) * number_of_double_vars * d_nchannels_out; std::ifstream dump_file; + std::cout << "Generating .mat file for " << dump_filename << std::endl; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { - dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + dump_file.open(dump_filename.c_str(), std::ios::binary | std::ios::ate); } catch (const std::ifstream::failure &e) { @@ -133,26 +164,26 @@ int hybrid_observables_cc::save_matfile() return 1; } // count number of epochs and rewind - long int num_epoch = 0; + int64_t num_epoch = 0LL; if (dump_file.is_open()) { size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); dump_file.seekg(0, std::ios::beg); } else { return 1; } - double **RX_time = new double *[d_nchannels]; - double **TOW_at_current_symbol_s = new double *[d_nchannels]; - double **Carrier_Doppler_hz = new double *[d_nchannels]; - double **Carrier_phase_cycles = new double *[d_nchannels]; - double **Pseudorange_m = new double *[d_nchannels]; - double **PRN = new double *[d_nchannels]; - double **Flag_valid_pseudorange = new double *[d_nchannels]; + double **RX_time = new double *[d_nchannels_out]; + double **TOW_at_current_symbol_s = new double *[d_nchannels_out]; + double **Carrier_Doppler_hz = new double *[d_nchannels_out]; + double **Carrier_phase_cycles = new double *[d_nchannels_out]; + double **Pseudorange_m = new double *[d_nchannels_out]; + double **PRN = new double *[d_nchannels_out]; + double **Flag_valid_pseudorange = new double *[d_nchannels_out]; - for (unsigned int i = 0; i < d_nchannels; i++) + for (uint32_t i = 0; i < d_nchannels_out; i++) { RX_time[i] = new double[num_epoch]; TOW_at_current_symbol_s[i] = new double[num_epoch]; @@ -167,9 +198,9 @@ int hybrid_observables_cc::save_matfile() { if (dump_file.is_open()) { - for (long int i = 0; i < num_epoch; i++) + for (int64_t i = 0; i < num_epoch; i++) { - for (unsigned int chan = 0; chan < d_nchannels; chan++) + for (uint32_t chan = 0; chan < d_nchannels_out; chan++) { dump_file.read(reinterpret_cast(&RX_time[chan][i]), sizeof(double)); dump_file.read(reinterpret_cast(&TOW_at_current_symbol_s[chan][i]), sizeof(double)); @@ -186,7 +217,7 @@ int hybrid_observables_cc::save_matfile() catch (const std::ifstream::failure &e) { std::cerr << "Problem reading dump file:" << e.what() << std::endl; - for (unsigned int i = 0; i < d_nchannels; i++) + for (uint32_t i = 0; i < d_nchannels_out; i++) { delete[] RX_time[i]; delete[] TOW_at_current_symbol_s[i]; @@ -207,17 +238,17 @@ int hybrid_observables_cc::save_matfile() return 1; } - double *RX_time_aux = new double[d_nchannels * num_epoch]; - double *TOW_at_current_symbol_s_aux = new double[d_nchannels * num_epoch]; - double *Carrier_Doppler_hz_aux = new double[d_nchannels * num_epoch]; - double *Carrier_phase_cycles_aux = new double[d_nchannels * num_epoch]; - double *Pseudorange_m_aux = new double[d_nchannels * num_epoch]; - double *PRN_aux = new double[d_nchannels * num_epoch]; - double *Flag_valid_pseudorange_aux = new double[d_nchannels * num_epoch]; - unsigned int k = 0; - for (long int j = 0; j < num_epoch; j++) + double *RX_time_aux = new double[d_nchannels_out * num_epoch]; + double *TOW_at_current_symbol_s_aux = new double[d_nchannels_out * num_epoch]; + double *Carrier_Doppler_hz_aux = new double[d_nchannels_out * num_epoch]; + double *Carrier_phase_cycles_aux = new double[d_nchannels_out * num_epoch]; + double *Pseudorange_m_aux = new double[d_nchannels_out * num_epoch]; + double *PRN_aux = new double[d_nchannels_out * num_epoch]; + double *Flag_valid_pseudorange_aux = new double[d_nchannels_out * num_epoch]; + uint32_t k = 0U; + for (int64_t j = 0; j < num_epoch; j++) { - for (unsigned int i = 0; i < d_nchannels; i++) + for (uint32_t i = 0; i < d_nchannels_out; i++) { RX_time_aux[k] = RX_time[i][j]; TOW_at_current_symbol_s_aux[k] = TOW_at_current_symbol_s[i][j]; @@ -240,9 +271,9 @@ int hybrid_observables_cc::save_matfile() } filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (reinterpret_cast(matfp) != NULL) + if (reinterpret_cast(matfp) != NULL) { - size_t dims[2] = {static_cast(d_nchannels), static_cast(num_epoch)}; + size_t dims[2] = {static_cast(d_nchannels_out), static_cast(num_epoch)}; matvar = Mat_VarCreate("RX_time", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, RX_time_aux, MAT_F_DONT_COPY_DATA); Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarFree(matvar); @@ -273,7 +304,7 @@ int hybrid_observables_cc::save_matfile() } Mat_Close(matfp); - for (unsigned int i = 0; i < d_nchannels; i++) + for (uint32_t i = 0; i < d_nchannels_out; i++) { delete[] RX_time[i]; delete[] TOW_at_current_symbol_s[i]; @@ -302,174 +333,169 @@ int hybrid_observables_cc::save_matfile() } -bool hybrid_observables_cc::interpolate_data(Gnss_Synchro &out, const unsigned int &ch, const double &ti) +double hybrid_observables_cc::compute_T_rx_s(const Gnss_Synchro &a) { - if ((ti < d_gnss_synchro_history->front(ch).RX_time) or (ti > d_gnss_synchro_history->back(ch).RX_time)) + return ((static_cast(a.Tracking_sample_counter) + a.Code_phase_samples) / static_cast(a.fs)); +} + + +bool hybrid_observables_cc::interp_trk_obs(Gnss_Synchro &interpolated_obs, const uint32_t &ch, const uint64_t &rx_clock) +{ + int32_t nearest_element = -1; + int64_t abs_diff; + int64_t old_abs_diff = std::numeric_limits::max(); + for (uint32_t i = 0; i < d_gnss_synchro_history->size(ch); i++) + { + abs_diff = llabs(static_cast(rx_clock) - static_cast(d_gnss_synchro_history->at(ch, i).Tracking_sample_counter)); + if (old_abs_diff > abs_diff) + { + old_abs_diff = abs_diff; + nearest_element = static_cast(i); + } + } + + if (nearest_element != -1 and nearest_element != static_cast(d_gnss_synchro_history->size(ch))) + { + if ((static_cast(old_abs_diff) / static_cast(d_gnss_synchro_history->at(ch, nearest_element).fs)) < 0.02) + { + int32_t neighbor_element; + if (rx_clock > d_gnss_synchro_history->at(ch, nearest_element).Tracking_sample_counter) + { + neighbor_element = nearest_element + 1; + } + else + { + neighbor_element = nearest_element - 1; + } + if (neighbor_element < static_cast(d_gnss_synchro_history->size(ch)) and neighbor_element >= 0) + { + int32_t t1_idx; + int32_t t2_idx; + if (rx_clock > d_gnss_synchro_history->at(ch, nearest_element).Tracking_sample_counter) + { + //std::cout << "S1= " << d_gnss_synchro_history->at(ch, nearest_element).Tracking_sample_counter + // << " Si=" << rx_clock << " S2=" << d_gnss_synchro_history->at(ch, neighbor_element).Tracking_sample_counter << std::endl; + t1_idx = nearest_element; + t2_idx = neighbor_element; + } + else + { + //std::cout << "inv S1= " << d_gnss_synchro_history->at(ch, neighbor_element).Tracking_sample_counter + // << " Si=" << rx_clock << " S2=" << d_gnss_synchro_history->at(ch, nearest_element).Tracking_sample_counter << std::endl; + t1_idx = neighbor_element; + t2_idx = nearest_element; + } + + // 1st: copy the nearest gnss_synchro data for that channel + interpolated_obs = d_gnss_synchro_history->at(ch, nearest_element); + + // 2nd: Linear interpolation: y(t) = y(t1) + (y(t2) - y(t1)) * (t - t1) / (t2 - t1) + + double T_rx_s = static_cast(rx_clock) / static_cast(interpolated_obs.fs); + + double time_factor = (T_rx_s - d_gnss_synchro_history->at(ch, t1_idx).RX_time) / + (d_gnss_synchro_history->at(ch, t2_idx).RX_time - + d_gnss_synchro_history->at(ch, t1_idx).RX_time); + + // CARRIER PHASE INTERPOLATION + interpolated_obs.Carrier_phase_rads = d_gnss_synchro_history->at(ch, t1_idx).Carrier_phase_rads + (d_gnss_synchro_history->at(ch, t2_idx).Carrier_phase_rads - d_gnss_synchro_history->at(ch, t1_idx).Carrier_phase_rads) * time_factor; + // CARRIER DOPPLER INTERPOLATION + interpolated_obs.Carrier_Doppler_hz = d_gnss_synchro_history->at(ch, t1_idx).Carrier_Doppler_hz + (d_gnss_synchro_history->at(ch, t2_idx).Carrier_Doppler_hz - d_gnss_synchro_history->at(ch, t1_idx).Carrier_Doppler_hz) * time_factor; + // TOW INTERPOLATION + interpolated_obs.interp_TOW_ms = static_cast(d_gnss_synchro_history->at(ch, t1_idx).TOW_at_current_symbol_ms) + (static_cast(d_gnss_synchro_history->at(ch, t2_idx).TOW_at_current_symbol_ms) - static_cast(d_gnss_synchro_history->at(ch, t1_idx).TOW_at_current_symbol_ms)) * time_factor; + // + // std::cout << "Rx samplestamp: " << T_rx_s << " Channel " << ch << " interp buff idx " << nearest_element + // << " ,diff: " << old_abs_diff << " samples (" << static_cast(old_abs_diff) / static_cast(d_gnss_synchro_history->at(ch, nearest_element).fs) << " s)\n"; + return true; + } + else + { + return false; + } + } + else + { + // std::cout << "ALERT: Channel " << ch << " interp buff idx " << nearest_element + // << " ,diff: " << old_abs_diff << " samples (" << static_cast(old_abs_diff) / static_cast(d_gnss_synchro_history->at(ch, nearest_element).fs) << " s)\n"; + // usleep(1000); + return false; + } + } + else { return false; } - find_interp_elements(ch, ti); - - // 1st: copy the nearest gnss_synchro data for that channel - out = d_gnss_synchro_history->at(ch, 0); - - // 2nd: Linear interpolation: y(t) = y(t1) + (y(t2) - y(t1)) * (t - t1) / (t2 - t1) - - // CARRIER PHASE INTERPOLATION - out.Carrier_phase_rads = d_gnss_synchro_history->at(ch, 0).Carrier_phase_rads + (d_gnss_synchro_history->at(ch, 1).Carrier_phase_rads - d_gnss_synchro_history->at(ch, 0).Carrier_phase_rads) * (ti - d_gnss_synchro_history->at(ch, 0).RX_time) / (d_gnss_synchro_history->at(ch, 1).RX_time - d_gnss_synchro_history->at(ch, 0).RX_time); - - // CARRIER DOPPLER INTERPOLATION - out.Carrier_Doppler_hz = d_gnss_synchro_history->at(ch, 0).Carrier_Doppler_hz + (d_gnss_synchro_history->at(ch, 1).Carrier_Doppler_hz - d_gnss_synchro_history->at(ch, 0).Carrier_Doppler_hz) * (ti - d_gnss_synchro_history->at(ch, 0).RX_time) / (d_gnss_synchro_history->at(ch, 1).RX_time - d_gnss_synchro_history->at(ch, 0).RX_time); - - // TOW INTERPOLATION - out.interp_TOW_ms = static_cast(d_gnss_synchro_history->at(ch, 0).TOW_at_current_symbol_ms) + (static_cast(d_gnss_synchro_history->at(ch, 1).TOW_at_current_symbol_ms) - static_cast(d_gnss_synchro_history->at(ch, 0).TOW_at_current_symbol_ms)) * (ti - d_gnss_synchro_history->at(ch, 0).RX_time) / (d_gnss_synchro_history->at(ch, 1).RX_time - d_gnss_synchro_history->at(ch, 0).RX_time); - - return true; } -double hybrid_observables_cc::compute_T_rx_s(const Gnss_Synchro &a) +void hybrid_observables_cc::forecast(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items_required) { - if (a.Flag_valid_word) + for (int32_t n = 0; n < static_cast(d_nchannels_in) - 1; n++) { - return ((static_cast(a.Tracking_sample_counter) + a.Code_phase_samples) / static_cast(a.fs)); - } - else - { - return 0.0; + ninput_items_required[n] = 0; } + // last input channel is the sample counter, triggered each ms + ninput_items_required[d_nchannels_in - 1] = 1; } -void hybrid_observables_cc::find_interp_elements(const unsigned int &ch, const double &ti) -{ - unsigned int closest = 0; - double dif = std::numeric_limits::max(); - double dt = 0.0; - for (unsigned int i = 0; i < d_gnss_synchro_history->size(ch); i++) - { - dt = std::fabs(ti - d_gnss_synchro_history->at(ch, i).RX_time); - if (dt < dif) - { - closest = i; - dif = dt; - } - else - { - break; - } - } - if (ti > d_gnss_synchro_history->at(ch, closest).RX_time) - { - while (closest > 0) - { - d_gnss_synchro_history->pop_front(ch); - closest--; - } - } - else - { - while (closest > 1) - { - d_gnss_synchro_history->pop_front(ch); - closest--; - } - } -} - - -void hybrid_observables_cc::forecast(int noutput_items, gr_vector_int &ninput_items_required) -{ - for (unsigned int i = 0; i < d_nchannels; i++) - { - ninput_items_required[i] = 0; - } - ninput_items_required[d_nchannels] = noutput_items; -} - - -void hybrid_observables_cc::clean_history(unsigned int pos) -{ - while (d_gnss_synchro_history->size(pos) > 0) - { - if ((T_rx_s - d_gnss_synchro_history->front(pos).RX_time) > max_delta) - { - d_gnss_synchro_history->pop_front(pos); - } - else - { - return; - } - } -} - - -void hybrid_observables_cc::correct_TOW_and_compute_prange(std::vector &data) +void hybrid_observables_cc::update_TOW(std::vector &data) { + //1. Set the TOW using the minimum TOW in the observables. + // this will be the receiver time. + //2. If the TOW is set, it must be incremented by the desired receiver time step. + // the time step must match the observables timer block (connected to the las input channel) std::vector::iterator it; - - /////////////////////// DEBUG ////////////////////////// - // Logs if there is a pseudorange difference between - // signals of the same satellite higher than a threshold - //////////////////////////////////////////////////////// -#ifndef NDEBUG - std::vector::iterator it2; - double thr_ = 250.0 / SPEED_OF_LIGHT; // Maximum pseudorange difference = 250 meters - for (it = data.begin(); it != (data.end() - 1); it++) + // if (!T_rx_TOW_set) + // { + //uint32_t TOW_ref = std::numeric_limits::max(); + uint32_t TOW_ref = 0U; + for (it = data.begin(); it != data.end(); it++) { - for (it2 = it + 1; it2 != data.end(); it2++) - { - if (it->PRN == it2->PRN and it->System == it2->System) - { - double tow_dif_ = std::fabs(it->TOW_at_current_symbol_ms - it2->TOW_at_current_symbol_ms); - if (tow_dif_ > thr_ * 1000.0) - { - DLOG(INFO) << "System " << it->System << ". Signals " << it->Signal << " and " << it2->Signal - << ". TOW difference in PRN " << it->PRN - << " = " << tow_dif_ * 1e3 << "[ms]. Equivalent to " << tow_dif_ * SPEED_OF_LIGHT - << " meters in pseudorange"; - std::cout << TEXT_RED << "System " << it->System << ". Signals " << it->Signal << " and " << it2->Signal - << ". TOW difference in PRN " << it->PRN - << " = " << tow_dif_ * 1e3 << "[ms]. Equivalent to " << tow_dif_ * SPEED_OF_LIGHT - << " meters in pseudorange" << TEXT_RESET << std::endl; - } - } - } - } -#endif - - if (!T_rx_TOW_set) - { - unsigned int TOW_ref = std::numeric_limits::lowest(); - for (it = data.begin(); it != data.end(); it++) + if (it->Flag_valid_word) { if (it->TOW_at_current_symbol_ms > TOW_ref) { TOW_ref = it->TOW_at_current_symbol_ms; + T_rx_TOW_set = true; } } - T_rx_TOW_ms = TOW_ref; - T_rx_TOW_set = true; - } - else - { - T_rx_TOW_ms += T_rx_step_ms; - //todo: check what happens during the week rollover - if (T_rx_TOW_ms >= 604800000) - { - T_rx_TOW_ms = T_rx_TOW_ms % 604800000; - } } + T_rx_TOW_ms = TOW_ref; + //} + // else + // { + // T_rx_TOW_ms += T_rx_step_ms; + // //todo: check what happens during the week rollover + // if (T_rx_TOW_ms >= 604800000) + // { + // T_rx_TOW_ms = T_rx_TOW_ms % 604800000; + // } + // } + // std::cout << "T_rx_TOW_ms: " << T_rx_TOW_ms << std::endl; +} + + +void hybrid_observables_cc::compute_pranges(std::vector &data) +{ + std::vector::iterator it; for (it = data.begin(); it != data.end(); it++) { - double traveltime_s = (static_cast(T_rx_TOW_ms) - it->interp_TOW_ms + GPS_STARTOFFSET_ms) / 1000.0; - - //std::cout.precision(17); - //std::cout << "Diff T_rx_TOW_ms - interp_TOW_ms: " << static_cast(T_rx_TOW_ms) - it->interp_TOW_ms << std::endl; - - it->RX_time = (T_rx_TOW_ms + GPS_STARTOFFSET_ms) / 1000.0; - it->Pseudorange_m = traveltime_s * SPEED_OF_LIGHT; + if (it->Flag_valid_word) + { + double traveltime_s = (static_cast(T_rx_TOW_ms) - it->interp_TOW_ms + GPS_STARTOFFSET_ms) / 1000.0; + //todo: check what happens during the week rollover (TOW rollover at 604800000s) + it->RX_time = (static_cast(T_rx_TOW_ms) + GPS_STARTOFFSET_ms) / 1000.0; + it->Pseudorange_m = traveltime_s * SPEED_OF_LIGHT; + it->Flag_valid_pseudorange = true; + // debug code + // std::cout.precision(17); + // std::cout << "[" << it->Channel_ID << "] interp_TOW_ms: " << it->interp_TOW_ms << std::endl; + // std::cout << "[" << it->Channel_ID << "] Diff T_rx_TOW_ms - interp_TOW_ms: " << static_cast(T_rx_TOW_ms) - it->interp_TOW_ms << std::endl; + // std::cout << "[" << it->Channel_ID << "] Pseudorange_m: " << it->Pseudorange_m << std::endl; + } } + // usleep(1000); } @@ -480,156 +506,104 @@ int hybrid_observables_cc::general_work(int noutput_items __attribute__((unused) const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); Gnss_Synchro **out = reinterpret_cast(&output_items[0]); - unsigned int i; - unsigned int returned_elements = 0; - int total_input_items = 0; - for (i = 0; i < d_nchannels; i++) + // Push receiver clock into history buffer (connected to the last of the input channels) + // The clock buffer gives time to the channels to compute the tracking observables + if (ninput_items[d_nchannels_in - 1] > 0) { - total_input_items += ninput_items[i]; + d_Rx_clock_buffer.push_back(in[d_nchannels_in - 1][0].Tracking_sample_counter); + if (T_rx_clock_step_samples == 0) + { + T_rx_clock_step_samples = std::round(static_cast(in[d_nchannels_in - 1][0].fs) * 1e-3); // 1 ms + LOG(INFO) << "Observables clock step samples set to " << T_rx_clock_step_samples; + usleep(1000000); + } + + // Consume one item from the clock channel (last of the input channels) + consume(d_nchannels_in - 1, 1); } - for (int epoch = 0; epoch < ninput_items[d_nchannels]; epoch++) + + // Push the tracking observables into buffers to allow the observable interpolation at the desired Rx clock + for (uint32_t n = 0; n < d_nchannels_out; n++) { - T_rx_s += (static_cast(T_rx_step_ms) / 1000.0); - - ////////////////////////////////////////////////////////////////////////// - if ((total_input_items == 0) and (d_num_valid_channels == 0)) + // Push the valid tracking Gnss_Synchros to their corresponding deque + for (int32_t m = 0; m < ninput_items[n]; m++) { - consume(d_nchannels, epoch + 1); - return returned_elements; - } - ////////////////////////////////////////////////////////////////////////// - - if (total_input_items > 0 and epoch == 0) - { - for (i = 0; i < d_nchannels; i++) + if (in[n][m].Flag_valid_word) { - if (ninput_items[i] > 0) + if (d_gnss_synchro_history->size(n) > 0) { - // Add the new Gnss_Synchros to their corresponding deque - for (int aux = 0; aux < ninput_items[i]; aux++) + // Check if the last Gnss_Synchro comes from the same satellite as the previous ones + if (d_gnss_synchro_history->front(n).PRN != in[n][m].PRN) { - if (in[i][aux].Flag_valid_word) - { - d_gnss_synchro_history->push_back(i, in[i][aux]); - d_gnss_synchro_history->back(i).RX_time = compute_T_rx_s(in[i][aux]); - // Check if the last Gnss_Synchro comes from the same satellite as the previous ones - if (d_gnss_synchro_history->size(i) > 1) - { - if (d_gnss_synchro_history->front(i).PRN != d_gnss_synchro_history->back(i).PRN) - { - d_gnss_synchro_history->clear(i); - } - } - } + d_gnss_synchro_history->clear(n); } - consume(i, ninput_items[i]); } + d_gnss_synchro_history->push_back(n, in[n][m]); + d_gnss_synchro_history->back(n).RX_time = compute_T_rx_s(in[n][m]); } } + consume(n, ninput_items[n]); + } - for (i = 0; i < d_nchannels; i++) - { - if (d_gnss_synchro_history->size(i) > 2) - { - valid_channels[i] = true; - } - else - { - valid_channels[i] = false; - } - } - d_num_valid_channels = valid_channels.count(); - - // Check if there is any valid channel after reading the new incoming Gnss_Synchro data - if (d_num_valid_channels == 0) - { - consume(d_nchannels, epoch + 1); - return returned_elements; - } - - for (i = 0; i < d_nchannels; i++) // Discard observables with T_rx higher than the threshold - { - if (valid_channels[i]) - { - clean_history(i); - if (d_gnss_synchro_history->size(i) < 2) - { - valid_channels[i] = false; - } - } - } - - // Check if there is any valid channel after computing the time distance between the Gnss_Synchro data and the receiver time - d_num_valid_channels = valid_channels.count(); - double T_rx_s_out = T_rx_s - d_latency; - if ((d_num_valid_channels == 0) or (T_rx_s_out < 0.0)) - { - consume(d_nchannels, epoch + 1); - return returned_elements; - } - + if (d_Rx_clock_buffer.size() == d_Rx_clock_buffer.capacity()) + { std::vector epoch_data; - for (i = 0; i < d_nchannels; i++) + int32_t n_valid = 0; + for (uint32_t n = 0; n < d_nchannels_out; n++) { - if (valid_channels[i]) + Gnss_Synchro interpolated_gnss_synchro; + if (!interp_trk_obs(interpolated_gnss_synchro, n, d_Rx_clock_buffer.front() + T_rx_TOW_offset_ms * T_rx_clock_step_samples)) { - Gnss_Synchro interpolated_gnss_synchro; // empty set, it is required to COPY the nearest in the interpolation history = d_gnss_synchro_history->back(i); - if (interpolate_data(interpolated_gnss_synchro, i, T_rx_s_out)) - { - epoch_data.push_back(interpolated_gnss_synchro); - } - else - { - valid_channels[i] = false; - } - } - } - d_num_valid_channels = valid_channels.count(); - - if (d_num_valid_channels == 0) - { - consume(d_nchannels, epoch + 1); - return returned_elements; - } - - correct_TOW_and_compute_prange(epoch_data); - std::vector::iterator it = epoch_data.begin(); - for (i = 0; i < d_nchannels; i++) - { - if (valid_channels[i]) - { - out[i][epoch] = (*it); - out[i][epoch].Flag_valid_pseudorange = true; - it++; + // Produce an empty observation + interpolated_gnss_synchro = Gnss_Synchro(); + interpolated_gnss_synchro.Flag_valid_pseudorange = false; + interpolated_gnss_synchro.Flag_valid_word = false; + interpolated_gnss_synchro.Flag_valid_acquisition = false; + interpolated_gnss_synchro.fs = 0; + interpolated_gnss_synchro.Channel_ID = n; } else { - out[i][epoch] = Gnss_Synchro(); - out[i][epoch].Flag_valid_pseudorange = false; + n_valid++; + } + epoch_data.push_back(interpolated_gnss_synchro); + } + if (n_valid > 0) + { + update_TOW(epoch_data); + if (T_rx_TOW_ms % 20 != 0) + { + T_rx_TOW_offset_ms = T_rx_TOW_ms % 20; } } + if (n_valid > 0) compute_pranges(epoch_data); + + for (uint32_t n = 0; n < d_nchannels_out; n++) + { + out[n][0] = epoch_data.at(n); + } if (d_dump) { // MULTIPLEXED FILE RECORDING - Record results to file try { double tmp_double; - for (i = 0; i < d_nchannels; i++) + for (uint32_t i = 0; i < d_nchannels_out; i++) { - tmp_double = out[i][epoch].RX_time; + tmp_double = out[i][0].RX_time; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = out[i][epoch].interp_TOW_ms / 1000.0; + tmp_double = out[i][0].interp_TOW_ms / 1000.0; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = out[i][epoch].Carrier_Doppler_hz; + tmp_double = out[i][0].Carrier_Doppler_hz; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = out[i][epoch].Carrier_phase_rads / GPS_TWO_PI; + tmp_double = out[i][0].Carrier_phase_rads / GPS_TWO_PI; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = out[i][epoch].Pseudorange_m; + tmp_double = out[i][0].Pseudorange_m; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = static_cast(out[i][epoch].PRN); + tmp_double = static_cast(out[i][0].PRN); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_double = static_cast(out[i][epoch].Flag_valid_pseudorange); + tmp_double = static_cast(out[i][0].Flag_valid_pseudorange); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); } } @@ -639,9 +613,10 @@ int hybrid_observables_cc::general_work(int noutput_items __attribute__((unused) d_dump = false; } } - - returned_elements++; + return 1; + } + else + { + return 0; } - consume(d_nchannels, ninput_items[d_nchannels]); - return returned_elements; } diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h index c2008ceaf..033da7a25 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_cc.h @@ -48,7 +48,7 @@ class hybrid_observables_cc; typedef boost::shared_ptr hybrid_observables_cc_sptr; hybrid_observables_cc_sptr -hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, std::string dump_filename); +hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, bool dump_mat, std::string dump_filename); /*! * \brief This class implements a block that computes observables @@ -63,28 +63,28 @@ public: private: friend hybrid_observables_cc_sptr - hybrid_make_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, std::string dump_filename); - hybrid_observables_cc(unsigned int nchannels_in, unsigned int nchannels_out, bool dump, std::string dump_filename); - void clean_history(unsigned int pos); + hybrid_make_observables_cc(uint32_t nchannels_in, uint32_t nchannels_out, bool dump, bool dump_mat, std::string dump_filename); + hybrid_observables_cc(uint32_t nchannels_in, uint32_t nchannels_out, bool dump, bool dump_mat, std::string dump_filename); + bool interpolate_data(Gnss_Synchro& out, const uint32_t& ch, const double& ti); + bool interp_trk_obs(Gnss_Synchro& interpolated_obs, const uint32_t& ch, const uint64_t& rx_clock); double compute_T_rx_s(const Gnss_Synchro& a); - bool interpolate_data(Gnss_Synchro& out, const unsigned int& ch, const double& ti); - void find_interp_elements(const unsigned int& ch, const double& ti); - void correct_TOW_and_compute_prange(std::vector& data); - int save_matfile(); + void compute_pranges(std::vector& data); + void update_TOW(std::vector& data); + int32_t save_matfile(); + //time history + boost::circular_buffer d_Rx_clock_buffer; //Tracking observable history Gnss_circular_deque* d_gnss_synchro_history; - boost::dynamic_bitset<> valid_channels; - double T_rx_s; - unsigned int T_rx_step_ms; + uint32_t T_rx_clock_step_samples; //rx time follow GPST bool T_rx_TOW_set; - unsigned int T_rx_TOW_ms; - double max_delta; - double d_latency; + uint32_t T_rx_TOW_ms; + uint32_t T_rx_TOW_offset_ms; bool d_dump; - unsigned int d_nchannels; - unsigned int d_num_valid_channels; + bool d_dump_mat; + uint32_t d_nchannels_in; + uint32_t d_nchannels_out; std::string d_dump_filename; std::ofstream d_dump_file; }; diff --git a/src/algorithms/resampler/CMakeLists.txt b/src/algorithms/resampler/CMakeLists.txt index 64cb2a571..1841d3dfc 100644 --- a/src/algorithms/resampler/CMakeLists.txt +++ b/src/algorithms/resampler/CMakeLists.txt @@ -17,4 +17,4 @@ # add_subdirectory(adapters) -add_subdirectory(gnuradio_blocks) \ No newline at end of file +add_subdirectory(gnuradio_blocks) diff --git a/src/algorithms/resampler/adapters/CMakeLists.txt b/src/algorithms/resampler/adapters/CMakeLists.txt index 886ad5487..07e8ddc74 100644 --- a/src/algorithms/resampler/adapters/CMakeLists.txt +++ b/src/algorithms/resampler/adapters/CMakeLists.txt @@ -16,29 +16,39 @@ # along with GNSS-SDR. If not, see . # + set(RESAMPLER_ADAPTER_SOURCES - direct_resampler_conditioner.cc - mmse_resampler_conditioner.cc + direct_resampler_conditioner.cc + mmse_resampler_conditioner.cc +) + +set(RESAMPLER_ADAPTER_HEADERS + direct_resampler_conditioner.h + mmse_resampler_conditioner.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/algorithms/resampler/gnuradio_blocks - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${VOLK_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/algorithms/resampler/gnuradio_blocks + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_INCLUDE_DIRS} ) +if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.13.4") + add_definitions(-DGR_GREATER_38=1) +endif() -if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.15" ) - add_definitions( -DGR_GREATER_38=1 ) -endif(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.15" ) - - -file(GLOB RESAMPLER_ADAPTER_HEADERS "*.h") list(SORT RESAMPLER_ADAPTER_HEADERS) -add_library(resampler_adapters ${RESAMPLER_ADAPTER_SOURCES} ${RESAMPLER_ADAPTER_HEADERS}) +list(SORT RESAMPLER_ADAPTER_SOURCES) + +add_library(resampler_adapters + ${RESAMPLER_ADAPTER_SOURCES} + ${RESAMPLER_ADAPTER_HEADERS} +) + source_group(Headers FILES ${RESAMPLER_ADAPTER_HEADERS}) + target_link_libraries(resampler_adapters resampler_gr_blocks) diff --git a/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc b/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc index 696ccefea..c59179534 100644 --- a/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc +++ b/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc @@ -63,6 +63,17 @@ MmseResamplerConditioner::MmseResamplerConditioner( if (item_type_.compare("gr_complex") == 0) { item_size_ = sizeof(gr_complex); + + + //create a FIR low pass filter + std::vector taps = gr::filter::firdes::low_pass(1.0, + sample_freq_in_, + sample_freq_out_ / 2.1, + sample_freq_out_ / 10, + gr::filter::firdes::win_type::WIN_HAMMING); + std::cout << "Enabled fractional resampler low pass filter with " << taps.size() << " taps" << std::endl; + fir_filter_ccf_ = gr::filter::fir_filter_ccf::make(1, taps); + #ifdef GR_GREATER_38 resampler_ = gr::filter::mmse_resampler_cc::make(0.0, sample_freq_in_ / sample_freq_out_); #else @@ -96,18 +107,17 @@ MmseResamplerConditioner::MmseResamplerConditioner( MmseResamplerConditioner::~MmseResamplerConditioner() {} - - void MmseResamplerConditioner::connect(gr::top_block_sptr top_block) { if (dump_) { + top_block->connect(fir_filter_ccf_, 0, resampler_, 0); top_block->connect(resampler_, 0, file_sink_, 0); DLOG(INFO) << "connected resampler to file sink"; } else { - DLOG(INFO) << "nothing to connect internally"; + top_block->connect(fir_filter_ccf_, 0, resampler_, 0); } } @@ -116,14 +126,19 @@ void MmseResamplerConditioner::disconnect(gr::top_block_sptr top_block) { if (dump_) { + top_block->disconnect(fir_filter_ccf_, 0, resampler_, 0); top_block->disconnect(resampler_, 0, file_sink_, 0); } + else + { + top_block->disconnect(fir_filter_ccf_, 0, resampler_, 0); + } } gr::basic_block_sptr MmseResamplerConditioner::get_left_block() { - return resampler_; + return fir_filter_ccf_; } diff --git a/src/algorithms/resampler/adapters/mmse_resampler_conditioner.h b/src/algorithms/resampler/adapters/mmse_resampler_conditioner.h index b5c20c846..462e49e88 100644 --- a/src/algorithms/resampler/adapters/mmse_resampler_conditioner.h +++ b/src/algorithms/resampler/adapters/mmse_resampler_conditioner.h @@ -36,9 +36,13 @@ #include "gnss_block_interface.h" #ifdef GR_GREATER_38 #include +#include #else #include +#include #endif + +#include #include class ConfigurationInterface; @@ -91,6 +95,7 @@ private: #else gr::filter::fractional_resampler_cc::sptr resampler_; #endif + gr::filter::fir_filter_ccf::sptr fir_filter_ccf_; gr::block_sptr file_sink_; }; diff --git a/src/algorithms/resampler/gnuradio_blocks/CMakeLists.txt b/src/algorithms/resampler/gnuradio_blocks/CMakeLists.txt index 70db5015e..ae570d644 100644 --- a/src/algorithms/resampler/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/resampler/gnuradio_blocks/CMakeLists.txt @@ -17,22 +17,34 @@ # -set(RESAMPLER_GR_BLOCKS_SOURCES - direct_resampler_conditioner_cc.cc - direct_resampler_conditioner_cs.cc - direct_resampler_conditioner_cb.cc +set(RESAMPLER_GR_BLOCKS_SOURCES + direct_resampler_conditioner_cc.cc + direct_resampler_conditioner_cs.cc + direct_resampler_conditioner_cb.cc +) + +set(RESAMPLER_GR_BLOCKS_HEADERS + direct_resampler_conditioner_cc.h + direct_resampler_conditioner_cs.h + direct_resampler_conditioner_cb.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${VOLK_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_INCLUDE_DIRS} ) -file(GLOB RESAMPLER_GR_BLOCKS_HEADERS "*.h") list(SORT RESAMPLER_GR_BLOCKS_HEADERS) -add_library(resampler_gr_blocks ${RESAMPLER_GR_BLOCKS_SOURCES} ${RESAMPLER_GR_BLOCKS_HEADERS}) +list(SORT RESAMPLER_GR_BLOCKS_SOURCES) + +add_library(resampler_gr_blocks + ${RESAMPLER_GR_BLOCKS_SOURCES} + ${RESAMPLER_GR_BLOCKS_HEADERS} +) + source_group(Headers FILES ${RESAMPLER_GR_BLOCKS_HEADERS}) -add_dependencies(resampler_gr_blocks glog-${glog_RELEASE}) \ No newline at end of file + +add_dependencies(resampler_gr_blocks glog-${glog_RELEASE}) diff --git a/src/algorithms/signal_generator/adapters/CMakeLists.txt b/src/algorithms/signal_generator/adapters/CMakeLists.txt index 3d141ddb3..fe793203b 100644 --- a/src/algorithms/signal_generator/adapters/CMakeLists.txt +++ b/src/algorithms/signal_generator/adapters/CMakeLists.txt @@ -17,26 +17,31 @@ # set(SIGNAL_GENERATOR_ADAPTER_SOURCES signal_generator.cc) +set(SIGNAL_GENERATOR_ADAPTER_HEADERS signal_generator.h) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/signal_generator/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/signal_generator/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} ) -file(GLOB SIGNAL_GENERATOR_ADAPTER_HEADERS "*.h") -list(SORT SIGNAL_GENERATOR_ADAPTER_HEADERS) -add_library(signal_generator_adapters ${SIGNAL_GENERATOR_ADAPTER_SOURCES} ${SIGNAL_GENERATOR_ADAPTER_HEADERS}) -source_group(Headers FILES ${SIGNAL_GENERATOR_ADAPTER_HEADERS}) -target_link_libraries(signal_generator_adapters gnss_sp_libs - signal_generator_blocks - ${GNURADIO_RUNTIME_LIBRARIES} - ${GNURADIO_BLOCKS_LIBRARIES} - ${GNURADIO_FILTER_LIBRARIES} +add_library(signal_generator_adapters + ${SIGNAL_GENERATOR_ADAPTER_SOURCES} + ${SIGNAL_GENERATOR_ADAPTER_HEADERS} +) + +source_group(Headers FILES ${SIGNAL_GENERATOR_ADAPTER_HEADERS}) + +target_link_libraries(signal_generator_adapters + gnss_sp_libs + signal_generator_blocks + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${GNURADIO_FILTER_LIBRARIES} ) diff --git a/src/algorithms/signal_generator/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_generator/gnuradio_blocks/CMakeLists.txt index 55e2e9bd6..30ab655e1 100644 --- a/src/algorithms/signal_generator/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_generator/gnuradio_blocks/CMakeLists.txt @@ -17,31 +17,38 @@ # set(SIGNAL_GENERATOR_BLOCK_SOURCES signal_generator_c.cc) +set(SIGNAL_GENERATOR_BLOCK_HEADERS signal_generator_c.h) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${VOLK_GNSSSDR_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_GNSSSDR_INCLUDE_DIRS} +) + +add_library(signal_generator_blocks + ${SIGNAL_GENERATOR_BLOCK_SOURCES} + ${SIGNAL_GENERATOR_BLOCK_HEADERS} ) -file(GLOB SIGNAL_GENERATOR_BLOCK_HEADERS "*.h") -list(SORT SIGNAL_GENERATOR_BLOCK_HEADERS) -add_library(signal_generator_blocks ${SIGNAL_GENERATOR_BLOCK_SOURCES} ${SIGNAL_GENERATOR_BLOCK_HEADERS}) source_group(Headers FILES ${SIGNAL_GENERATOR_BLOCK_HEADERS}) -target_link_libraries(signal_generator_blocks gnss_system_parameters gnss_sp_libs - ${GNURADIO_RUNTIME_LIBRARIES} - ${GNURADIO_FFT_LIBRARIES} - ${VOLK_GNSSSDR_LIBRARIES} ${ORC_LIBRARIES} + +target_link_libraries(signal_generator_blocks + gnss_system_parameters + gnss_sp_libs + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_FFT_LIBRARIES} + ${VOLK_GNSSSDR_LIBRARIES} + ${ORC_LIBRARIES} ) -if(VOLK_GNSSSDR_FOUND) +if(VOLKGNSSSDR_FOUND) # add_dependencies(signal_generator_blocks glog-${glog_RELEASE}) -else(VOLK_GNSSSDR_FOUND) +else() add_dependencies(signal_generator_blocks volk_gnsssdr_module) -endif() \ No newline at end of file +endif() diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index 4ee93a535..6674cd853 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -16,8 +16,6 @@ # along with GNSS-SDR. If not, see . # -file(GLOB SIGNAL_SOURCE_ADAPTER_HEADERS "*.h") -list(SORT SIGNAL_SOURCE_ADAPTER_HEADERS) # Optional drivers @@ -25,29 +23,30 @@ if(ENABLE_RAW_UDP) find_package(PCAP) if(NOT PCAP_FOUND) message(FATAL_ERROR "PCAP required to compile custom UDP packet sample source (ENABLE_RAW_UDP)") - endif(NOT PCAP_FOUND) + endif() get_filename_component(PCAP_LIBRARY_DIRS ${PCAP_LIBRARY} DIRECTORY CACHE) set(OPT_LIBRARIES ${OPT_LIBRARIES} ${PCAP_LIBRARIES}) set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${PCAP_INCLUDE_DIRS}) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} custom_udp_signal_source.cc) -endif(ENABLE_RAW_UDP) + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} custom_udp_signal_source.h) +endif() if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) - find_package(Griio REQUIRED) - if(NOT IIO_FOUND) + find_package(GRIIO REQUIRED) + if(NOT GRIIO_FOUND) message(STATUS "gnuradio-iio not found, its installation is required.") message(STATUS "Please build and install the following projects:") message(STATUS " * libiio from https://github.com/analogdevicesinc/libiio") message(STATUS " * libad9361-iio from https://github.com/analogdevicesinc/libad9361-iio") message(STATUS " * gnuradio-iio from https://github.com/analogdevicesinc/gr-iio") message(FATAL_ERROR "gnuradio-iio is required for building gnss-sdr with this option enabled.") - endif(NOT IIO_FOUND) + endif() set(OPT_LIBRARIES ${OPT_LIBRARIES} ${IIO_LIBRARIES}) set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) -endif(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) +endif() if(ENABLE_AD9361) - find_package(libiio REQUIRED) + find_package(LIBIIO REQUIRED) if(NOT LIBIIO_FOUND) message(STATUS "libiio not found, its installation is required.") message(STATUS "Please build and install the following projects:") @@ -55,30 +54,33 @@ if(ENABLE_AD9361) message(STATUS " * libad9361-iio from https://github.com/analogdevicesinc/libad9361-iio") message(STATUS " * gnuradio-iio from https://github.com/analogdevicesinc/gr-iio") message(FATAL_ERROR "libiio is required for building gnss-sdr with this option enabled.") - endif(NOT LIBIIO_FOUND) + endif() set(OPT_LIBRARIES ${OPT_LIBRARIES} ${LIBIIO_LIBRARIES}) set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${LIBIIO_INCLUDE_DIRS}) -endif(ENABLE_AD9361) +endif() if(ENABLE_PLUTOSDR) ############################################## # ADALM-PLUTO (Analog Devices Inc.) ############################################## - if(IIO_FOUND) + if(GRIIO_FOUND) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} plutosdr_signal_source.cc) - endif(IIO_FOUND) -endif(ENABLE_PLUTOSDR) + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} plutosdr_signal_source.h) + endif() +endif() if(ENABLE_FMCOMMS2) ############################################### # FMCOMMS2 based SDR Hardware ############################################### - if(IIO_FOUND) + if(GRIIO_FOUND) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} fmcomms2_signal_source.cc) - endif(IIO_FOUND) -endif(ENABLE_FMCOMMS2) + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} fmcomms2_signal_source.h) + endif() +endif() + if(ENABLE_AD9361) ############################################### @@ -86,59 +88,61 @@ if(ENABLE_AD9361) ############################################### if(LIBIIO_FOUND) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} ad9361_fpga_signal_source.cc) - endif(LIBIIO_FOUND) -endif(ENABLE_AD9361) - + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ad9361_fpga_signal_source.h) + endif() +endif() if(ENABLE_GN3S) - ############################################## - # GN3S (USB dongle) - ############################################## - find_package(GrGN3S REQUIRED) - if(NOT GR_GN3S_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(NOT GR_GN3S_FOUND) - set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GR_GN3S_LIBRARIES}) - set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${GR_GN3S_INCLUDE_DIRS}) - set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} gn3s_signal_source.cc) -endif(ENABLE_GN3S) + ############################################## + # GN3S (USB dongle) + ############################################## + find_package(GRGN3S REQUIRED) + 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_LIBRARIES ${OPT_LIBRARIES} ${GR_GN3S_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${GR_GN3S_INCLUDE_DIRS}) + 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) - ############################################## - # TELEORBIT FLEXIBAND FRONTEND ADAPTER - ############################################## - find_package(Teleorbit REQUIRED) - if(NOT TELEORBIT_FOUND) - message(FATAL_ERROR "Teleorbit Flexiband GNU Radio driver required to build gnss-sdr with the optional FLEXIBAND adapter") - endif(NOT TELEORBIT_FOUND) - - # Set up variables - set(FLEXIBAND_DRIVER_INCLUDE_DIRS - ${OPT_DRIVER_INCLUDE_DIRS} - ${TELEORBIT_INCLUDE_DIR}/teleorbit - ) - set(OPT_LIBRARIES ${OPT_LIBRARIES} ${TELEORBIT_LIBRARIES}) - set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${FLEXIBAND_DRIVER_INCLUDE_DIRS}) - set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} flexiband_signal_source.cc) -endif(ENABLE_FLEXIBAND) + ############################################## + # TELEORBIT FLEXIBAND FRONTEND ADAPTER + ############################################## + find_package(TELEORBIT REQUIRED) + if(NOT TELEORBIT_FOUND) + message(FATAL_ERROR "Teleorbit Flexiband GNU Radio driver required to build gnss-sdr with the optional FLEXIBAND adapter") + endif() + # Set up variables + set(FLEXIBAND_DRIVER_INCLUDE_DIRS + ${OPT_DRIVER_INCLUDE_DIRS} + ${TELEORBIT_INCLUDE_DIR}/teleorbit + ) + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${TELEORBIT_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${FLEXIBAND_DRIVER_INCLUDE_DIRS}) + set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} flexiband_signal_source.cc) + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} flexiband_signal_source.h) +endif() if(ENABLE_ARRAY) - ############################################## - # DBFCTTC GNSS EXPERIMENTAL ARRAY PROTOTYPE - ############################################## - find_package(GrDbfcttc REQUIRED) - if(NOT GR_DBFCTTC_FOUND) - message(" gr-dbfcttc not found, install it from https://github.com/gnss-sdr/gr-dbfcttc ") - message(FATAL_ERROR "gr-dbfcttc required for building gnss-sdr with this option enabled") - endif(NOT GR_DBFCTTC_FOUND) - set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GR_DBFCTTC_LIBRARIES}) - set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${GR_DBFCTTC_INCLUDE_DIRS}) - set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} raw_array_signal_source.cc) -endif(ENABLE_ARRAY) + ############################################## + # DBFCTTC GNSS EXPERIMENTAL ARRAY PROTOTYPE + ############################################## + find_package(GRDBFCTTC REQUIRED) + if(NOT GRDBFCTTC_FOUND) + message(" gr-dbfcttc not found, install it from https://github.com/gnss-sdr/gr-dbfcttc ") + message(FATAL_ERROR "gr-dbfcttc required for building gnss-sdr with this option enabled") + endif() + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GR_DBFCTTC_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${GR_DBFCTTC_INCLUDE_DIRS}) + set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} raw_array_signal_source.cc) + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} raw_array_signal_source.h) +endif() if(ENABLE_OSMOSDR) @@ -148,71 +152,91 @@ if(ENABLE_OSMOSDR) if(NOT GROSMOSDR_FOUND) if(ENABLE_PACKAGING) list(REMOVE_ITEM SIGNAL_SOURCE_ADAPTER_HEADERS ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/adapters/osmosdr_signal_source.h) - endif(ENABLE_PACKAGING) - else(NOT GROSMOSDR_FOUND) + endif() + else() # set OSMO include dirs set(OSMO_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${GROSMOSDR_INCLUDE_DIR}/osmosdr - ) + ) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} osmosdr_signal_source.cc) + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} osmosdr_signal_source.h) set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GROSMOSDR_LIBRARIES}) set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${OSMO_DRIVER_INCLUDE_DIRS}) - endif(NOT GROSMOSDR_FOUND) -endif(ENABLE_OSMOSDR) + endif() +endif() + if(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} uhd_signal_source.cc) + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} uhd_signal_source.h) set(OPT_LIBRARIES ${OPT_LIBRARIES} ${UHD_LIBRARIES} ${GNURADIO_UHD_LIBRARIES}) set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${UHD_INCLUDE_DIRS}) -else(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd) - list(REMOVE_ITEM SIGNAL_SOURCE_ADAPTER_HEADERS ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/adapters/uhd_signal_source.h) -endif(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd) +endif() -set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc - gen_signal_source.cc - nsr_file_signal_source.cc - spir_file_signal_source.cc - spir_gss6450_file_signal_source.cc - rtl_tcp_signal_source.cc - labsat_signal_source.cc - ${OPT_DRIVER_SOURCES} +set(SIGNAL_SOURCE_ADAPTER_SOURCES + file_signal_source.cc + gen_signal_source.cc + nsr_file_signal_source.cc + spir_file_signal_source.cc + spir_gss6450_file_signal_source.cc + rtl_tcp_signal_source.cc + labsat_signal_source.cc + ${OPT_DRIVER_SOURCES} ) +set(SIGNAL_SOURCE_ADAPTER_HEADERS + file_signal_source.h + gen_signal_source.h + nsr_file_signal_source.h + spir_file_signal_source.h + spir_gss6450_file_signal_source.h + rtl_tcp_signal_source.h + labsat_signal_source.h + ${OPT_DRIVER_HEADERS} +) + + if(PC_GNURADIO_RUNTIME_VERSION VERSION_GREATER 3.7.3) - set(SIGNAL_SOURCE_ADAPTER_SOURCES ${SIGNAL_SOURCE_ADAPTER_SOURCES} - two_bit_cpx_file_signal_source.cc - two_bit_packed_file_signal_source.cc ) -endif(PC_GNURADIO_RUNTIME_VERSION VERSION_GREATER 3.7.3) + set(SIGNAL_SOURCE_ADAPTER_SOURCES ${SIGNAL_SOURCE_ADAPTER_SOURCES} + two_bit_cpx_file_signal_source.cc + two_bit_packed_file_signal_source.cc) + set(SIGNAL_SOURCE_ADAPTER_HEADERS ${SIGNAL_SOURCE_ADAPTER_HEADERS} + two_bit_cpx_file_signal_source.h + two_bit_packed_file_signal_source.h) +endif() include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${OPT_DRIVER_INCLUDE_DIRS} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/gnuradio_blocks - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${VOLK_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${OPT_DRIVER_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/gnuradio_blocks + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_INCLUDE_DIRS} ) if(ARCH_64BITS) add_definitions(-DARCH_64BITS=1) -endif(ARCH_64BITS) +endif() add_definitions(-DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}") +list(SORT SIGNAL_SOURCE_ADAPTER_HEADERS) +list(SORT SIGNAL_SOURCE_ADAPTER_SOURCES) + add_library(signal_source_adapters ${SIGNAL_SOURCE_ADAPTER_SOURCES} ${SIGNAL_SOURCE_ADAPTER_HEADERS}) source_group(Headers FILES ${SIGNAL_SOURCE_ADAPTER_HEADERS}) target_link_libraries(signal_source_adapters signal_source_gr_blocks - ${Boost_LIBRARIES} - ${GNURADIO_PMT_LIBRARIES} - ${GNURADIO_BLOCKS_LIBRARIES} - ${OPT_LIBRARIES} - gnss_sp_libs + ${Boost_LIBRARIES} + ${GNURADIO_PMT_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${OPT_LIBRARIES} + gnss_sp_libs ) diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h index 5fee04b1a..89fd50449 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h @@ -36,6 +36,7 @@ #include "fpga_switch.h" #include #include +#include #include class ConfigurationInterface; @@ -76,11 +77,11 @@ private: std::string role_; // Front-end settings - std::string uri_; // device direction - unsigned long freq_; // frequency of local oscillator - unsigned long sample_rate_; - unsigned long bandwidth_; - unsigned long buffer_size_; // reception buffer + std::string uri_; // device direction + uint64_t freq_; // frequency of local oscillator + uint64_t sample_rate_; + uint64_t bandwidth_; + uint64_t buffer_size_; // reception buffer bool rx1_en_; bool rx2_en_; bool quadrature_; @@ -96,14 +97,14 @@ private: // DDS configuration for LO generation for external mixer bool enable_dds_lo_; - unsigned long freq_rf_tx_hz_; - unsigned long freq_dds_tx_hz_; + uint64_t freq_rf_tx_hz_; + uint64_t freq_dds_tx_hz_; double scale_dds_dbfs_; double phase_dds_deg_; double tx_attenuation_db_; - unsigned int in_stream_; - unsigned int out_stream_; + uint32_t in_stream_; + uint32_t out_stream_; std::string item_type_; size_t item_size_; diff --git a/src/algorithms/signal_source/adapters/file_signal_source.cc b/src/algorithms/signal_source/adapters/file_signal_source.cc index c20f85664..8efaf2b09 100644 --- a/src/algorithms/signal_source/adapters/file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/file_signal_source.cc @@ -70,7 +70,7 @@ FileSignalSource::FileSignalSource(ConfigurationInterface* configuration, double seconds_to_skip = configuration->property(role + ".seconds_to_skip", default_seconds_to_skip); header_size = configuration->property(role + ".header_size", 0); - long samples_to_skip = 0; + int64_t samples_to_skip = 0; bool is_complex = false; @@ -112,7 +112,7 @@ FileSignalSource::FileSignalSource(ConfigurationInterface* configuration, if (seconds_to_skip > 0) { - samples_to_skip = static_cast(seconds_to_skip * sampling_frequency_); + samples_to_skip = static_cast(seconds_to_skip * sampling_frequency_); if (is_complex) { @@ -200,8 +200,8 @@ FileSignalSource::FileSignalSource(ConfigurationInterface* configuration, if (size > 0) { - long bytes_to_skip = samples_to_skip * item_size_; - long bytes_to_process = static_cast(size) - bytes_to_skip; + int64_t bytes_to_skip = samples_to_skip * item_size_; + int64_t bytes_to_process = static_cast(size) - bytes_to_skip; samples_ = floor(static_cast(bytes_to_process) / static_cast(item_size()) - ceil(0.002 * static_cast(sampling_frequency_))); //process all the samples available in the file excluding at least the last 1 ms } } diff --git a/src/algorithms/signal_source/adapters/file_signal_source.h b/src/algorithms/signal_source/adapters/file_signal_source.h index 97fda6ddf..4e1347e31 100644 --- a/src/algorithms/signal_source/adapters/file_signal_source.h +++ b/src/algorithms/signal_source/adapters/file_signal_source.h @@ -41,6 +41,7 @@ #include #include #include +#include #include class ConfigurationInterface; @@ -107,7 +108,7 @@ public: } private: - unsigned long long samples_; + uint64_t samples_; long sampling_frequency_; std::string filename_; std::string item_type_; @@ -115,8 +116,8 @@ private: bool dump_; std::string dump_filename_; std::string role_; - unsigned int in_streams_; - unsigned int out_streams_; + uint32_t in_streams_; + uint32_t out_streams_; gr::blocks::file_source::sptr file_source_; boost::shared_ptr valve_; gr::blocks::file_sink::sptr sink_; diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc index 758f3ff7b..874cbe2f8 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -42,7 +42,7 @@ using google::LogMessage; SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* configuration, - std::string role, unsigned int in_streams, unsigned int out_streams, gr::msg_queue::sptr queue) : role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue) + std::string role, uint32_t in_streams, uint32_t out_streams, gr::msg_queue::sptr queue) : role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue) { std::string default_filename = "../data/my_capture.dat"; std::string default_dump_filename = "../data/my_capture_dump.dat"; @@ -59,8 +59,8 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* adc_bits_ = configuration->property(role + ".adc_bits", 4); n_channels_ = configuration->property(role + ".total_channels", 1); sel_ch_ = configuration->property(role + ".sel_ch", 1); - item_size_ = sizeof(int); - long bytes_seek = configuration->property(role + ".bytes_to_skip", 65536); + item_size_ = sizeof(int32_t); + int64_t bytes_seek = configuration->property(role + ".bytes_to_skip", 65536); double sample_size_byte = static_cast(adc_bits_) / 4.0; if (sel_ch_ > n_channels_) @@ -69,17 +69,22 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* } if (n_channels_ > 1) { - for (unsigned int i = 0; i < (n_channels_ - 1); i++) + for (uint32_t i = 0; i < n_channels_; i++) { - null_sinks_.push_back(gr::blocks::null_sink::make(item_size_)); + null_sinks_.push_back(gr::blocks::null_sink::make(sizeof(gr_complex))); + unpack_spir_vec_.push_back(make_unpack_spir_gss6450_samples(adc_bits_)); + if (endian_swap_) + { + endian_vec_.push_back(gr::blocks::endian_swap::make(item_size_)); + } } - DLOG(INFO) << "NUMBER OF NULL SINKS = " << null_sinks_.size(); } try { file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_); file_source_->seek(bytes_seek / item_size_, SEEK_SET); - unpack_spir_ = make_unpack_spir_gss6450_samples(adc_bits_); + + deint_ = gr::blocks::deinterleave::make(item_size_); } catch (const std::exception& e) @@ -133,8 +138,8 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* if (size > 0) { - samples_ = static_cast(floor(static_cast(static_cast(size) - static_cast(bytes_seek)) / (sample_size_byte * static_cast(n_channels_)))); - samples_ = samples_ - static_cast(ceil(0.002 * sampling_frequency_)); //process all the samples available in the file excluding the last 2 ms + samples_ = static_cast(floor(static_cast(static_cast(size) - static_cast(bytes_seek)) / (sample_size_byte * static_cast(n_channels_)))); + samples_ = samples_ - static_cast(ceil(0.002 * sampling_frequency_)); //process all the samples available in the file excluding the last 2 ms } } @@ -143,22 +148,20 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* LOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]" << std::endl; - valve_ = gnss_sdr_make_valve(sizeof(gr_complex), samples_, queue_); - DLOG(INFO) << "valve(" << valve_->unique_id() << ")"; + for (uint32_t i = 0; i < (n_channels_); i++) + { + valve_vec_.push_back(gnss_sdr_make_valve(sizeof(gr_complex), samples_, queue_)); + if (dump_) + { + std::string tmp_str = dump_filename_ + "_ch" + std::to_string(i); + sink_vec_.push_back(gr::blocks::file_sink::make(sizeof(gr_complex), tmp_str.c_str())); + } + if (enable_throttle_control_) + { + throttle_vec_.push_back(gr::blocks::throttle::make(sizeof(gr_complex), sampling_frequency_)); + } + } - if (dump_) - { - sink_ = gr::blocks::file_sink::make(sizeof(gr_complex), dump_filename_.c_str()); - DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")"; - } - if (enable_throttle_control_) - { - throttle_ = gr::blocks::throttle::make(sizeof(gr_complex), sampling_frequency_); - } - if (endian_swap_) - { - endian_ = gr::blocks::endian_swap::make(item_size_); - } DLOG(INFO) << "File source filename " << filename_; DLOG(INFO) << "Samples " << samples_; DLOG(INFO) << "Sampling frequency " << sampling_frequency_; @@ -188,39 +191,55 @@ void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) if (samples_ > 0) { top_block->connect(file_source_, 0, deint_, 0); + if (endian_swap_) { - top_block->connect(deint_, sel_ch_ - 1, endian_, 0); - top_block->connect(endian_, 0, unpack_spir_, 0); + top_block->connect(deint_, sel_ch_ - 1, endian_vec_.at(sel_ch_ - 1), 0); + top_block->connect(endian_vec_.at(sel_ch_ - 1), 0, unpack_spir_vec_.at(sel_ch_ - 1), 0); } else { - top_block->connect(deint_, sel_ch_ - 1, unpack_spir_, 0); + top_block->connect(deint_, sel_ch_ - 1, unpack_spir_vec_.at(sel_ch_ - 1), 0); } + if (n_channels_ > 1) { - unsigned int aux = 0; - for (unsigned int i = 0; i < n_channels_; i++) + uint32_t aux = 0; + for (uint32_t i = 0; i < n_channels_; i++) { if (i != (sel_ch_ - 1)) { - top_block->connect(deint_, i, null_sinks_.at(aux), 0); + if (endian_swap_) + { + top_block->connect(deint_, i, endian_vec_.at(i), 0); + top_block->connect(endian_vec_.at(i), 0, unpack_spir_vec_.at(i), 0); + } + else + { + top_block->connect(deint_, i, unpack_spir_vec_.at(i), 0); + } + aux++; } } } - if (enable_throttle_control_) + for (uint32_t i = 0; i < n_channels_; i++) { - top_block->connect(unpack_spir_, 0, throttle_, 0); - top_block->connect(throttle_, 0, valve_, 0); - } - else - { - top_block->connect(unpack_spir_, 0, valve_, 0); - } - if (dump_) - { - top_block->connect(valve_, 0, sink_, 0); + if (enable_throttle_control_) + { + top_block->connect(unpack_spir_vec_.at(i), 0, throttle_vec_.at(i), 0); + top_block->connect(throttle_vec_.at(i), 0, valve_vec_.at(i), 0); + } + else + { + top_block->connect(unpack_spir_vec_.at(i), 0, valve_vec_.at(i), 0); + } + if (dump_) + { + top_block->connect(valve_vec_.at(i), 0, sink_vec_.at(i), 0); + } + + top_block->connect(valve_vec_.at(i), 0, null_sinks_.at(i), 0); } } else @@ -237,37 +256,52 @@ void SpirGSS6450FileSignalSource::disconnect(gr::top_block_sptr top_block) top_block->disconnect(file_source_, 0, deint_, 0); if (endian_swap_) { - top_block->disconnect(deint_, sel_ch_ - 1, endian_, 0); - top_block->disconnect(endian_, 0, unpack_spir_, 0); + top_block->disconnect(deint_, sel_ch_ - 1, endian_vec_.at(sel_ch_ - 1), 0); + top_block->disconnect(endian_vec_.at(sel_ch_ - 1), 0, unpack_spir_vec_.at(sel_ch_ - 1), 0); } else { - top_block->disconnect(deint_, sel_ch_ - 1, unpack_spir_, 0); + top_block->disconnect(deint_, sel_ch_ - 1, unpack_spir_vec_.at(sel_ch_ - 1), 0); } if (n_channels_ > 1) { - unsigned int aux = 0; - for (unsigned int i = 0; i < n_channels_; i++) + uint32_t aux = 0; + for (uint32_t i = 0; i < n_channels_; i++) { if (i != (sel_ch_ - 1)) { - top_block->disconnect(deint_, i, null_sinks_.at(aux), 0); + if (endian_swap_) + { + top_block->disconnect(deint_, i, endian_vec_.at(i), 0); + top_block->disconnect(endian_vec_.at(i), 0, unpack_spir_vec_.at(i), 0); + } + else + { + top_block->disconnect(deint_, i, unpack_spir_vec_.at(i), 0); + } + aux++; } } } - if (enable_throttle_control_) + + for (uint32_t i = 0; i < (n_channels_); i++) { - top_block->disconnect(unpack_spir_, 0, throttle_, 0); - top_block->disconnect(throttle_, 0, valve_, 0); - } - else - { - top_block->disconnect(unpack_spir_, 0, valve_, 0); - } - if (dump_) - { - top_block->disconnect(valve_, 0, sink_, 0); + if (enable_throttle_control_) + { + top_block->disconnect(unpack_spir_vec_.at(i), 0, throttle_vec_.at(i), 0); + top_block->disconnect(throttle_vec_.at(i), 0, valve_vec_.at(i), 0); + } + else + { + top_block->disconnect(unpack_spir_vec_.at(i), 0, valve_vec_.at(i), 0); + } + if (dump_) + { + top_block->disconnect(valve_vec_.at(i), 0, sink_vec_.at(i), 0); + } + + top_block->disconnect(valve_vec_.at(i), 0, null_sinks_.at(i), 0); } } else @@ -283,22 +317,12 @@ gr::basic_block_sptr SpirGSS6450FileSignalSource::get_left_block() return gr::blocks::file_source::sptr(); } +gr::basic_block_sptr SpirGSS6450FileSignalSource::get_right_block(int RF_channel) +{ + return valve_vec_.at(RF_channel); +} gr::basic_block_sptr SpirGSS6450FileSignalSource::get_right_block() { - if (samples_ > 0) - { - return valve_; - } - else - { - if (enable_throttle_control_) - { - return throttle_; - } - else - { - return unpack_spir_; - } - } + return valve_vec_.at(0); } diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h index 606bbd313..a37a4fe7f 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -57,7 +58,7 @@ class SpirGSS6450FileSignalSource : public GNSSBlockInterface { public: SpirGSS6450FileSignalSource(ConfigurationInterface* configuration, std::string role, - unsigned int in_streams, unsigned int out_streams, gr::msg_queue::sptr queue); + uint32_t in_streams, uint32_t out_streams, gr::msg_queue::sptr queue); virtual ~SpirGSS6450FileSignalSource(); inline std::string role() override @@ -78,6 +79,7 @@ public: 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(int RF_channel) override; gr::basic_block_sptr get_right_block() override; inline std::string filename() const @@ -106,7 +108,7 @@ public: } private: - unsigned long long samples_; + uint64_t samples_; double sampling_frequency_; std::string filename_; bool repeat_; @@ -116,19 +118,19 @@ private: std::string dump_filename_; std::string role_; std::string item_type_; - unsigned int in_streams_; - unsigned int out_streams_; - unsigned int adc_bits_; - unsigned int n_channels_; - unsigned int sel_ch_; + uint32_t in_streams_; + uint32_t out_streams_; + uint32_t adc_bits_; + uint32_t n_channels_; + uint32_t sel_ch_; gr::blocks::file_source::sptr file_source_; gr::blocks::deinterleave::sptr deint_; - gr::blocks::endian_swap::sptr endian_; + std::vector endian_vec_; std::vector null_sinks_; - unpack_spir_gss6450_samples_sptr unpack_spir_; - boost::shared_ptr valve_; - gr::blocks::file_sink::sptr sink_; - gr::blocks::throttle::sptr throttle_; + std::vector unpack_spir_vec_; + std::vector> valve_vec_; + std::vector sink_vec_; + std::vector throttle_vec_; gr::msg_queue::sptr queue_; size_t item_size_; }; diff --git a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt index 4108bed58..fb94ec51c 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt @@ -20,44 +20,67 @@ if(ENABLE_RAW_UDP) find_package(PCAP) if(NOT PCAP_FOUND) - message(FATAL_ERROR "PCAP required to compile custom UDP packet sample source (ENABLE_RAW_UDP)") - endif(NOT PCAP_FOUND) + message(FATAL_ERROR "PCAP required to compile custom UDP packet sample source") + endif() get_filename_component(PCAP_LIBRARY_DIRS ${PCAP_LIBRARY} DIRECTORY CACHE) set(OPT_LIBRARIES ${OPT_LIBRARIES} ${PCAP_LIBRARIES}) set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${PCAP_INCLUDE_DIRS}) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} gr_complex_ip_packet_source.cc) -endif(ENABLE_RAW_UDP) + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} gr_complex_ip_packet_source.h) +endif() + set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES - unpack_byte_2bit_samples.cc - unpack_byte_2bit_cpx_samples.cc - unpack_byte_4bit_samples.cc - unpack_intspir_1bit_samples.cc - rtl_tcp_signal_source_c.cc - unpack_2bit_samples.cc - unpack_spir_gss6450_samples.cc - labsat23_source.cc - ${OPT_DRIVER_SOURCES} + unpack_byte_2bit_samples.cc + unpack_byte_2bit_cpx_samples.cc + unpack_byte_4bit_samples.cc + unpack_intspir_1bit_samples.cc + rtl_tcp_signal_source_c.cc + unpack_2bit_samples.cc + unpack_spir_gss6450_samples.cc + labsat23_source.cc + ${OPT_DRIVER_SOURCES} ) + +set(SIGNAL_SOURCE_GR_BLOCKS_HEADERS + unpack_byte_2bit_samples.h + unpack_byte_2bit_cpx_samples.h + unpack_byte_4bit_samples.h + unpack_intspir_1bit_samples.h + rtl_tcp_signal_source_c.h + unpack_2bit_samples.h + unpack_spir_gss6450_samples.h + labsat23_source.h + ${OPT_DRIVER_HEADERS} +) + + include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${OPT_DRIVER_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/libs + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${OPT_DRIVER_INCLUDE_DIRS} ) -file(GLOB SIGNAL_SOURCE_GR_BLOCKS_HEADERS "*.h") list(SORT SIGNAL_SOURCE_GR_BLOCKS_HEADERS) -add_library(signal_source_gr_blocks ${SIGNAL_SOURCE_GR_BLOCKS_SOURCES} ${SIGNAL_SOURCE_GR_BLOCKS_HEADERS}) +list(SORT SIGNAL_SOURCE_GR_BLOCKS_SOURCES) + +add_library(signal_source_gr_blocks + ${SIGNAL_SOURCE_GR_BLOCKS_SOURCES} + ${SIGNAL_SOURCE_GR_BLOCKS_HEADERS} +) + source_group(Headers FILES ${SIGNAL_SOURCE_GR_BLOCKS_HEADERS}) -target_link_libraries(signal_source_gr_blocks - signal_source_lib - ${GNURADIO_RUNTIME_LIBRARIES} + +target_link_libraries(signal_source_gr_blocks + signal_source_lib + ${GNURADIO_RUNTIME_LIBRARIES} ${Boost_LIBRARIES} ${OPT_LIBRARIES} ) + add_dependencies(signal_source_gr_blocks glog-${glog_RELEASE}) diff --git a/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc b/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc index 89e535df8..34731a1c1 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/labsat23_source.cc @@ -236,8 +236,8 @@ int labsat23_source::general_work(int noutput_items, //std::cout << "Section ID: " << (int)section_id << std::endl; byte_counter += 2; - uint8_t section_lenght_bytes = 0; - section_lenght_bytes += memblock[byte_counter] | (memblock[byte_counter + 1] << 8) | (memblock[byte_counter + 2] << 16) | (memblock[byte_counter + 3] << 24); + //uint8_t section_lenght_bytes = 0; + //section_lenght_bytes += memblock[byte_counter] | (memblock[byte_counter + 1] << 8) | (memblock[byte_counter + 2] << 16) | (memblock[byte_counter + 3] << 24); //std::cout << "section_lenght_bytes=" << (int)section_lenght_bytes << std::endl; byte_counter += 4; diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc index a9426b41f..8722288d3 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc @@ -3,6 +3,7 @@ * * \brief Unpacks SPIR int samples * \author Antonio Ramos, antonio(at)cttc.es + * \author Javier Arribas jarribas (at) cttc.es * ------------------------------------------------------------------------- * * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) @@ -40,15 +41,11 @@ unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int a unpack_spir_gss6450_samples::unpack_spir_gss6450_samples(unsigned int adc_nbit) : gr::sync_interpolator("unpack_spir_gss6450_samples", - gr::io_signature::make(1, 1, sizeof(int)), + gr::io_signature::make(1, 1, sizeof(int32_t)), gr::io_signature::make(1, 1, sizeof(gr_complex)), 16 / adc_nbit) { adc_bits = adc_nbit; samples_per_int = 16 / adc_bits; - i_data.resize(adc_bits, false); - q_data.resize(adc_bits, false); - adc_bits_two_pow = static_cast(std::exp2(adc_bits)); - two_compl_thres = adc_bits_two_pow / 2; } @@ -56,48 +53,87 @@ unpack_spir_gss6450_samples::~unpack_spir_gss6450_samples() { } - -int unpack_spir_gss6450_samples::compute_two_complement(unsigned long data) +void unpack_spir_gss6450_samples::decode_4bits_word(uint32_t input_uint32, gr_complex* out, int adc_bits) { - int res = 0; - if (static_cast(data) < two_compl_thres) + int8_t tmp_char; + float Q; + float I; + switch (adc_bits) { - res = static_cast(data); - } - else - { - res = static_cast(data) - adc_bits_two_pow; - } - return res; -} + case 2: + //four bits per complex sample (2 I + 2 Q), 8 samples per int32[s0,s1,s2,s3,s4,s5,s6,s7] + for (int i = 0; i < 8; i++) + { + tmp_char = input_uint32 & 3; + if (tmp_char >= 2) + { + I = (tmp_char - 4); + } + else + { + I = tmp_char; + } + input_uint32 = input_uint32 >> 2; + tmp_char = input_uint32 & 3; + if (tmp_char >= 2) + { + Q = (tmp_char - 4); + } + else + { + Q = tmp_char; + } + input_uint32 = input_uint32 >> 2; + + out[7 - i] = gr_complex(I, Q); + } + break; + case 4: + //eight bits per complex sample (4 I + 4 Q), 4 samples per int32= [s0,s1,s2,s3] + for (int i = 0; i < 4; i++) + { + tmp_char = input_uint32 & 0x0F; + + if (tmp_char >= 8) + { + I = (tmp_char - 16); + } + else + { + I = tmp_char; + } + input_uint32 = input_uint32 >> 4; + tmp_char = input_uint32 & 0x0F; + if (tmp_char >= 8) + { + Q = (tmp_char - 16); + } + else + { + Q = tmp_char; + } + input_uint32 = input_uint32 >> 4; + + out[3 - i] = gr_complex(I, Q); + } + break; + } +} int unpack_spir_gss6450_samples::work(int noutput_items, gr_vector_const_void_star& input_items, gr_vector_void_star& output_items) { - const int* in = reinterpret_cast(input_items[0]); + const int32_t* in = reinterpret_cast(input_items[0]); gr_complex* out = reinterpret_cast(output_items[0]); - unsigned int n_sample = 0; - unsigned int in_counter = 0; - std::bitset<32> bs; - for (int i = 0; i < noutput_items; i++) + int n_sample = 0; + int in_counter = 0; + do { - bs = in[in_counter]; - int i_shift = adc_bits * 2 * (samples_per_int - n_sample - 1) + adc_bits; - int q_shift = adc_bits * 2 * (samples_per_int - n_sample - 1); - for (unsigned int k = 0; k < adc_bits; k++) - { - i_data[k] = bs[i_shift + k]; - q_data[k] = bs[q_shift + k]; - } - out[i] = gr_complex(static_cast(compute_two_complement(i_data.to_ulong())) + 0.5, - static_cast(compute_two_complement(q_data.to_ulong())) + 0.5); - n_sample++; - if (n_sample == samples_per_int) - { - n_sample = 0; - in_counter++; - } + decode_4bits_word(in[in_counter++], &out[n_sample], adc_bits); + n_sample += samples_per_int; } + while (n_sample < noutput_items); + return noutput_items; } diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h index a604982f1..a8f4b47f9 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h @@ -3,6 +3,7 @@ * * \brief Unpacks SPIR int samples * \author Antonio Ramos, antonio.ramos(at)cttc.es + * \author Javier Arribas jarribas (at) cttc.es * ------------------------------------------------------------------------- * * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) @@ -32,7 +33,6 @@ #define GNSS_SDR_UNPACK_SPIR_GSS6450_SAMPLES_H #include -#include class unpack_spir_gss6450_samples; @@ -47,18 +47,13 @@ public: int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); friend unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples_sptr(unsigned int adc_nbit); + void decode_4bits_word(uint32_t input_int32, gr_complex *out, int adc_bits); unpack_spir_gss6450_samples(unsigned int adc_nbit); ~unpack_spir_gss6450_samples(); private: - int compute_two_complement(unsigned long data); - unsigned int adc_bits; unsigned int samples_per_int; - int two_compl_thres; - int adc_bits_two_pow; - boost::dynamic_bitset<> i_data; - boost::dynamic_bitset<> q_data; }; #endif diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index 8ace0c109..3f2a6bbe5 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -17,67 +17,69 @@ # if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) - find_package(Griio REQUIRED) - if(NOT IIO_FOUND) - message(STATUS "gnuradio-iio not found, its installation is required.") - message(STATUS "Please build and install the following projects:") - message(STATUS " * libiio from https://github.com/analogdevicesinc/libiio") - message(STATUS " * libad9361-iio from https://github.com/analogdevicesinc/libad9361-iio") - message(STATUS " * gnuradio-iio from https://github.com/analogdevicesinc/gr-iio") - message(FATAL_ERROR "gnuradio-iio is required for building gnss-sdr with this option enabled") - endif(NOT IIO_FOUND) - set(OPT_LIBRARIES ${OPT_LIBRARIES} ${IIO_LIBRARIES}) - set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) -endif(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) + find_package(GRIIO REQUIRED) + if(NOT GRIIO_FOUND) + message(STATUS "gnuradio-iio not found, its installation is required.") + message(STATUS "Please build and install the following projects:") + message(STATUS " * libiio from https://github.com/analogdevicesinc/libiio") + message(STATUS " * libad9361-iio from https://github.com/analogdevicesinc/libad9361-iio") + message(STATUS " * gnuradio-iio from https://github.com/analogdevicesinc/gr-iio") + message(FATAL_ERROR "gnuradio-iio is required for building gnss-sdr with this option enabled") + endif() + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${IIO_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) +endif() if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) - find_package(libiio REQUIRED) - if(NOT LIBIIO_FOUND) - message(STATUS "libiio not found, its installation is required.") - message(STATUS "Please build and install the following projects:") - message(STATUS " * libiio from https://github.com/analogdevicesinc/libiio") - message(STATUS " * libad9361-iio from https://github.com/analogdevicesinc/libad9361-iio") - message(STATUS " * gnuradio-iio from https://github.com/analogdevicesinc/gr-iio") - message(FATAL_ERROR "libiio is required for building gnss-sdr with this option enabled") - endif(NOT LIBIIO_FOUND) - set(OPT_LIBRARIES ${OPT_LIBRARIES} ${LIBIIO_LIBRARIES}) - set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${LIBIIO_INCLUDE_DIRS}) + find_package(LIBIIO REQUIRED) + if(NOT LIBIIO_FOUND) + message(STATUS "libiio not found, its installation is required.") + message(STATUS "Please build and install the following projects:") + message(STATUS " * libiio from https://github.com/analogdevicesinc/libiio") + message(STATUS " * libad9361-iio from https://github.com/analogdevicesinc/libad9361-iio") + message(STATUS " * gnuradio-iio from https://github.com/analogdevicesinc/gr-iio") + message(FATAL_ERROR "libiio is required for building gnss-sdr with this option enabled") + endif() + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${LIBIIO_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${LIBIIO_INCLUDE_DIRS}) - ############################################### - # FMCOMMS2 based SDR Hardware - ############################################### - if(LIBIIO_FOUND) - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ad9361_manager.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ad9361_manager.h) - endif(LIBIIO_FOUND) -endif(ENABLE_FMCOMMS2 OR ENABLE_AD9361) + ############################################### + # FMCOMMS2 based SDR Hardware + ############################################### + if(LIBIIO_FOUND) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ad9361_manager.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ad9361_manager.h) + endif() +endif() if(ENABLE_FPGA OR ENABLE_AD9361) - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_switch.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_switch.h) -endif(ENABLE_FPGA OR ENABLE_AD9361) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_switch.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_switch.h) +endif() include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${Boost_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${OPT_DRIVER_INCLUDE_DIRS} - ) + ${CMAKE_CURRENT_SOURCE_DIR} + ${Boost_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${OPT_DRIVER_INCLUDE_DIRS} +) set(SIGNAL_SOURCE_LIB_SOURCES - rtl_tcp_commands.cc - rtl_tcp_dongle_info.cc - ${OPT_SIGNAL_SOURCE_LIB_SOURCES} - ) - + rtl_tcp_commands.cc + rtl_tcp_dongle_info.cc + ${OPT_SIGNAL_SOURCE_LIB_SOURCES} +) + set(SIGNAL_SOURCE_LIB_HEADERS - rtl_tcp_commands.h - rtl_tcp_dongle_info.h - ${OPT_SIGNAL_SOURCE_LIB_HEADERS} - ) + rtl_tcp_commands.h + rtl_tcp_dongle_info.h + ${OPT_SIGNAL_SOURCE_LIB_HEADERS} +) list(SORT SIGNAL_SOURCE_LIB_HEADERS) +list(SORT SIGNAL_SOURCE_LIB_SOURCES) + add_library(signal_source_lib ${SIGNAL_SOURCE_LIB_SOURCES} ${SIGNAL_SOURCE_LIB_HEADERS}) source_group(Headers FILES ${SIGNAL_SOURCE_LIB_HEADERS}) target_link_libraries(signal_source_lib ${OPT_LIBRARIES}) diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index d2583a5d5..7c9c9f3c9 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -46,8 +46,8 @@ void errchk(int v, const char *what) } -/* write attribute: long long int */ -void wr_ch_lli(struct iio_channel *chn, const char *what, long long val) +/* write attribute: int64_t int */ +void wr_ch_lli(struct iio_channel *chn, const char *what, int64_t val) { errchk(iio_channel_attr_write_longlong(chn, what, val), what); } @@ -176,9 +176,9 @@ bool cfg_ad9361_streaming_ch(struct iio_context *ctx, struct stream_cfg *cfg, en } -bool config_ad9361_rx_local(unsigned long bandwidth_, - unsigned long sample_rate_, - unsigned long freq_, +bool config_ad9361_rx_local(uint64_t bandwidth_, + uint64_t sample_rate_, + uint64_t freq_, std::string rf_port_select_, std::string gain_mode_rx1_, std::string gain_mode_rx2_, @@ -292,9 +292,9 @@ bool config_ad9361_rx_local(unsigned long bandwidth_, bool config_ad9361_rx_remote(std::string remote_host, - unsigned long bandwidth_, - unsigned long sample_rate_, - unsigned long freq_, + uint64_t bandwidth_, + uint64_t sample_rate_, + uint64_t freq_, std::string rf_port_select_, std::string gain_mode_rx1_, std::string gain_mode_rx2_, @@ -407,11 +407,11 @@ bool config_ad9361_rx_remote(std::string remote_host, } -bool config_ad9361_lo_local(unsigned long bandwidth_, - unsigned long sample_rate_, - unsigned long freq_rf_tx_hz_, +bool config_ad9361_lo_local(uint64_t bandwidth_, + uint64_t sample_rate_, + uint64_t freq_rf_tx_hz_, double tx_attenuation_db_, - long long freq_dds_tx_hz_, + int64_t freq_dds_tx_hz_, double scale_dds_dbfs_) { // TX stream config @@ -476,13 +476,13 @@ bool config_ad9361_lo_local(unsigned long bandwidth_, //set frequency, scale and phase - ret = iio_channel_attr_write_longlong(dds_channel0_I, "frequency", (long long)freq_dds_tx_hz_); + ret = iio_channel_attr_write_longlong(dds_channel0_I, "frequency", static_cast(freq_dds_tx_hz_)); if (ret < 0) { std::cout << "Failed to set TX DDS frequency I: " << ret << std::endl; } - ret = iio_channel_attr_write_longlong(dds_channel0_Q, "frequency", (long long)freq_dds_tx_hz_); + ret = iio_channel_attr_write_longlong(dds_channel0_Q, "frequency", static_cast(freq_dds_tx_hz_)); if (ret < 0) { std::cout << "Failed to set TX DDS frequency Q: " << ret << std::endl; @@ -544,11 +544,11 @@ bool config_ad9361_lo_local(unsigned long bandwidth_, bool config_ad9361_lo_remote(std::string remote_host, - unsigned long bandwidth_, - unsigned long sample_rate_, - unsigned long freq_rf_tx_hz_, + uint64_t bandwidth_, + uint64_t sample_rate_, + uint64_t freq_rf_tx_hz_, double tx_attenuation_db_, - long long freq_dds_tx_hz_, + int64_t freq_dds_tx_hz_, double scale_dds_dbfs_) { // TX stream config @@ -613,13 +613,13 @@ bool config_ad9361_lo_remote(std::string remote_host, //set frequency, scale and phase - ret = iio_channel_attr_write_longlong(dds_channel0_I, "frequency", (long long)freq_dds_tx_hz_); + ret = iio_channel_attr_write_longlong(dds_channel0_I, "frequency", static_cast(freq_dds_tx_hz_)); if (ret < 0) { std::cout << "Failed to set TX DDS frequency I: " << ret << std::endl; } - ret = iio_channel_attr_write_longlong(dds_channel0_Q, "frequency", (long long)freq_dds_tx_hz_); + ret = iio_channel_attr_write_longlong(dds_channel0_Q, "frequency", static_cast(freq_dds_tx_hz_)); if (ret < 0) { std::cout << "Failed to set TX DDS frequency Q: " << ret << std::endl; diff --git a/src/algorithms/signal_source/libs/ad9361_manager.h b/src/algorithms/signal_source/libs/ad9361_manager.h index acfe3abb5..875b724c0 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.h +++ b/src/algorithms/signal_source/libs/ad9361_manager.h @@ -33,6 +33,7 @@ #ifndef GNSS_SDR_AD9361_MANAGER_H #define GNSS_SDR_AD9361_MANAGER_H +#include #include #ifdef __APPLE__ @@ -51,9 +52,9 @@ enum iodev /* common RX and TX streaming params */ struct stream_cfg { - long long bw_hz; // Analog banwidth in Hz - long long fs_hz; // Baseband sample rate in Hz - long long lo_hz; // Local oscillator frequency in Hz + int64_t bw_hz; // Analog banwidth in Hz + int64_t fs_hz; // Baseband sample rate in Hz + int64_t lo_hz; // Local oscillator frequency in Hz const char *rfport; // Port name }; @@ -61,8 +62,8 @@ struct stream_cfg /* check return value of attr_write function */ void errchk(int v, const char *what); -/* write attribute: long long int */ -void wr_ch_lli(struct iio_channel *chn, const char *what, long long val); +/* write attribute: int64_t int */ +void wr_ch_lli(struct iio_channel *chn, const char *what, int64_t val); /* write attribute: string */ void wr_ch_str(struct iio_channel *chn, const char *what, const char *str); @@ -88,9 +89,9 @@ bool get_lo_chan(struct iio_context *ctx, enum iodev d, struct iio_channel **chn /* applies streaming configuration through IIO */ bool cfg_ad9361_streaming_ch(struct iio_context *ctx, struct stream_cfg *cfg, enum iodev type, int chid); -bool config_ad9361_rx_local(unsigned long bandwidth_, - unsigned long sample_rate_, - unsigned long freq_, +bool config_ad9361_rx_local(uint64_t bandwidth_, + uint64_t sample_rate_, + uint64_t freq_, std::string rf_port_select_, std::string gain_mode_rx1_, std::string gain_mode_rx2_, @@ -98,28 +99,28 @@ bool config_ad9361_rx_local(unsigned long bandwidth_, double rf_gain_rx2_); bool config_ad9361_rx_remote(std::string remote_host, - unsigned long bandwidth_, - unsigned long sample_rate_, - unsigned long freq_, + uint64_t bandwidth_, + uint64_t sample_rate_, + uint64_t freq_, std::string rf_port_select_, std::string gain_mode_rx1_, std::string gain_mode_rx2_, double rf_gain_rx1_, double rf_gain_rx2_); -bool config_ad9361_lo_local(unsigned long bandwidth_, - unsigned long sample_rate_, - unsigned long freq_rf_tx_hz_, +bool config_ad9361_lo_local(uint64_t bandwidth_, + uint64_t sample_rate_, + uint64_t freq_rf_tx_hz_, double tx_attenuation_db_, - long long freq_dds_tx_hz_, + int64_t freq_dds_tx_hz_, double scale_dds_dbfs_); bool config_ad9361_lo_remote(std::string remote_host, - unsigned long bandwidth_, - unsigned long sample_rate_, - unsigned long freq_rf_tx_hz_, + uint64_t bandwidth_, + uint64_t sample_rate_, + uint64_t freq_rf_tx_hz_, double tx_attenuation_db_, - long long freq_dds_tx_hz_, + int64_t freq_dds_tx_hz_, double scale_dds_dbfs_); diff --git a/src/algorithms/telemetry_decoder/CMakeLists.txt b/src/algorithms/telemetry_decoder/CMakeLists.txt index ea74d8ec3..96259341c 100644 --- a/src/algorithms/telemetry_decoder/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/CMakeLists.txt @@ -18,4 +18,4 @@ add_subdirectory(adapters) add_subdirectory(gnuradio_blocks) -add_subdirectory(libs) \ No newline at end of file +add_subdirectory(libs) diff --git a/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt b/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt index 6722ce03b..01836e5ae 100644 --- a/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt @@ -20,30 +20,51 @@ set(TELEMETRY_DECODER_ADAPTER_SOURCES gps_l1_ca_telemetry_decoder.cc gps_l2c_telemetry_decoder.cc - gps_l5_telemetry_decoder.cc + gps_l5_telemetry_decoder.cc galileo_e1b_telemetry_decoder.cc sbas_l1_telemetry_decoder.cc galileo_e5a_telemetry_decoder.cc glonass_l1_ca_telemetry_decoder.cc - glonass_l2_ca_telemetry_decoder.cc + glonass_l2_ca_telemetry_decoder.cc +) + +set(TELEMETRY_DECODER_ADAPTER_HEADERS + gps_l1_ca_telemetry_decoder.h + gps_l2c_telemetry_decoder.h + gps_l5_telemetry_decoder.h + galileo_e1b_telemetry_decoder.h + sbas_l1_telemetry_decoder.h + galileo_e5a_telemetry_decoder.h + glonass_l1_ca_telemetry_decoder.h + glonass_l2_ca_telemetry_decoder.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs/libswiftcnav - ${Boost_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs/libswiftcnav + ${Boost_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} ) -file(GLOB TELEMETRY_DECODER_ADAPTER_HEADERS "*.h") list(SORT TELEMETRY_DECODER_ADAPTER_HEADERS) -add_library(telemetry_decoder_adapters ${TELEMETRY_DECODER_ADAPTER_SOURCES} ${TELEMETRY_DECODER_ADAPTER_HEADERS}) +list(SORT TELEMETRY_DECODER_ADAPTER_SOURCES) + +add_library(telemetry_decoder_adapters + ${TELEMETRY_DECODER_ADAPTER_SOURCES} + ${TELEMETRY_DECODER_ADAPTER_HEADERS} +) + source_group(Headers FILES ${TELEMETRY_DECODER_ADAPTER_HEADERS}) -target_link_libraries(telemetry_decoder_adapters telemetry_decoder_gr_blocks gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES}) + +target_link_libraries(telemetry_decoder_adapters + telemetry_decoder_gr_blocks + gnss_system_parameters + ${GNURADIO_RUNTIME_LIBRARIES} +) diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc index ab20cab1d..f7a663358 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc @@ -55,7 +55,7 @@ GalileoE1BTelemetryDecoder::GalileoE1BTelemetryDecoder(ConfigurationInterface* c dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); // make telemetry decoder object - telemetry_decoder_ = galileo_e1b_make_telemetry_decoder_cc(satellite_, dump_); // TODO fix me + telemetry_decoder_ = galileo_make_telemetry_decoder_cc(satellite_, 1, dump_); //unified galileo decoder set to INAV (frame_type=1) DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.h index d762eabd8..119e294ad 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.h @@ -36,7 +36,7 @@ #include "telemetry_decoder_interface.h" -#include "galileo_e1b_telemetry_decoder_cc.h" +#include "galileo_telemetry_decoder_cc.h" #include "gnss_satellite.h" #include @@ -76,7 +76,6 @@ public: void set_satellite(const Gnss_Satellite& satellite) override; inline void set_channel(int channel) override { telemetry_decoder_->set_channel(channel); } - inline void reset() override { return; @@ -88,7 +87,7 @@ public: } private: - galileo_e1b_telemetry_decoder_cc_sptr telemetry_decoder_; + galileo_telemetry_decoder_cc_sptr telemetry_decoder_; Gnss_Satellite satellite_; int channel_; bool dump_; diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc index 48ed8b216..99ab590ea 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc @@ -58,7 +58,7 @@ GalileoE5aTelemetryDecoder::GalileoE5aTelemetryDecoder(ConfigurationInterface* c dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); // make telemetry decoder object - telemetry_decoder_ = galileo_e5a_make_telemetry_decoder_cc(satellite_, dump_); // TODO fix me + telemetry_decoder_ = galileo_make_telemetry_decoder_cc(satellite_, 2, dump_); //unified galileo decoder set to FNAV (frame_type=2) DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; channel_ = 0; if (in_streams_ > 1) diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.h index 4a4167bf5..022636384 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.h @@ -37,7 +37,7 @@ #ifndef GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_H_ #define GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_H_ -#include "galileo_e5a_telemetry_decoder_cc.h" +#include "galileo_telemetry_decoder_cc.h" #include "telemetry_decoder_interface.h" #include @@ -76,7 +76,6 @@ public: void set_satellite(const Gnss_Satellite& satellite) override; inline void set_channel(int channel) override { telemetry_decoder_->set_channel(channel); } - inline void reset() override { return; @@ -88,7 +87,7 @@ public: } private: - galileo_e5a_telemetry_decoder_cc_sptr telemetry_decoder_; + galileo_telemetry_decoder_cc_sptr telemetry_decoder_; Gnss_Satellite satellite_; int channel_; bool dump_; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt index 3af26e46b..83fe5d36f 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt @@ -17,35 +17,56 @@ # set(TELEMETRY_DECODER_GR_BLOCKS_SOURCES - gps_l1_ca_telemetry_decoder_cc.cc - gps_l2c_telemetry_decoder_cc.cc - gps_l5_telemetry_decoder_cc.cc - galileo_e1b_telemetry_decoder_cc.cc - sbas_l1_telemetry_decoder_cc.cc - galileo_e5a_telemetry_decoder_cc.cc - glonass_l1_ca_telemetry_decoder_cc.cc - glonass_l2_ca_telemetry_decoder_cc.cc + gps_l1_ca_telemetry_decoder_cc.cc + gps_l2c_telemetry_decoder_cc.cc + gps_l5_telemetry_decoder_cc.cc + sbas_l1_telemetry_decoder_cc.cc + glonass_l1_ca_telemetry_decoder_cc.cc + glonass_l2_ca_telemetry_decoder_cc.cc + galileo_telemetry_decoder_cc.cc +) + +set(TELEMETRY_DECODER_GR_BLOCKS_HEADERS + gps_l1_ca_telemetry_decoder_cc.h + gps_l2c_telemetry_decoder_cc.h + gps_l5_telemetry_decoder_cc.h + sbas_l1_telemetry_decoder_cc.h + glonass_l1_ca_telemetry_decoder_cc.h + glonass_l2_ca_telemetry_decoder_cc.h + galileo_telemetry_decoder_cc.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs/libswiftcnav - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${VOLK_GNSSSDR_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs/libswiftcnav + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_GNSSSDR_INCLUDE_DIRS} ) -file(GLOB TELEMETRY_DECODER_GR_BLOCKS_HEADERS "*.h") list(SORT TELEMETRY_DECODER_GR_BLOCKS_HEADERS) -add_library(telemetry_decoder_gr_blocks ${TELEMETRY_DECODER_GR_BLOCKS_SOURCES} ${TELEMETRY_DECODER_GR_BLOCKS_HEADERS}) -source_group(Headers FILES ${TELEMETRY_DECODER_GR_BLOCKS_HEADERS}) -target_link_libraries(telemetry_decoder_gr_blocks telemetry_decoder_libswiftcnav telemetry_decoder_lib gnss_system_parameters ${GNURADIO_RUNTIME_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES}) +list(SORT TELEMETRY_DECODER_GR_BLOCKS_SOURCES) -if(NOT VOLK_GNSSSDR_FOUND) - add_dependencies(telemetry_decoder_gr_blocks volk_gnsssdr_module) -endif(NOT VOLK_GNSSSDR_FOUND) +add_library(telemetry_decoder_gr_blocks + ${TELEMETRY_DECODER_GR_BLOCKS_SOURCES} + ${TELEMETRY_DECODER_GR_BLOCKS_HEADERS} +) + +source_group(Headers FILES ${TELEMETRY_DECODER_GR_BLOCKS_HEADERS}) + +target_link_libraries(telemetry_decoder_gr_blocks + telemetry_decoder_libswiftcnav + telemetry_decoder_lib + gnss_system_parameters + ${GNURADIO_RUNTIME_LIBRARIES} + ${VOLK_GNSSSDR_LIBRARIES} +) + +if(NOT VOLKGNSSSDR_FOUND) + add_dependencies(telemetry_decoder_gr_blocks volk_gnsssdr_module) +endif() diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.cc deleted file mode 100644 index 9e1dc3394..000000000 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.cc +++ /dev/null @@ -1,491 +0,0 @@ -/*! - * \file galileo_e1b_telemetry_decoder_cc.cc - * \brief Implementation of a Galileo INAV message demodulator block - * \author Mara Branzanti 2013. mara.branzanti(at)gmail.com - * \author Javier Arribas 2013. jarribas(at)cttc.es - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) - * - * GNSS-SDR is a software defined Global Navigation - * Satellite Systems receiver - * - * This file is part of GNSS-SDR. - * - * GNSS-SDR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNSS-SDR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . - * - * ------------------------------------------------------------------------- - */ - - -#include "galileo_e1b_telemetry_decoder_cc.h" -#include "control_message_factory.h" -#include "convolutional.h" -#include "gnss_synchro.h" -#include -#include -#include -#include -#include - - -#define CRC_ERROR_LIMIT 6 - -using google::LogMessage; - - -galileo_e1b_telemetry_decoder_cc_sptr -galileo_e1b_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump) -{ - return galileo_e1b_telemetry_decoder_cc_sptr(new galileo_e1b_telemetry_decoder_cc(satellite, dump)); -} - - -void galileo_e1b_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int *page_part_bits) -{ - Viterbi(page_part_bits, out0, state0, out1, state1, - page_part_symbols, KK, nn, DataLength); -} - - -void galileo_e1b_telemetry_decoder_cc::deinterleaver(int rows, int cols, double *in, double *out) -{ - for (int r = 0; r < rows; r++) - { - for (int c = 0; c < cols; c++) - { - out[c * rows + r] = in[r * cols + c]; - } - } -} - - -galileo_e1b_telemetry_decoder_cc::galileo_e1b_telemetry_decoder_cc( - const Gnss_Satellite &satellite, - bool dump) : gr::block("galileo_e1b_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) -{ - // Ephemeris data port out - this->message_port_register_out(pmt::mp("telemetry")); - // initialize internal vars - d_dump = dump; - d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); - LOG(INFO) << "Initializing GALILEO E1B TELEMETRY PROCESSING"; - d_samples_per_symbol = (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS) / Galileo_E1_B_SYMBOL_RATE_BPS; - - // set the preamble - unsigned short int preambles_bits[GALILEO_INAV_PREAMBLE_LENGTH_BITS] = GALILEO_INAV_PREAMBLE; - - d_symbols_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol; - - memcpy(static_cast(this->d_preambles_bits), static_cast(preambles_bits), GALILEO_INAV_PREAMBLE_LENGTH_BITS * sizeof(unsigned short int)); - - // preamble bits to sampled symbols - d_preambles_symbols = static_cast(volk_gnsssdr_malloc(d_symbols_per_preamble * sizeof(int), volk_gnsssdr_get_alignment())); - int n = 0; - for (int i = 0; i < GALILEO_INAV_PREAMBLE_LENGTH_BITS; i++) - { - for (unsigned int j = 0; j < d_samples_per_symbol; j++) - { - if (d_preambles_bits[i] == 1) - { - d_preambles_symbols[n] = 1; - } - else - { - d_preambles_symbols[n] = -1; - } - n++; - } - } - d_sample_counter = 0; - d_stat = 0; - d_preamble_index = 0; - - d_flag_frame_sync = false; - - d_flag_parity = false; - d_TOW_at_current_symbol = 0; - delta_t = 0; - d_CRC_error_counter = 0; - flag_even_word_arrived = 0; - d_flag_preamble = false; - d_channel = 0; - flag_TOW_set = false; - - // vars for Viterbi decoder - int max_states = 1 << mm; /* 2^mm */ - g_encoder[0] = 121; // Polynomial G1 - g_encoder[1] = 91; // Polynomial G2 - out0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment())); - out1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment())); - state0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment())); - state1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment())); - /* create appropriate transition matrices */ - nsc_transit(out0, state0, 0, g_encoder, KK, nn); - nsc_transit(out1, state1, 1, g_encoder, KK, nn); -} - - -galileo_e1b_telemetry_decoder_cc::~galileo_e1b_telemetry_decoder_cc() -{ - volk_gnsssdr_free(d_preambles_symbols); - volk_gnsssdr_free(out0); - volk_gnsssdr_free(out1); - volk_gnsssdr_free(state0); - volk_gnsssdr_free(state1); - if (d_dump_file.is_open() == true) - { - try - { - d_dump_file.close(); - } - catch (const std::exception &ex) - { - LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); - } - } -} - - -void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols, int frame_length) -{ - double page_part_symbols_deint[frame_length]; - // 1. De-interleave - deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS, GALILEO_INAV_INTERLEAVER_COLS, page_part_symbols, page_part_symbols_deint); - - // 2. Viterbi decoder - // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) - // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180� - for (int i = 0; i < frame_length; i++) - { - if ((i + 1) % 2 == 0) - { - page_part_symbols_deint[i] = -page_part_symbols_deint[i]; - } - } - - int page_part_bits[frame_length / 2]; - viterbi_decoder(page_part_symbols_deint, page_part_bits); - - // 3. Call the Galileo page decoder - std::string page_String; - for (int i = 0; i < (frame_length / 2); i++) - { - if (page_part_bits[i] > 0) - { - page_String.push_back('1'); - } - else - { - page_String.push_back('0'); - } - } - - if (page_part_bits[0] == 1) - { - // DECODE COMPLETE WORD (even + odd) and TEST CRC - d_nav.split_page(page_String, flag_even_word_arrived); - if (d_nav.flag_CRC_test == true) - { - LOG(INFO) << "Galileo E1 CRC correct in channel " << d_channel << " from satellite " << d_satellite; - //std::cout << "Galileo E1 CRC correct on channel " << d_channel << " from satellite " << d_satellite << std::endl; - } - else - { - std::cout << "Galileo E1 CRC error in channel " << d_channel << " from satellite " << d_satellite << std::endl; - LOG(INFO) << "Galileo E1 CRC error in channel " << d_channel << " from satellite " << d_satellite; - } - flag_even_word_arrived = 0; - } - else - { - // STORE HALF WORD (even page) - d_nav.split_page(page_String.c_str(), flag_even_word_arrived); - flag_even_word_arrived = 1; - } - - // 4. Push the new navigation data to the queues - if (d_nav.have_new_ephemeris() == true) - { - // get object for this SV (mandatory) - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_ephemeris()); - std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_nav.have_new_iono_and_GST() == true) - { - // get object for this SV (mandatory) - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_iono()); - std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": iono/GST model parameters from satellite " << d_satellite << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_nav.have_new_utc_model() == true) - { - // get object for this SV (mandatory) - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_utc_model()); - std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_nav.have_new_almanac() == true) - { - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_almanac()); - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - //debug - std::cout << "Galileo E1 I/NAV almanac received in channel " << d_channel << " from satellite " << d_satellite << std::endl; - DLOG(INFO) << "GPS_to_Galileo time conversion:"; - DLOG(INFO) << "A0G=" << tmp_obj->A_0G_10; - DLOG(INFO) << "A1G=" << tmp_obj->A_1G_10; - DLOG(INFO) << "T0G=" << tmp_obj->t_0G_10; - DLOG(INFO) << "WN_0G_10=" << tmp_obj->WN_0G_10; - DLOG(INFO) << "Current parameters:"; - DLOG(INFO) << "d_TOW_at_current_symbol=" << d_TOW_at_current_symbol; - DLOG(INFO) << "d_nav.WN_0=" << d_nav.WN_0; - delta_t = tmp_obj->A_0G_10 + tmp_obj->A_1G_10 * (d_TOW_at_current_symbol - tmp_obj->t_0G_10 + 604800 * (fmod((d_nav.WN_0 - tmp_obj->WN_0G_10), 64))); - DLOG(INFO) << "delta_t=" << delta_t << "[s]"; - } -} - - -void galileo_e1b_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite) -{ - d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); - DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite; - DLOG(INFO) << "Navigation Satellite set to " << d_satellite; -} - - -void galileo_e1b_telemetry_decoder_cc::set_channel(int channel) -{ - d_channel = channel; - LOG(INFO) << "Navigation channel set to " << channel; - // ############# ENABLE DATA FILE LOG ################# - if (d_dump == true) - { - if (d_dump_file.is_open() == false) - { - try - { - d_dump_filename = "telemetry"; - d_dump_filename.append(boost::lexical_cast(d_channel)); - d_dump_filename.append(".dat"); - d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); - } - } - } -} - - -int galileo_e1b_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) -{ - int corr_value = 0; - int preamble_diff = 0; - - Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer - const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer - - Gnss_Synchro current_symbol; // structure to save the synchronization information and send the output object to the next block - // 1. Copy the current tracking output - current_symbol = in[0][0]; - d_symbol_history.push_back(current_symbol); // add new symbol to the symbol queue - d_sample_counter++; // count for the processed samples - consume_each(1); - - d_flag_preamble = false; - unsigned int required_symbols = GALILEO_INAV_PAGE_SYMBOLS + d_symbols_per_preamble; - - if (d_symbol_history.size() > required_symbols) - { - // TODO Optimize me! - // ******* preamble correlation ******** - for (int i = 0; i < d_symbols_per_preamble; i++) - { - if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping - { - corr_value -= d_preambles_symbols[i]; - } - else - { - corr_value += d_preambles_symbols[i]; - } - } - } - - // ******* frame sync ****************** - if (d_stat == 0) // no preamble information - { - if (abs(corr_value) >= d_symbols_per_preamble) - { - d_preamble_index = d_sample_counter; // record the preamble sample stamp - LOG(INFO) << "Preamble detection for Galileo satellite " << this->d_satellite; - d_stat = 1; // enter into frame pre-detection status - } - } - else if (d_stat == 1) // possible preamble lock - { - if (abs(corr_value) >= d_symbols_per_preamble) - { - // check preamble separation - preamble_diff = d_sample_counter - d_preamble_index; - if (abs(preamble_diff - GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS) == 0) - { - // try to decode frame - LOG(INFO) << "Starting page decoder for Galileo satellite " << this->d_satellite; - d_preamble_index = d_sample_counter; // record the preamble sample stamp - d_stat = 2; - } - else - { - if (preamble_diff > GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS) - { - d_stat = 0; // start again - } - } - } - } - else if (d_stat == 2) - { - if (d_sample_counter == d_preamble_index + GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS) - { - // NEW Galileo page part is received - // 0. fetch the symbols into an array - int frame_length = GALILEO_INAV_PAGE_PART_SYMBOLS - d_symbols_per_preamble; - double page_part_symbols[frame_length]; - - for (int i = 0; i < frame_length; i++) - { - if (corr_value > 0) - { - page_part_symbols[i] = d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now! - } - else - { - page_part_symbols[i] = -d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now! - } - } - - // call the decoder - decode_word(page_part_symbols, frame_length); - if (d_nav.flag_CRC_test == true) - { - d_CRC_error_counter = 0; - d_flag_preamble = true; // valid preamble indicator (initialized to false every work()) - d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P) - if (!d_flag_frame_sync) - { - d_flag_frame_sync = true; - DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " - << d_symbol_history.at(0).Tracking_sample_counter << " [samples]"; - } - } - else - { - d_CRC_error_counter++; - d_preamble_index = d_sample_counter; // record the preamble sample stamp - if (d_CRC_error_counter > CRC_ERROR_LIMIT) - { - LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite; - d_flag_frame_sync = false; - d_stat = 0; - } - } - } - } - - // UPDATE GNSS SYNCHRO DATA - // 2. Add the telemetry decoder information - if (this->d_flag_preamble == true and d_nav.flag_TOW_set == true) - // update TOW at the preamble instant - { - if (d_nav.flag_TOW_5 == true) // page 5 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec) - { - // TOW_5 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay - d_TOW_at_current_symbol = d_nav.TOW_5 + static_cast(GALILEO_INAV_PAGE_PART_SECONDS) + static_cast(required_symbols + 1) * GALILEO_E1_CODE_PERIOD; - d_nav.flag_TOW_5 = false; - } - - else if (d_nav.flag_TOW_6 == true) // page 6 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec) - { - // TOW_6 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay - d_TOW_at_current_symbol = d_nav.TOW_6 + static_cast(GALILEO_INAV_PAGE_PART_SECONDS) + static_cast(required_symbols + 1) * GALILEO_E1_CODE_PERIOD; - d_nav.flag_TOW_6 = false; - } - else - { - // this page has no timing information - d_TOW_at_current_symbol += GALILEO_E1_CODE_PERIOD; // + GALILEO_INAV_PAGE_PART_SYMBOLS*GALILEO_E1_CODE_PERIOD; - } - } - else // if there is not a new preamble, we define the TOW of the current symbol - { - d_TOW_at_current_symbol += GALILEO_E1_CODE_PERIOD; - } - - // if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true) - - if (d_nav.flag_GGTO_1 == true and d_nav.flag_GGTO_2 == true and d_nav.flag_GGTO_3 == true and d_nav.flag_GGTO_4 == true) // all GGTO parameters arrived - { - delta_t = d_nav.A_0G_10 + d_nav.A_1G_10 * (d_TOW_at_current_symbol - d_nav.t_0G_10 + 604800.0 * (fmod((d_nav.WN_0 - d_nav.WN_0G_10), 64.0))); - } - - if (d_flag_frame_sync == true and d_nav.flag_TOW_set == true) - { - current_symbol.Flag_valid_word = true; - } - else - { - current_symbol.Flag_valid_word = false; - } - - current_symbol.TOW_at_current_symbol_ms = round(d_TOW_at_current_symbol * 1000.0); - // todo: Galileo to GPS time conversion should be moved to observable block. - // current_symbol.TOW_at_current_symbol_ms -= delta_t; //Galileo to GPS TOW - - if (d_dump == true) - { - // MULTIPLEXED FILE RECORDING - Record results to file - try - { - double tmp_double; - unsigned long int tmp_ulong_int; - tmp_double = d_TOW_at_current_symbol; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_ulong_int = current_symbol.Tracking_sample_counter; - d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(unsigned long int)); - tmp_double = 0; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "Exception writing observables dump file " << e.what(); - } - } - - // remove used symbols from history - if (d_symbol_history.size() > required_symbols) - { - d_symbol_history.pop_front(); - } - // 3. Make the output (copy the object contents to the GNURadio reserved memory) - *out[0] = current_symbol; - return 1; -} diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.h deleted file mode 100644 index 8f434f0d5..000000000 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e1b_telemetry_decoder_cc.h +++ /dev/null @@ -1,126 +0,0 @@ -/*! - * \file galileo_e1b_telemetry_decoder_cc.h - * \brief Interface of a Galileo INAV message demodulator block - * \author Javier Arribas 2013 jarribas(at)cttc.es, - * Mara Branzanti 2013 mara.branzanti(at)gmail.com - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) - * - * GNSS-SDR is a software defined Global Navigation - * Satellite Systems receiver - * - * This file is part of GNSS-SDR. - * - * GNSS-SDR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNSS-SDR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . - * - * ------------------------------------------------------------------------- - */ - -#ifndef GNSS_SDR_GALILEO_E1B_TELEMETRY_DECODER_CC_H -#define GNSS_SDR_GALILEO_E1B_TELEMETRY_DECODER_CC_H - - -#include "Galileo_E1.h" -#include "galileo_navigation_message.h" -#include "galileo_ephemeris.h" -#include "galileo_almanac.h" -#include "galileo_iono.h" -#include "galileo_utc_model.h" -#include "gnss_satellite.h" -#include "gnss_synchro.h" -#include -#include -#include - - -class galileo_e1b_telemetry_decoder_cc; - -typedef boost::shared_ptr galileo_e1b_telemetry_decoder_cc_sptr; - -galileo_e1b_telemetry_decoder_cc_sptr galileo_e1b_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - -/*! - * \brief This class implements a block that decodes the INAV data defined in Galileo ICD - * - */ -class galileo_e1b_telemetry_decoder_cc : public gr::block -{ -public: - ~galileo_e1b_telemetry_decoder_cc(); - void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN - void set_channel(int channel); //!< Set receiver's channel - int flag_even_word_arrived; - - /*! - * \brief This is where all signal processing takes place - */ - int general_work(int noutput_items, gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - -private: - friend galileo_e1b_telemetry_decoder_cc_sptr - galileo_e1b_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - galileo_e1b_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - - void viterbi_decoder(double *page_part_symbols, int *page_part_bits); - - void deinterleaver(int rows, int cols, double *in, double *out); - - void decode_word(double *symbols, int frame_length); - - unsigned short int d_preambles_bits[GALILEO_INAV_PREAMBLE_LENGTH_BITS]; - - int *d_preambles_symbols; - unsigned int d_samples_per_symbol; - int d_symbols_per_preamble; - - std::deque d_symbol_history; - - long unsigned int d_sample_counter; - long unsigned int d_preamble_index; - unsigned int d_stat; - bool d_flag_frame_sync; - - bool d_flag_parity; - bool d_flag_preamble; - int d_CRC_error_counter; - - // navigation message vars - Galileo_Navigation_Message d_nav; - - bool d_dump; - Gnss_Satellite d_satellite; - int d_channel; - - double d_TOW_at_current_symbol; - - bool flag_TOW_set; - double delta_t; //GPS-GALILEO time offset - - std::string d_dump_filename; - std::ofstream d_dump_file; - - // vars for Viterbi decoder - int *out0, *out1, *state0, *state1; - int g_encoder[2]; - const int nn = 2; // Coding rate 1/n - const int KK = 7; // Constraint Length - int mm = KK - 1; - const int CodeLength = 240; - int DataLength = (CodeLength / nn) - mm; -}; - -#endif diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc deleted file mode 100644 index 96431880b..000000000 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.cc +++ /dev/null @@ -1,509 +0,0 @@ -/*! - * \file galileo_e5a_telemetry_decoder_cc.cc - * \brief Implementation of a Galileo FNAV message demodulator block - * \author Marc Sales, 2014. marcsales92(at)gmail.com - * Javier Arribas, 2017. jarribas(at)cttc.es - * \based on work from: - *
        - *
      • Javier Arribas, 2011. jarribas(at)cttc.es - *
      - * - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) - * - * GNSS-SDR is a software defined Global Navigation - * Satellite Systems receiver - * - * This file is part of GNSS-SDR. - * - * GNSS-SDR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNSS-SDR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . - * - * ------------------------------------------------------------------------- - */ - -#include "galileo_e5a_telemetry_decoder_cc.h" -#include "control_message_factory.h" -#include "convolutional.h" -#include "display.h" -#include -#include -#include -#include -#include -#include - - -#define GALILEO_E5a_CRC_ERROR_LIMIT 6 - -using google::LogMessage; - - -galileo_e5a_telemetry_decoder_cc_sptr -galileo_e5a_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump) -{ - return galileo_e5a_telemetry_decoder_cc_sptr(new galileo_e5a_telemetry_decoder_cc(satellite, dump)); -} - - -void galileo_e5a_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int *page_part_bits) -{ - Viterbi(page_part_bits, out0, state0, out1, state1, - page_part_symbols, KK, nn, DataLength); -} - - -void galileo_e5a_telemetry_decoder_cc::deinterleaver(int rows, int cols, double *in, double *out) -{ - for (int r = 0; r < rows; r++) - { - for (int c = 0; c < cols; c++) - { - out[c * rows + r] = in[r * cols + c]; - } - } -} - - -void galileo_e5a_telemetry_decoder_cc::decode_word(double *page_symbols, int frame_length) -{ - double page_symbols_deint[frame_length]; - // 1. De-interleave - deinterleaver(GALILEO_FNAV_INTERLEAVER_ROWS, GALILEO_FNAV_INTERLEAVER_COLS, page_symbols, page_symbols_deint); - - // 2. Viterbi decoder - // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) - // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180� - for (int i = 0; i < frame_length; i++) - { - if ((i + 1) % 2 == 0) - { - page_symbols_deint[i] = -page_symbols_deint[i]; - } - } - int page_bits[frame_length / 2]; - viterbi_decoder(page_symbols_deint, page_bits); - - // 3. Call the Galileo page decoder - std::string page_String; - for (int i = 0; i < frame_length; i++) - { - if (page_bits[i] > 0) - { - page_String.push_back('1'); - } - else - { - page_String.push_back('0'); - } - } - - // DECODE COMPLETE WORD (even + odd) and TEST CRC - d_nav.split_page(page_String); - if (d_nav.flag_CRC_test == true) - { - LOG(INFO) << "Galileo E5a CRC correct in channel " << d_channel << " from satellite " << d_satellite; - } - else - { - std::cout << "Galileo E5a CRC error in channel " << d_channel << " from satellite " << d_satellite << std::endl; - LOG(INFO) << "Galileo E5a CRC error in channel " << d_channel << " from satellite " << d_satellite; - } - - // 4. Push the new navigation data to the queues - if (d_nav.have_new_ephemeris() == true) - { - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_ephemeris()); - std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << TEXT_RESET << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_nav.have_new_iono_and_GST() == true) - { - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_iono()); - std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": iono/GST model parameters from satellite " << d_satellite << TEXT_RESET << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_nav.have_new_utc_model() == true) - { - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_utc_model()); - std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << TEXT_RESET << std::endl; - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } -} - - -galileo_e5a_telemetry_decoder_cc::galileo_e5a_telemetry_decoder_cc( - const Gnss_Satellite &satellite, bool dump) : gr::block("galileo_e5a_telemetry_decoder_cc", - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) -{ - // Ephemeris data port out - this->message_port_register_out(pmt::mp("telemetry")); - // initialize internal vars - d_dump = dump; - d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); - LOG(INFO) << "GALILEO E5A TELEMETRY PROCESSING: satellite " << d_satellite; - - // set the preamble - for (int i = 0; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++) - { - if (GALILEO_FNAV_PREAMBLE.at(i) == '0') - { - d_preambles_bits[i] = 1; - } - else - { - d_preambles_bits[i] = -1; - } - } - for (int i = 0; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++) - { - for (int k = 0; k < GALILEO_FNAV_CODES_PER_SYMBOL; k++) - { - d_preamble_samples[(i * GALILEO_FNAV_CODES_PER_SYMBOL) + k] = d_preambles_bits[i]; - } - } - - d_sample_counter = 0; - d_stat = 0; - corr_value = 0; - d_flag_preamble = false; - d_preamble_index = 0; - d_flag_frame_sync = false; - d_TOW_at_current_symbol = 0.0; - flag_TOW_set = false; - d_CRC_error_counter = 0; - d_channel = 0; - delta_t = 0.0; - d_symbol_counter = 0; - d_prompt_acum = 0.0; - flag_bit_start = true; - new_symbol = false; - required_symbols = GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS; - - // vars for Viterbi decoder - int max_states = 1 << mm; // 2^mm - g_encoder[0] = 121; // Polynomial G1 - g_encoder[1] = 91; // Polynomial G2 - out0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment())); - out1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment())); - state0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment())); - state1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment())); - // create appropriate transition matrices - nsc_transit(out0, state0, 0, g_encoder, KK, nn); - nsc_transit(out1, state1, 1, g_encoder, KK, nn); -} - - -galileo_e5a_telemetry_decoder_cc::~galileo_e5a_telemetry_decoder_cc() -{ - volk_gnsssdr_free(out0); - volk_gnsssdr_free(out1); - volk_gnsssdr_free(state0); - volk_gnsssdr_free(state1); - if (d_dump_file.is_open() == true) - { - try - { - d_dump_file.close(); - } - catch (const std::exception &ex) - { - LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); - } - } -} - - -void galileo_e5a_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite) -{ - d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); - DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite; - DLOG(INFO) << "Navigation Satellite set to " << d_satellite; -} - - -void galileo_e5a_telemetry_decoder_cc::set_channel(int channel) -{ - d_channel = channel; - LOG(INFO) << "Navigation channel set to " << channel; - // Enable data file logging - if (d_dump == true) - { - if (d_dump_file.is_open() == false) - { - try - { - d_dump_filename = "telemetry"; - d_dump_filename.append(boost::lexical_cast(d_channel)); - d_dump_filename.append(".dat"); - d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); - } - } - } -} - - -int galileo_e5a_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) -{ - int preamble_diff = 0; - - Gnss_Synchro *out = reinterpret_cast(output_items[0]); // Get the output buffer pointer - const Gnss_Synchro *in = reinterpret_cast(input_items[0]); // Get the input buffer pointer - - // 1. Copy the current tracking output - Gnss_Synchro current_sample = in[0]; - d_symbol_counter++; - if (flag_bit_start) - { - d_prompt_acum += current_sample.Prompt_I; - if (d_symbol_counter == GALILEO_FNAV_CODES_PER_SYMBOL) - { - current_sample.Prompt_I = d_prompt_acum / static_cast(GALILEO_FNAV_CODES_PER_SYMBOL); - d_symbol_history.push_back(current_sample); // add new symbol to the symbol queue - d_prompt_acum = 0.0; - d_symbol_counter = 0; - new_symbol = true; - } - } - else - { - if (current_sample.Prompt_I < 0.0) - { - d_preamble_init.push_back(1); - } - else - { - d_preamble_init.push_back(-1); - } - - if (d_preamble_init.size() == GALILEO_FNAV_CODES_PER_PREAMBLE) - { - std::deque::iterator iter; - int k = 0; - corr_value = 0; - for (iter = d_preamble_init.begin(); iter != d_preamble_init.end(); iter++) - { - corr_value += *iter * d_preamble_samples[k]; - k++; - } - if (abs(corr_value) == GALILEO_FNAV_CODES_PER_PREAMBLE) - { - d_symbol_counter = 0; - flag_bit_start = true; - corr_value = 0; - d_preamble_init.clear(); - d_symbol_history.clear(); - LOG(INFO) << "Bit start sync for Galileo E5a satellite " << d_satellite; - } - else - { - d_preamble_init.pop_front(); - } - } - } - d_sample_counter++; // count for the processed samples - consume_each(1); - - d_flag_preamble = false; - - if ((d_symbol_history.size() > required_symbols) && new_symbol) - { - // ****************** Preamble orrelation ****************** - corr_value = 0; - for (int i = 0; i < GALILEO_FNAV_PREAMBLE_LENGTH_BITS; i++) - { - if (d_symbol_history.at(i).Prompt_I < 0.0) // symbols clipping - { - corr_value -= d_preambles_bits[i]; - } - else - { - corr_value += d_preambles_bits[i]; - } - } - } - // ****************** Frame sync ****************** - if ((d_stat == 0) && new_symbol) // no preamble information - { - if (abs(corr_value) >= GALILEO_FNAV_PREAMBLE_LENGTH_BITS) - { - d_preamble_index = d_sample_counter; // record the preamble sample stamp - LOG(INFO) << "Preamble detection for Galileo E5a satellite " << d_satellite; - d_stat = 1; // enter into frame pre-detection status - } - } - else if ((d_stat == 1) && new_symbol) // possible preamble lock - { - if (abs(corr_value) >= GALILEO_FNAV_PREAMBLE_LENGTH_BITS) - { - // check preamble separation - preamble_diff = d_sample_counter - d_preamble_index; - if (preamble_diff == GALILEO_FNAV_CODES_PER_PAGE) - { - // try to decode frame - LOG(INFO) << "Starting page decoder for Galileo E5a satellite " << d_satellite; - d_preamble_index = d_sample_counter; // record the preamble sample stamp - d_stat = 2; - } - else if (preamble_diff > GALILEO_FNAV_CODES_PER_PAGE) - { - d_stat = 0; // start again - flag_bit_start = false; - LOG(INFO) << "Preamble diff = " << preamble_diff; - } - } - } - else if ((d_stat == 2) && new_symbol) - { - if (d_sample_counter == (d_preamble_index + GALILEO_FNAV_CODES_PER_PAGE)) - { - // NEW Galileo page part is received - // 0. fetch the symbols into an array - int frame_length = GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS; - double corr_sign = 0.0; - if (corr_value > 0) - { - corr_sign = -1.0; - } - else - { - corr_sign = 1.0; - } - for (int i = 0; i < frame_length; i++) - { - page_symbols[i] = corr_sign * d_symbol_history.at(i + GALILEO_FNAV_PREAMBLE_LENGTH_BITS).Prompt_I; // because last symbol of the preamble is just received now! - } - - // call the decoder - decode_word(page_symbols, frame_length); - if (d_nav.flag_CRC_test == true) - { - d_CRC_error_counter = 0; - d_flag_preamble = true; // valid preamble indicator (initialized to false every work()) - d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P) - if (!d_flag_frame_sync) - { - d_flag_frame_sync = true; - DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " - << d_symbol_history.at(0).Tracking_sample_counter << " [samples]"; - } - } - else - { - d_CRC_error_counter++; - d_preamble_index = d_sample_counter; // record the preamble sample stamp - if (d_CRC_error_counter > GALILEO_E5A_CRC_ERROR_LIMIT) - { - LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite; - d_flag_frame_sync = false; - d_stat = 0; - flag_bit_start = false; - } - } - } - } - new_symbol = false; - - // UPDATE GNSS SYNCHRO DATA - // Add the telemetry decoder information - if (d_flag_preamble and d_nav.flag_TOW_set) - // update TOW at the preamble instant - // We expect a preamble each 10 seconds (FNAV page period) - { - if (d_nav.flag_TOW_1 == true) - { - d_TOW_at_current_symbol = d_nav.FNAV_TOW_1 + (static_cast(GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD); - d_nav.flag_TOW_1 = false; - } - else if (d_nav.flag_TOW_2 == true) - { - d_TOW_at_current_symbol = d_nav.FNAV_TOW_2 + (static_cast(GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD); - d_nav.flag_TOW_2 = false; - } - else if (d_nav.flag_TOW_3 == true) - { - d_TOW_at_current_symbol = d_nav.FNAV_TOW_3 + (static_cast(GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD); - d_nav.flag_TOW_3 = false; - } - else if (d_nav.flag_TOW_4 == true) - { - d_TOW_at_current_symbol = d_nav.FNAV_TOW_4 + (static_cast(GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD); - d_nav.flag_TOW_4 = false; - } - else - { - d_TOW_at_current_symbol += GALILEO_E5a_CODE_PERIOD; - } - } - else // if there is not a new preamble, we define the TOW of the current symbol - { - d_TOW_at_current_symbol += GALILEO_E5a_CODE_PERIOD; - } - - //if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true) - if (d_flag_frame_sync and d_nav.flag_TOW_set) - { - current_sample.Flag_valid_word = true; - } - else - { - current_sample.Flag_valid_word = false; - } - - current_sample.TOW_at_current_symbol_ms = round(d_TOW_at_current_symbol * 1000.0); - - if (d_dump) - { - // MULTIPLEXED FILE RECORDING - Record results to file - try - { - double tmp_double; - unsigned long int tmp_ulong_int; - tmp_double = d_TOW_at_current_symbol; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_ulong_int = current_sample.Tracking_sample_counter; - d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(unsigned long int)); - tmp_double = 0.0; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "Exception writing Galileo E5a Telemetry Decoder dump file " << e.what(); - } - } - // remove used symbols from history - while (d_symbol_history.size() > required_symbols) - { - d_symbol_history.pop_front(); - } - // 3. Make the output - if (current_sample.Flag_valid_word) - { - out[0] = current_sample; - return 1; - } - else - { - return 0; - } -} diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h deleted file mode 100644 index 32400ca01..000000000 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_e5a_telemetry_decoder_cc.h +++ /dev/null @@ -1,126 +0,0 @@ -/*! - * \file galileo_e5a_telemetry_decoder_cc.cc - * \brief Implementation of a Galileo FNAV message demodulator block - * \author Marc Sales, 2014. marcsales92(at)gmail.com - * Javier Arribas, 2017. jarribas(at)cttc.es - * \based on work from: - *
        - *
      • Javier Arribas, 2011. jarribas(at)cttc.es - *
      - * - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) - * - * GNSS-SDR is a software defined Global Navigation - * Satellite Systems receiver - * - * This file is part of GNSS-SDR. - * - * GNSS-SDR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNSS-SDR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . - * - * ------------------------------------------------------------------------- - */ - -#ifndef GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_CC_H_ -#define GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_CC_H_ - -#include "Galileo_E5a.h" -#include "gnss_satellite.h" -#include "galileo_fnav_message.h" -#include "galileo_ephemeris.h" -#include "galileo_almanac.h" -#include "galileo_iono.h" -#include "galileo_utc_model.h" -#include "gnss_synchro.h" -#include -#include -#include -#include - - -class galileo_e5a_telemetry_decoder_cc; - -typedef boost::shared_ptr galileo_e5a_telemetry_decoder_cc_sptr; - -galileo_e5a_telemetry_decoder_cc_sptr galileo_e5a_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - - -/*! - * \brief This class implements a block that decodes the FNAV data defined in Galileo ICD - * - */ -class galileo_e5a_telemetry_decoder_cc : public gr::block -{ -public: - ~galileo_e5a_telemetry_decoder_cc(); - void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN - void set_channel(int channel); //!< Set receiver's channel - /*! - * \brief This is where all signal processing takes place - */ - int general_work(int noutput_items, gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - -private: - friend galileo_e5a_telemetry_decoder_cc_sptr - galileo_e5a_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - galileo_e5a_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - - void viterbi_decoder(double *page_part_symbols, int *page_part_bits); - - void deinterleaver(int rows, int cols, double *in, double *out); - - void decode_word(double *page_symbols, int frame_length); - - int d_preambles_bits[GALILEO_FNAV_PREAMBLE_LENGTH_BITS]; - int d_preamble_samples[GALILEO_FNAV_CODES_PER_PREAMBLE]; - std::deque d_preamble_init; - int d_stat; - int d_CRC_error_counter; - int d_channel; - int d_symbol_counter; - int corr_value; - unsigned int required_symbols; - long unsigned int d_sample_counter; - long unsigned int d_preamble_index; - bool d_flag_frame_sync; - bool d_flag_preamble; - bool d_dump; - bool flag_TOW_set; - bool flag_bit_start; - bool new_symbol; - double d_prompt_acum; - double page_symbols[GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS]; - double d_TOW_at_current_symbol; - double delta_t; //GPS-GALILEO time offset - std::string d_dump_filename; - std::ofstream d_dump_file; - std::deque d_symbol_history; - Gnss_Satellite d_satellite; - // navigation message vars - Galileo_Fnav_Message d_nav; - - // vars for Viterbi decoder - int *out0, *out1, *state0, *state1; - int g_encoder[2]; - const int nn = 2; // Coding rate 1/n - const int KK = 7; // Constraint Length - int mm = KK - 1; - const int CodeLength = 488; - int DataLength = (CodeLength / nn) - mm; -}; - -#endif /* GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_CC_H_ */ diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.cc new file mode 100644 index 000000000..da1851fad --- /dev/null +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.cc @@ -0,0 +1,787 @@ +/*! + * \file galileo_telemetry_decoder_cc.cc + * \brief Implementation of a Galileo unified INAV and FNAV message demodulator block + * \author Javier Arribas 2018. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "galileo_telemetry_decoder_cc.h" +#include "control_message_factory.h" +#include "convolutional.h" +#include "display.h" +#include "gnss_synchro.h" +#include +#include +#include +#include +#include + + +#define CRC_ERROR_LIMIT 6 + +using google::LogMessage; + + +galileo_telemetry_decoder_cc_sptr +galileo_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, int frame_type, bool dump) +{ + return galileo_telemetry_decoder_cc_sptr(new galileo_telemetry_decoder_cc(satellite, frame_type, dump)); +} + + +void galileo_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits) +{ + Viterbi(page_part_bits, out0, state0, out1, state1, + page_part_symbols, KK, nn, DataLength); +} + + +void galileo_telemetry_decoder_cc::deinterleaver(int32_t rows, int32_t cols, double *in, double *out) +{ + for (int32_t r = 0; r < rows; r++) + { + for (int32_t c = 0; c < cols; c++) + { + out[c * rows + r] = in[r * cols + c]; + } + } +} + + +galileo_telemetry_decoder_cc::galileo_telemetry_decoder_cc( + const Gnss_Satellite &satellite, int frame_type, + bool dump) : gr::block("galileo_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) +{ + // Ephemeris data port out + this->message_port_register_out(pmt::mp("telemetry")); + // initialize internal vars + d_dump = dump; + d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); + d_frame_type = frame_type; + LOG(INFO) << "Initializing GALILEO UNIFIED TELEMETRY DECODER"; + + switch (d_frame_type) + { + case 1: // INAV + { + d_PRN_code_period_ms = static_cast(GALILEO_E1_CODE_PERIOD_MS); + d_samples_per_symbol = Galileo_E1_B_SAMPLES_PER_SYMBOL; + d_bits_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS; + // set the preamble + d_samples_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol; + d_preamble_period_symbols = GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS; + d_required_symbols = static_cast(GALILEO_INAV_PAGE_SYMBOLS) + d_samples_per_preamble; + // preamble bits to sampled symbols + d_preamble_samples = static_cast(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); + d_secondary_code_samples = nullptr; + d_frame_length_symbols = GALILEO_INAV_PAGE_PART_SYMBOLS - GALILEO_INAV_PREAMBLE_LENGTH_BITS; + CodeLength = GALILEO_INAV_PAGE_PART_SYMBOLS - GALILEO_INAV_PREAMBLE_LENGTH_BITS; + DataLength = (CodeLength / nn) - mm; + break; + } + case 2: // FNAV + { + d_PRN_code_period_ms = static_cast(GALILEO_E5a_CODE_PERIOD_MS); + d_samples_per_symbol = GALILEO_FNAV_CODES_PER_SYMBOL; + d_bits_per_preamble = GALILEO_FNAV_PREAMBLE_LENGTH_BITS; + // set the preamble + d_samples_per_preamble = GALILEO_FNAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol; + d_preamble_period_symbols = GALILEO_FNAV_CODES_PER_PAGE; + d_required_symbols = static_cast(GALILEO_FNAV_SYMBOLS_PER_PAGE) * d_samples_per_symbol + d_samples_per_preamble; + // preamble bits to sampled symbols + d_preamble_samples = static_cast(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); + d_secondary_code_samples = static_cast(volk_gnsssdr_malloc(Galileo_E5a_I_SECONDARY_CODE_LENGTH * sizeof(int32_t), volk_gnsssdr_get_alignment())); + d_frame_length_symbols = GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS; + CodeLength = GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS; + DataLength = (CodeLength / nn) - mm; + for (int32_t i = 0; i < Galileo_E5a_I_SECONDARY_CODE_LENGTH; i++) + { + if (Galileo_E5a_I_SECONDARY_CODE.at(i) == '1') + { + d_secondary_code_samples[i] = 1; + } + else + { + d_secondary_code_samples[i] = -1; + } + } + break; + } + default: + d_bits_per_preamble = 0; + d_samples_per_preamble = 0; + d_preamble_period_symbols = 0; + d_preamble_samples = nullptr; + d_secondary_code_samples = nullptr; + d_samples_per_symbol = 0U; + d_PRN_code_period_ms = 0U; + d_required_symbols = 0U; + d_frame_length_symbols = 0.0; + CodeLength = 0; + DataLength = 0; + std::cout << "Galileo unified telemetry decoder error: Unknown frame type " << std::endl; + } + + d_page_part_symbols = static_cast(volk_gnsssdr_malloc(d_frame_length_symbols * sizeof(double), volk_gnsssdr_get_alignment())); + int32_t n = 0; + for (int32_t i = 0; i < d_bits_per_preamble; i++) + { + switch (d_frame_type) + { + case 1: // INAV + { + if (GALILEO_INAV_PREAMBLE.at(i) == '1') + { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) + { + d_preamble_samples[n] = 1; + n++; + } + } + else + { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) + { + d_preamble_samples[n] = -1; + n++; + } + } + break; + } + case 2: // FNAV for E5a-I + { + // Galileo E5a data channel (E5a-I) still has a secondary code + int m = 0; + if (GALILEO_FNAV_PREAMBLE.at(i) == '1') + { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) + { + d_preamble_samples[n] = d_secondary_code_samples[m]; + n++; + m++; + m = m % Galileo_E5a_I_SECONDARY_CODE_LENGTH; + } + } + else + { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) + { + d_preamble_samples[n] = -d_secondary_code_samples[m]; + n++; + m++; + m = m % Galileo_E5a_I_SECONDARY_CODE_LENGTH; + } + } + break; + } + } + } + d_sample_counter = 0ULL; + d_stat = 0; + d_preamble_index = 0ULL; + + d_flag_frame_sync = false; + + d_flag_parity = false; + d_TOW_at_current_symbol_ms = 0; + d_TOW_at_Preamble_ms = 0; + delta_t = 0; + d_CRC_error_counter = 0; + flag_even_word_arrived = 0; + d_flag_preamble = false; + d_channel = 0; + flag_TOW_set = false; + + // vars for Viterbi decoder + int32_t max_states = 1 << mm; // 2^mm + g_encoder[0] = 121; // Polynomial G1 + g_encoder[1] = 91; // Polynomial G2 + out0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + out1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + state0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + state1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + // create appropriate transition matrices + nsc_transit(out0, state0, 0, g_encoder, KK, nn); + nsc_transit(out1, state1, 1, g_encoder, KK, nn); +} + + +galileo_telemetry_decoder_cc::~galileo_telemetry_decoder_cc() +{ + volk_gnsssdr_free(d_preamble_samples); + if (d_frame_type == 2) + { + volk_gnsssdr_free(d_secondary_code_samples); + } + volk_gnsssdr_free(d_page_part_symbols); + volk_gnsssdr_free(out0); + volk_gnsssdr_free(out1); + volk_gnsssdr_free(state0); + volk_gnsssdr_free(state1); + if (d_dump_file.is_open() == true) + { + try + { + d_dump_file.close(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); + } + } +} + + +void galileo_telemetry_decoder_cc::decode_INAV_word(double *page_part_symbols, int32_t frame_length) +{ + // 1. De-interleave + double *page_part_symbols_deint = static_cast(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment())); + deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS, GALILEO_INAV_INTERLEAVER_COLS, page_part_symbols, page_part_symbols_deint); + + // 2. Viterbi decoder + // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) + // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180º + for (int32_t i = 0; i < frame_length; i++) + { + if ((i + 1) % 2 == 0) + { + page_part_symbols_deint[i] = -page_part_symbols_deint[i]; + } + } + + int32_t *page_part_bits = static_cast(volk_gnsssdr_malloc((frame_length / 2) * sizeof(int32_t), volk_gnsssdr_get_alignment())); + viterbi_decoder(page_part_symbols_deint, page_part_bits); + volk_gnsssdr_free(page_part_symbols_deint); + + // 3. Call the Galileo page decoder + std::string page_String; + for (int32_t i = 0; i < (frame_length / 2); i++) + { + if (page_part_bits[i] > 0) + { + page_String.push_back('1'); + } + else + { + page_String.push_back('0'); + } + } + + if (page_part_bits[0] == 1) + { + // DECODE COMPLETE WORD (even + odd) and TEST CRC + d_inav_nav.split_page(page_String, flag_even_word_arrived); + if (d_inav_nav.flag_CRC_test == true) + { + LOG(INFO) << "Galileo E1 CRC correct in channel " << d_channel << " from satellite " << d_satellite; + } + else + { + LOG(INFO) << "Galileo E1 CRC error in channel " << d_channel << " from satellite " << d_satellite; + } + flag_even_word_arrived = 0; + } + else + { + // STORE HALF WORD (even page) + d_inav_nav.split_page(page_String.c_str(), flag_even_word_arrived); + flag_even_word_arrived = 1; + } + volk_gnsssdr_free(page_part_bits); + + // 4. Push the new navigation data to the queues + if (d_inav_nav.have_new_ephemeris() == true) + { + // get object for this SV (mandatory) + std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_ephemeris()); + std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + if (d_inav_nav.have_new_iono_and_GST() == true) + { + // get object for this SV (mandatory) + std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_iono()); + std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": iono/GST model parameters from satellite " << d_satellite << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + if (d_inav_nav.have_new_utc_model() == true) + { + // get object for this SV (mandatory) + std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_utc_model()); + std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + delta_t = tmp_obj->A_0G_10 + tmp_obj->A_1G_10 * (static_cast(d_TOW_at_current_symbol_ms) / 1000.0 - tmp_obj->t_0G_10 + 604800 * (fmod((d_inav_nav.WN_0 - tmp_obj->WN_0G_10), 64))); + DLOG(INFO) << "delta_t=" << delta_t << "[s]"; + } + if (d_inav_nav.have_new_almanac() == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_almanac()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + //debug + std::cout << "Galileo E1 I/NAV almanac received in channel " << d_channel << " from satellite " << d_satellite << std::endl; + DLOG(INFO) << "Current parameters:"; + DLOG(INFO) << "d_TOW_at_current_symbol_ms=" << d_TOW_at_current_symbol_ms; + DLOG(INFO) << "d_nav.WN_0=" << d_inav_nav.WN_0; + } +} + + +void galileo_telemetry_decoder_cc::decode_FNAV_word(double *page_symbols, int32_t frame_length) +{ + // 1. De-interleave + double *page_symbols_deint = static_cast(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment())); + deinterleaver(GALILEO_FNAV_INTERLEAVER_ROWS, GALILEO_FNAV_INTERLEAVER_COLS, page_symbols, page_symbols_deint); + + // 2. Viterbi decoder + // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) + // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180� + for (int32_t i = 0; i < frame_length; i++) + { + if ((i + 1) % 2 == 0) + { + page_symbols_deint[i] = -page_symbols_deint[i]; + } + } + int32_t *page_bits = static_cast(volk_gnsssdr_malloc((frame_length / 2) * sizeof(int32_t), volk_gnsssdr_get_alignment())); + viterbi_decoder(page_symbols_deint, page_bits); + volk_gnsssdr_free(page_symbols_deint); + + // 3. Call the Galileo page decoder + std::string page_String; + for (int32_t i = 0; i < frame_length; i++) + { + if (page_bits[i] > 0) + { + page_String.push_back('1'); + } + else + { + page_String.push_back('0'); + } + } + volk_gnsssdr_free(page_bits); + + // DECODE COMPLETE WORD (even + odd) and TEST CRC + d_fnav_nav.split_page(page_String); + if (d_fnav_nav.flag_CRC_test == true) + { + LOG(INFO) << "Galileo E5a CRC correct in channel " << d_channel << " from satellite " << d_satellite; + } + else + { + LOG(INFO) << "Galileo E5a CRC error in channel " << d_channel << " from satellite " << d_satellite; + } + + // 4. Push the new navigation data to the queues + if (d_fnav_nav.have_new_ephemeris() == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_fnav_nav.get_ephemeris()); + std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << TEXT_RESET << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + if (d_fnav_nav.have_new_iono_and_GST() == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_fnav_nav.get_iono()); + std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": iono/GST model parameters from satellite " << d_satellite << TEXT_RESET << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + if (d_fnav_nav.have_new_utc_model() == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_fnav_nav.get_utc_model()); + std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << TEXT_RESET << std::endl; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } +} + + +void galileo_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite) +{ + d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); + DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite; + DLOG(INFO) << "Navigation Satellite set to " << d_satellite; +} + + +void galileo_telemetry_decoder_cc::set_channel(int32_t channel) +{ + d_channel = channel; + LOG(INFO) << "Navigation channel set to " << channel; + // ############# ENABLE DATA FILE LOG ################# + if (d_dump == true) + { + if (d_dump_file.is_open() == false) + { + try + { + d_dump_filename = "telemetry"; + d_dump_filename.append(boost::lexical_cast(d_channel)); + d_dump_filename.append(".dat"); + d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); + } + } + } +} + + +int galileo_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + int32_t corr_value = 0; + int32_t preamble_diff = 0; + + Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer + const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer + + Gnss_Synchro current_symbol; // structure to save the synchronization information and send the output object to the next block + // 1. Copy the current tracking output + current_symbol = in[0][0]; + // add new symbol to the symbol queue + d_symbol_history.push_back(current_symbol.Prompt_I); + d_sample_counter++; // count for the processed samples + consume_each(1); + d_flag_preamble = false; + + if (d_symbol_history.size() > d_required_symbols) + { + // TODO Optimize me! + // ******* preamble correlation ******** + for (int32_t i = 0; i < d_samples_per_preamble; i++) + { + if (d_symbol_history.at(i) < 0.0) // symbols clipping + { + corr_value -= d_preamble_samples[i]; + } + else + { + corr_value += d_preamble_samples[i]; + } + } + } + + // ******* frame sync ****************** + switch (d_stat) + { + case 0: // no preamble information + { + if (abs(corr_value) >= d_samples_per_preamble) + { + d_preamble_index = d_sample_counter; // record the preamble sample stamp + LOG(INFO) << "Preamble detection for Galileo satellite " << this->d_satellite; + d_stat = 1; // enter into frame pre-detection status + } + break; + } + case 1: // possible preamble lock + { + if (abs(corr_value) >= d_samples_per_preamble) + { + // check preamble separation + preamble_diff = static_cast(d_sample_counter - d_preamble_index); + if (abs(preamble_diff - d_preamble_period_symbols) == 0) + { + // try to decode frame + LOG(INFO) << "Starting page decoder for Galileo satellite " << this->d_satellite; + d_preamble_index = d_sample_counter; // record the preamble sample stamp + d_stat = 2; + } + else + { + if (preamble_diff > d_preamble_period_symbols) + { + d_stat = 0; // start again + } + } + } + break; + } + case 2: //preamble acquired + { + if (d_sample_counter == d_preamble_index + static_cast(d_preamble_period_symbols)) + { + // call the decoder + switch (d_frame_type) + { + case 1: // INAV + // NEW Galileo page part is received + // 0. fetch the symbols into an array + if (corr_value > 0) //normal PLL lock + { + for (uint32_t i = 0; i < d_frame_length_symbols; i++) + { + d_page_part_symbols[i] = d_symbol_history.at(i + d_samples_per_preamble); // because last symbol of the preamble is just received now! + } + } + else //180 deg. inverted carrier phase PLL lock + { + for (uint32_t i = 0; i < d_frame_length_symbols; i++) + { + d_page_part_symbols[i] = d_symbol_history.at(i + d_samples_per_preamble); // because last symbol of the preamble is just received now! + } + } + decode_INAV_word(d_page_part_symbols, d_frame_length_symbols); + break; + case 2: // FNAV + // NEW Galileo page part is received + // 0. fetch the symbols into an array + if (corr_value > 0) //normal PLL lock + { + int k = 0; + for (uint32_t i = 0; i < d_frame_length_symbols; i++) + { + d_page_part_symbols[i] = 0; + for (uint32_t m = 0; m < d_samples_per_symbol; m++) + { + d_page_part_symbols[i] += static_cast(d_secondary_code_samples[k]) * d_symbol_history.at(i * d_samples_per_symbol + d_samples_per_preamble + m); // because last symbol of the preamble is just received now! + k++; + k = k % Galileo_E5a_I_SECONDARY_CODE_LENGTH; + } + } + } + else //180 deg. inverted carrier phase PLL lock + { + int k = 0; + for (uint32_t i = 0; i < d_frame_length_symbols; i++) + { + d_page_part_symbols[i] = 0; + for (uint32_t m = 0; m < d_samples_per_symbol; m++) //integrate samples into symbols + { + d_page_part_symbols[i] -= static_cast(d_secondary_code_samples[k]) * d_symbol_history.at(i * d_samples_per_symbol + d_samples_per_preamble + m); // because last symbol of the preamble is just received now! + k++; + k = k % Galileo_E5a_I_SECONDARY_CODE_LENGTH; + } + } + } + decode_FNAV_word(d_page_part_symbols, d_frame_length_symbols); + break; + default: + return -1; + break; + } + + if (d_inav_nav.flag_CRC_test == true or d_fnav_nav.flag_CRC_test == true) + { + d_CRC_error_counter = 0; + d_flag_preamble = true; // valid preamble indicator (initialized to false every work()) + d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P) + if (!d_flag_frame_sync) + { + d_flag_frame_sync = true; + DLOG(INFO) << " Frame sync SAT " << this->d_satellite; + } + } + else + { + d_CRC_error_counter++; + d_preamble_index = d_sample_counter; // record the preamble sample stamp + if (d_CRC_error_counter > CRC_ERROR_LIMIT) + { + LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite; + d_flag_frame_sync = false; + d_stat = 0; + d_TOW_at_current_symbol_ms = 0; + d_TOW_at_Preamble_ms = 0; + d_fnav_nav.flag_TOW_set = false; + d_inav_nav.flag_TOW_set = false; + } + } + } + break; + } + } + + // UPDATE GNSS SYNCHRO DATA + // 2. Add the telemetry decoder information + if (this->d_flag_preamble == true) + // update TOW at the preamble instant + { + switch (d_frame_type) + { + case 1: // INAV + { + if (d_inav_nav.flag_TOW_set == true) + { + if (d_inav_nav.flag_TOW_5 == true) // page 5 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec) + { + // TOW_5 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay + d_TOW_at_Preamble_ms = static_cast(d_inav_nav.TOW_5 * 1000.0); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast(GALILEO_INAV_PAGE_PART_MS + (d_required_symbols + 1) * GALILEO_E1_CODE_PERIOD_MS); + d_inav_nav.flag_TOW_5 = false; + } + + else if (d_inav_nav.flag_TOW_6 == true) // page 6 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec) + { + // TOW_6 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay + d_TOW_at_Preamble_ms = static_cast(d_inav_nav.TOW_6 * 1000.0); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast(GALILEO_INAV_PAGE_PART_MS + (d_required_symbols + 1) * GALILEO_E1_CODE_PERIOD_MS); + d_inav_nav.flag_TOW_6 = false; + } + else + { + // this page has no timing information + d_TOW_at_current_symbol_ms += static_cast(GALILEO_E1_CODE_PERIOD_MS); // + GALILEO_INAV_PAGE_PART_SYMBOLS*GALILEO_E1_CODE_PERIOD; + } + } + break; + } + case 2: // FNAV + { + if (d_fnav_nav.flag_TOW_set == true) + { + if (d_fnav_nav.flag_TOW_1 == true) + { + d_TOW_at_Preamble_ms = static_cast(d_fnav_nav.FNAV_TOW_1 * 1000.0); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((d_required_symbols + 1) * GALILEO_E5a_CODE_PERIOD_MS); + //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); + d_fnav_nav.flag_TOW_1 = false; + } + else if (d_fnav_nav.flag_TOW_2 == true) + { + d_TOW_at_Preamble_ms = static_cast(d_fnav_nav.FNAV_TOW_2 * 1000.0); + //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((d_required_symbols + 1) * GALILEO_E5a_CODE_PERIOD_MS); + d_fnav_nav.flag_TOW_2 = false; + } + else if (d_fnav_nav.flag_TOW_3 == true) + { + d_TOW_at_Preamble_ms = static_cast(d_fnav_nav.FNAV_TOW_3 * 1000.0); + //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((d_required_symbols + 1) * GALILEO_E5a_CODE_PERIOD_MS); + d_fnav_nav.flag_TOW_3 = false; + } + else if (d_fnav_nav.flag_TOW_4 == true) + { + d_TOW_at_Preamble_ms = static_cast(d_fnav_nav.FNAV_TOW_4 * 1000.0); + //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); + d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((d_required_symbols + 1) * GALILEO_E5a_CODE_PERIOD_MS); + d_fnav_nav.flag_TOW_4 = false; + } + else + { + d_TOW_at_current_symbol_ms += static_cast(GALILEO_E5a_CODE_PERIOD_MS); + } + break; + } + } + } + } + else // if there is not a new preamble, we define the TOW of the current symbol + { + switch (d_frame_type) + { + case 1: // INAV + { + if (d_inav_nav.flag_TOW_set == true) + { + d_TOW_at_current_symbol_ms += d_PRN_code_period_ms; + } + break; + } + case 2: // FNAV + { + if (d_fnav_nav.flag_TOW_set == true) + { + d_TOW_at_current_symbol_ms += d_PRN_code_period_ms; + } + break; + } + } + } + + // remove used symbols from history + // todo: Use circular buffer here + if (d_symbol_history.size() > d_required_symbols) + { + d_symbol_history.pop_front(); + } + + switch (d_frame_type) + { + case 1: // INAV + { + if (d_inav_nav.flag_TOW_set) + { + if (d_inav_nav.flag_GGTO_1 == true and d_inav_nav.flag_GGTO_2 == true and d_inav_nav.flag_GGTO_3 == true and d_inav_nav.flag_GGTO_4 == true) // all GGTO parameters arrived + { + delta_t = d_inav_nav.A_0G_10 + d_inav_nav.A_1G_10 * (static_cast(d_TOW_at_current_symbol_ms) / 1000.0 - d_inav_nav.t_0G_10 + 604800.0 * (fmod((d_inav_nav.WN_0 - d_inav_nav.WN_0G_10), 64.0))); + } + + current_symbol.Flag_valid_word = true; + } + break; + } + + case 2: // FNAV + { + if (d_fnav_nav.flag_TOW_set) + { + current_symbol.Flag_valid_word = true; + } + break; + } + } + + if (d_inav_nav.flag_TOW_set or d_fnav_nav.flag_TOW_set) + { + 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. + // current_symbol.TOW_at_current_symbol_ms -= delta_t; //Galileo to GPS TOW + + if (d_dump == true) + { + // MULTIPLEXED FILE RECORDING - Record results to file + try + { + double tmp_double; + uint64_t tmp_ulong_int; + tmp_double = static_cast(d_TOW_at_current_symbol_ms) / 1000.0; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_ulong_int = current_symbol.Tracking_sample_counter; + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); + tmp_double = static_cast(d_TOW_at_Preamble_ms) / 1000.0; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "Exception writing observables dump file " << e.what(); + } + } + // 3. Make the output (copy the object contents to the GNURadio reserved memory) + *out[0] = current_symbol; + return 1; + } + else + { + return 0; + } +} diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.h new file mode 100644 index 000000000..6dc96f309 --- /dev/null +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_cc.h @@ -0,0 +1,136 @@ +/*! + * \file galileo_telemetry_decoder_cc.h + * \brief Implementation of a Galileo unified INAV and FNAV message demodulator block + * \author Javier Arribas 2018. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GALILEO_TELEMETRY_DECODER_CC_H +#define GNSS_SDR_GALILEO_TELEMETRY_DECODER_CC_H + + +#include "Galileo_E1.h" +#include "Galileo_E5a.h" +#include "galileo_navigation_message.h" +#include "galileo_fnav_message.h" +#include "galileo_ephemeris.h" +#include "galileo_almanac_helper.h" +#include "galileo_iono.h" +#include "galileo_utc_model.h" +#include "gnss_satellite.h" +#include "gnss_synchro.h" +#include +#include +#include + + +class galileo_telemetry_decoder_cc; + +typedef boost::shared_ptr galileo_telemetry_decoder_cc_sptr; + +galileo_telemetry_decoder_cc_sptr galileo_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, int frame_type, bool dump); + +/*! + * \brief This class implements a block that decodes the INAV and FNAV data defined in Galileo ICD + */ +class galileo_telemetry_decoder_cc : public gr::block +{ +public: + ~galileo_telemetry_decoder_cc(); + void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN + void set_channel(int32_t channel); //!< Set receiver's channel + int32_t flag_even_word_arrived; + + /*! + * \brief This is where all signal processing takes place + */ + int general_work(int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + +private: + friend galileo_telemetry_decoder_cc_sptr + galileo_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, int frame_type, bool dump); + galileo_telemetry_decoder_cc(const Gnss_Satellite &satellite, int frame_type, bool dump); + + void viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits); + + void deinterleaver(int32_t rows, int32_t cols, double *in, double *out); + + void decode_INAV_word(double *symbols, int32_t frame_length); + void decode_FNAV_word(double *page_symbols, int32_t frame_length); + + int d_frame_type; + int32_t d_bits_per_preamble; + int32_t d_samples_per_preamble; + int32_t d_preamble_period_symbols; + int32_t *d_preamble_samples; + int32_t *d_secondary_code_samples; + uint32_t d_samples_per_symbol; + uint32_t d_PRN_code_period_ms; + uint32_t d_required_symbols; + uint32_t d_frame_length_symbols; + double *d_page_part_symbols; + + std::deque d_symbol_history; + + uint64_t d_sample_counter; + uint64_t d_preamble_index; + uint32_t d_stat; + bool d_flag_frame_sync; + + bool d_flag_parity; + bool d_flag_preamble; + int32_t d_CRC_error_counter; + + // navigation message vars + Galileo_Navigation_Message d_inav_nav; + Galileo_Fnav_Message d_fnav_nav; + + bool d_dump; + Gnss_Satellite d_satellite; + int32_t d_channel; + + uint32_t d_TOW_at_Preamble_ms; + uint32_t d_TOW_at_current_symbol_ms; + + bool flag_TOW_set; + double delta_t; //GPS-GALILEO time offset + + std::string d_dump_filename; + std::ofstream d_dump_file; + + // vars for Viterbi decoder + int32_t *out0, *out1, *state0, *state1; + int32_t g_encoder[2]; + const int32_t nn = 2; // Coding rate 1/n + const int32_t KK = 7; // Constraint Length + int32_t mm = KK - 1; + int32_t CodeLength; + int32_t DataLength; +}; + +#endif diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc index 4c246e90c..49c40a082 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.cc @@ -65,18 +65,18 @@ glonass_l1_ca_telemetry_decoder_cc::glonass_l1_ca_telemetry_decoder_cc( d_samples_per_symbol = (GLONASS_L1_CA_CODE_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS) / GLONASS_L1_CA_SYMBOL_RATE_BPS; // Set the preamble information - unsigned short int preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS] = GLONASS_GNAV_PREAMBLE; + uint16_t preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS] = GLONASS_GNAV_PREAMBLE; // Since preamble rate is different than navigation data rate we use a constant d_symbols_per_preamble = GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS; - memcpy(static_cast(this->d_preambles_bits), static_cast(preambles_bits), GLONASS_GNAV_PREAMBLE_LENGTH_BITS * sizeof(unsigned short int)); + memcpy(static_cast(this->d_preambles_bits), static_cast(preambles_bits), GLONASS_GNAV_PREAMBLE_LENGTH_BITS * sizeof(uint16_t)); // preamble bits to sampled symbols - d_preambles_symbols = static_cast(malloc(sizeof(signed int) * d_symbols_per_preamble)); - int n = 0; - for (int i = 0; i < GLONASS_GNAV_PREAMBLE_LENGTH_BITS; i++) + d_preambles_symbols = static_cast(malloc(sizeof(int32_t) * d_symbols_per_preamble)); + int32_t n = 0; + for (int32_t i = 0; i < GLONASS_GNAV_PREAMBLE_LENGTH_BITS; i++) { - for (unsigned int j = 0; j < GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_PREAMBLE_BIT; j++) + for (uint32_t j = 0; j < GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_PREAMBLE_BIT; j++) { if (d_preambles_bits[i] == 1) { @@ -89,9 +89,9 @@ glonass_l1_ca_telemetry_decoder_cc::glonass_l1_ca_telemetry_decoder_cc( n++; } } - d_sample_counter = 0; + d_sample_counter = 0ULL; d_stat = 0; - d_preamble_index = 0; + d_preamble_index = 0ULL; d_flag_frame_sync = false; @@ -124,10 +124,10 @@ glonass_l1_ca_telemetry_decoder_cc::~glonass_l1_ca_telemetry_decoder_cc() } -void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, int frame_length) +void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, int32_t frame_length) { double chip_acc = 0.0; - int chip_acc_counter = 0; + int32_t chip_acc_counter = 0; // 1. Transform from symbols to bits std::string bi_binary_code; @@ -135,7 +135,7 @@ void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, in std::string data_bits; // Group samples into bi-binary code - for (int i = 0; i < (frame_length); i++) + for (int32_t i = 0; i < (frame_length); i++) { chip_acc += frame_symbols[i]; chip_acc_counter += 1; @@ -157,7 +157,7 @@ void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, in } } // Convert from bi-binary code to relative code - for (int i = 0; i < (GLONASS_GNAV_STRING_BITS); i++) + for (int32_t i = 0; i < (GLONASS_GNAV_STRING_BITS); i++) { if (bi_binary_code[2 * i] == '1' && bi_binary_code[2 * i + 1] == '0') { @@ -170,7 +170,7 @@ void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, in } // Convert from relative code to data bits data_bits.push_back('0'); - for (int i = 1; i < (GLONASS_GNAV_STRING_BITS); i++) + for (int32_t i = 1; i < (GLONASS_GNAV_STRING_BITS); i++) { data_bits.push_back(((relative_code[i - 1] - '0') ^ (relative_code[i] - '0')) + '0'); } @@ -207,7 +207,7 @@ void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, in } if (d_nav.have_new_almanac() == true) { - unsigned int slot_nbr = d_nav.i_alm_satellite_slot_number; + uint32_t slot_nbr = d_nav.i_alm_satellite_slot_number; std::shared_ptr tmp_obj = std::make_shared(d_nav.get_almanac(slot_nbr)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); LOG(INFO) << "GLONASS GNAV Almanac have been received in channel" << d_channel << " in slot number " << slot_nbr; @@ -232,7 +232,7 @@ void glonass_l1_ca_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &sat } -void glonass_l1_ca_telemetry_decoder_cc::set_channel(int channel) +void glonass_l1_ca_telemetry_decoder_cc::set_channel(int32_t channel) { d_channel = channel; LOG(INFO) << "Navigation channel set to " << channel; @@ -262,8 +262,8 @@ void glonass_l1_ca_telemetry_decoder_cc::set_channel(int channel) int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - int corr_value = 0; - int preamble_diff = 0; + int32_t corr_value = 0; + int32_t preamble_diff = 0; Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer @@ -276,12 +276,12 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu consume_each(1); d_flag_preamble = false; - unsigned int required_symbols = GLONASS_GNAV_STRING_SYMBOLS; + uint32_t required_symbols = GLONASS_GNAV_STRING_SYMBOLS; if (d_symbol_history.size() > required_symbols) { // ******* preamble correlation ******** - for (int i = 0; i < d_symbols_per_preamble; i++) + for (int32_t i = 0; i < d_symbols_per_preamble; i++) { if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping { @@ -312,9 +312,9 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu if (abs(corr_value) >= d_symbols_per_preamble) { // check preamble separation - preamble_diff = d_sample_counter - d_preamble_index; + preamble_diff = static_cast(d_sample_counter - d_preamble_index); // Record the PRN start sample index associated to the preamble - d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; + d_preamble_time_samples = static_cast(d_symbol_history.at(0).Tracking_sample_counter); if (abs(preamble_diff - GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) == 0) { // try to decode frame @@ -335,15 +335,15 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu else if (d_stat == 2) { // FIXME: The preamble index marks the first symbol of the string count. Here I just wait for another full string to be received before processing - if (d_sample_counter == d_preamble_index + GLONASS_GNAV_STRING_SYMBOLS) + if (d_sample_counter == d_preamble_index + static_cast(GLONASS_GNAV_STRING_SYMBOLS)) { // NEW GLONASS string received // 0. fetch the symbols into an array - int string_length = GLONASS_GNAV_STRING_SYMBOLS - d_symbols_per_preamble; + int32_t string_length = GLONASS_GNAV_STRING_SYMBOLS - d_symbols_per_preamble; double string_symbols[GLONASS_GNAV_DATA_SYMBOLS] = {0}; // ******* SYMBOL TO BIT ******* - for (int i = 0; i < string_length; i++) + for (int32_t i = 0; i < string_length; i++) { if (corr_value > 0) { @@ -415,7 +415,7 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu current_symbol.PRN = this->d_satellite.get_PRN(); current_symbol.TOW_at_current_symbol_ms = round(d_TOW_at_current_symbol * 1000.0); // todo: glonass time to gps time should be done in observables block - // current_symbol.TOW_at_current_symbol_ms -= -= static_cast(delta_t) * 1000; // Galileo to GPS TOW + // current_symbol.TOW_at_current_symbol_ms -= -= static_cast(delta_t) * 1000; // Galileo to GPS TOW if (d_dump == true) { @@ -423,11 +423,11 @@ int glonass_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu try { double tmp_double; - unsigned long int tmp_ulong_int; + uint64_t tmp_ulong_int; tmp_double = d_TOW_at_current_symbol; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_ulong_int = current_symbol.Tracking_sample_counter; - d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); tmp_double = 0; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.h index fd3d8d5d8..4c8e6b57b 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_cc.h @@ -63,7 +63,7 @@ class glonass_l1_ca_telemetry_decoder_cc : public gr::block public: ~glonass_l1_ca_telemetry_decoder_cc(); //!< Class destructor void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN - void set_channel(int channel); //!< Set receiver's channel + void set_channel(int32_t channel); //!< Set receiver's channel /*! * \brief This is where all signal processing takes place @@ -76,30 +76,30 @@ private: glonass_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); glonass_l1_ca_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - void decode_string(double *symbols, int frame_length); + void decode_string(double *symbols, int32_t frame_length); //!< Help with coherent tracking double d_preamble_time_samples; //!< Preamble decoding - unsigned short int d_preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS]; - int *d_preambles_symbols; - unsigned int d_samples_per_symbol; - int d_symbols_per_preamble; + uint16_t d_preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS]; + int32_t *d_preambles_symbols; + uint32_t d_samples_per_symbol; + int32_t d_symbols_per_preamble; //!< Storage for incoming data std::deque d_symbol_history; //!< Variables for internal functionality - long unsigned int d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed - long unsigned int d_preamble_index; //!< Index of sample number where preamble was found - unsigned int d_stat; //!< Status of decoder - bool d_flag_frame_sync; //!< Indicate when a frame sync is achieved - bool d_flag_parity; //!< Flag indicating when parity check was achieved (crc check) - bool d_flag_preamble; //!< Flag indicating when preamble was found - int d_CRC_error_counter; //!< Number of failed CRC operations - bool flag_TOW_set; //!< Indicates when time of week is set - double delta_t; //!< GPS-GLONASS time offset + uint64_t d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed + uint64_t d_preamble_index; //!< Index of sample number where preamble was found + uint32_t d_stat; //!< Status of decoder + bool d_flag_frame_sync; //!< Indicate when a frame sync is achieved + bool d_flag_parity; //!< Flag indicating when parity check was achieved (crc check) + bool d_flag_preamble; //!< Flag indicating when preamble was found + int32_t d_CRC_error_counter; //!< Number of failed CRC operations + bool flag_TOW_set; //!< Indicates when time of week is set + double delta_t; //!< GPS-GLONASS time offset //!< Navigation Message variable Glonass_Gnav_Navigation_Message d_nav; @@ -110,7 +110,7 @@ private: //!< Satellite Information and logging capacity Gnss_Satellite d_satellite; - int d_channel; + int32_t d_channel; bool d_dump; std::string d_dump_filename; std::ofstream d_dump_file; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_cc.cc index bf4181fb9..29b4f14d3 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_cc.cc @@ -65,18 +65,18 @@ glonass_l2_ca_telemetry_decoder_cc::glonass_l2_ca_telemetry_decoder_cc( d_samples_per_symbol = (GLONASS_L2_CA_CODE_RATE_HZ / GLONASS_L2_CA_CODE_LENGTH_CHIPS) / GLONASS_L2_CA_SYMBOL_RATE_BPS; // Set the preamble information - unsigned short int preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS] = GLONASS_GNAV_PREAMBLE; + uint16_t preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS] = GLONASS_GNAV_PREAMBLE; // Since preamble rate is different than navigation data rate we use a constant d_symbols_per_preamble = GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS; - memcpy(static_cast(this->d_preambles_bits), static_cast(preambles_bits), GLONASS_GNAV_PREAMBLE_LENGTH_BITS * sizeof(unsigned short int)); + memcpy(static_cast(this->d_preambles_bits), static_cast(preambles_bits), GLONASS_GNAV_PREAMBLE_LENGTH_BITS * sizeof(uint16_t)); // preamble bits to sampled symbols - d_preambles_symbols = static_cast(malloc(sizeof(signed int) * d_symbols_per_preamble)); - int n = 0; - for (int i = 0; i < GLONASS_GNAV_PREAMBLE_LENGTH_BITS; i++) + d_preambles_symbols = static_cast(malloc(sizeof(int32_t) * d_symbols_per_preamble)); + int32_t n = 0; + for (int32_t i = 0; i < GLONASS_GNAV_PREAMBLE_LENGTH_BITS; i++) { - for (unsigned int j = 0; j < GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_PREAMBLE_BIT; j++) + for (uint32_t j = 0; j < GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_PREAMBLE_BIT; j++) { if (d_preambles_bits[i] == 1) { @@ -89,9 +89,9 @@ glonass_l2_ca_telemetry_decoder_cc::glonass_l2_ca_telemetry_decoder_cc( n++; } } - d_sample_counter = 0; + d_sample_counter = 0ULL; d_stat = 0; - d_preamble_index = 0; + d_preamble_index = 0ULL; d_flag_frame_sync = false; @@ -124,10 +124,10 @@ glonass_l2_ca_telemetry_decoder_cc::~glonass_l2_ca_telemetry_decoder_cc() } -void glonass_l2_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, int frame_length) +void glonass_l2_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, int32_t frame_length) { double chip_acc = 0.0; - int chip_acc_counter = 0; + int32_t chip_acc_counter = 0; // 1. Transform from symbols to bits std::string bi_binary_code; @@ -135,7 +135,7 @@ void glonass_l2_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, in std::string data_bits; // Group samples into bi-binary code - for (int i = 0; i < (frame_length); i++) + for (int32_t i = 0; i < (frame_length); i++) { chip_acc += frame_symbols[i]; chip_acc_counter += 1; @@ -157,7 +157,7 @@ void glonass_l2_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, in } } // Convert from bi-binary code to relative code - for (int i = 0; i < (GLONASS_GNAV_STRING_BITS); i++) + for (int32_t i = 0; i < (GLONASS_GNAV_STRING_BITS); i++) { if (bi_binary_code[2 * i] == '1' && bi_binary_code[2 * i + 1] == '0') { @@ -170,7 +170,7 @@ void glonass_l2_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, in } // Convert from relative code to data bits data_bits.push_back('0'); - for (int i = 1; i < (GLONASS_GNAV_STRING_BITS); i++) + for (int32_t i = 1; i < (GLONASS_GNAV_STRING_BITS); i++) { data_bits.push_back(((relative_code[i - 1] - '0') ^ (relative_code[i] - '0')) + '0'); } @@ -207,7 +207,7 @@ void glonass_l2_ca_telemetry_decoder_cc::decode_string(double *frame_symbols, in } if (d_nav.have_new_almanac() == true) { - unsigned int slot_nbr = d_nav.i_alm_satellite_slot_number; + uint32_t slot_nbr = d_nav.i_alm_satellite_slot_number; std::shared_ptr tmp_obj = std::make_shared(d_nav.get_almanac(slot_nbr)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); LOG(INFO) << "GLONASS GNAV Almanac have been received in channel" << d_channel << " in slot number " << slot_nbr; @@ -232,7 +232,7 @@ void glonass_l2_ca_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &sat } -void glonass_l2_ca_telemetry_decoder_cc::set_channel(int channel) +void glonass_l2_ca_telemetry_decoder_cc::set_channel(int32_t channel) { d_channel = channel; LOG(INFO) << "Navigation channel set to " << channel; @@ -262,8 +262,8 @@ void glonass_l2_ca_telemetry_decoder_cc::set_channel(int channel) int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - int corr_value = 0; - int preamble_diff = 0; + int32_t corr_value = 0; + int32_t preamble_diff = 0; Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer @@ -276,12 +276,12 @@ int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu consume_each(1); d_flag_preamble = false; - unsigned int required_symbols = GLONASS_GNAV_STRING_SYMBOLS; + uint32_t required_symbols = GLONASS_GNAV_STRING_SYMBOLS; if (d_symbol_history.size() > required_symbols) { // ******* preamble correlation ******** - for (int i = 0; i < d_symbols_per_preamble; i++) + for (int32_t i = 0; i < d_symbols_per_preamble; i++) { if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping { @@ -312,9 +312,9 @@ int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu if (abs(corr_value) >= d_symbols_per_preamble) { // check preamble separation - preamble_diff = d_sample_counter - d_preamble_index; + preamble_diff = static_cast(d_sample_counter - d_preamble_index); // Record the PRN start sample index associated to the preamble - d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; + d_preamble_time_samples = static_cast(d_symbol_history.at(0).Tracking_sample_counter); if (abs(preamble_diff - GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) == 0) { // try to decode frame @@ -335,15 +335,15 @@ int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu else if (d_stat == 2) { // FIXME: The preamble index marks the first symbol of the string count. Here I just wait for another full string to be received before processing - if (d_sample_counter == d_preamble_index + GLONASS_GNAV_STRING_SYMBOLS) + if (d_sample_counter == d_preamble_index + static_cast(GLONASS_GNAV_STRING_SYMBOLS)) { // NEW GLONASS string received // 0. fetch the symbols into an array - int string_length = GLONASS_GNAV_STRING_SYMBOLS - d_symbols_per_preamble; + int32_t string_length = GLONASS_GNAV_STRING_SYMBOLS - d_symbols_per_preamble; double string_symbols[GLONASS_GNAV_DATA_SYMBOLS] = {0}; // ******* SYMBOL TO BIT ******* - for (int i = 0; i < string_length; i++) + for (int32_t i = 0; i < string_length; i++) { if (corr_value > 0) { @@ -415,7 +415,7 @@ int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu current_symbol.PRN = this->d_satellite.get_PRN(); current_symbol.TOW_at_current_symbol_ms = round(d_TOW_at_current_symbol * 1000.0); // todo: glonass time to gps time should be done in observables block - // current_symbol.TOW_at_current_symbol_ms -= static_cast(delta_t) * 1000; + // current_symbol.TOW_at_current_symbol_ms -= static_cast(delta_t) * 1000; if (d_dump == true) { @@ -423,11 +423,11 @@ int glonass_l2_ca_telemetry_decoder_cc::general_work(int noutput_items __attribu try { double tmp_double; - unsigned long int tmp_ulong_int; + uint64_t tmp_ulong_int; tmp_double = d_TOW_at_current_symbol; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_ulong_int = current_symbol.Tracking_sample_counter; - d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); tmp_double = 0; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_cc.h index bad3ad62f..8b834228a 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_cc.h @@ -61,7 +61,7 @@ class glonass_l2_ca_telemetry_decoder_cc : public gr::block public: ~glonass_l2_ca_telemetry_decoder_cc(); //!< Class destructor void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN - void set_channel(int channel); //!< Set receiver's channel + void set_channel(int32_t channel); //!< Set receiver's channel /*! * \brief This is where all signal processing takes place @@ -74,30 +74,30 @@ private: glonass_l2_ca_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); glonass_l2_ca_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - void decode_string(double *symbols, int frame_length); + void decode_string(double *symbols, int32_t frame_length); //!< Help with coherent tracking double d_preamble_time_samples; //!< Preamble decoding - unsigned short int d_preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS]; - int *d_preambles_symbols; - unsigned int d_samples_per_symbol; - int d_symbols_per_preamble; + uint16_t d_preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS]; + int32_t *d_preambles_symbols; + uint32_t d_samples_per_symbol; + int32_t d_symbols_per_preamble; //!< Storage for incoming data std::deque d_symbol_history; //!< Variables for internal functionality - long unsigned int d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed - long unsigned int d_preamble_index; //!< Index of sample number where preamble was found - unsigned int d_stat; //!< Status of decoder - bool d_flag_frame_sync; //!< Indicate when a frame sync is achieved - bool d_flag_parity; //!< Flag indicating when parity check was achieved (crc check) - bool d_flag_preamble; //!< Flag indicating when preamble was found - int d_CRC_error_counter; //!< Number of failed CRC operations - bool flag_TOW_set; //!< Indicates when time of week is set - double delta_t; //!< GPS-GLONASS time offset + uint64_t d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed + uint64_t d_preamble_index; //!< Index of sample number where preamble was found + uint32_t d_stat; //!< Status of decoder + bool d_flag_frame_sync; //!< Indicate when a frame sync is achieved + bool d_flag_parity; //!< Flag indicating when parity check was achieved (crc check) + bool d_flag_preamble; //!< Flag indicating when preamble was found + int32_t d_CRC_error_counter; //!< Number of failed CRC operations + bool flag_TOW_set; //!< Indicates when time of week is set + double delta_t; //!< GPS-GLONASS time offset //!< Navigation Message variable Glonass_Gnav_Navigation_Message d_nav; @@ -108,7 +108,7 @@ private: //!< Satellite Information and logging capacity Gnss_Satellite d_satellite; - int d_channel; + int32_t d_channel; bool d_dump; std::string d_dump_filename; std::ofstream d_dump_file; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc index 78ff3aaa9..e4a12bd43 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.cc @@ -62,14 +62,14 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc( d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); // set the preamble - unsigned short int preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE; + uint16_t preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE; // preamble bits to sampled symbols - d_preambles_symbols = static_cast(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int), volk_gnsssdr_get_alignment())); - int n = 0; - for (int i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++) + d_preambles_symbols = static_cast(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int32_t), volk_gnsssdr_get_alignment())); + int32_t n = 0; + for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++) { - for (unsigned int j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++) + for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++) { if (preambles_bits[i] == 1) { @@ -82,33 +82,27 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc( n++; } } - d_stat = 0; - d_symbol_accumulator = 0; - d_symbol_accumulator_counter = 0; - d_frame_bit_index = 0; + d_stat = 0U; d_flag_frame_sync = false; - d_GPS_frame_4bytes = 0; d_prev_GPS_frame_4bytes = 0; - d_flag_parity = false; d_TOW_at_Preamble_ms = 0; flag_TOW_set = false; d_flag_preamble = false; d_flag_new_tow_available = false; - d_word_number = 0; d_channel = 0; flag_PLL_180_deg_phase_locked = false; - d_preamble_time_samples = 0; + d_preamble_time_samples = 0ULL; d_TOW_at_current_symbol_ms = 0; - d_symbol_history.resize(GPS_CA_PREAMBLE_LENGTH_SYMBOLS + 1); // Change fixed buffer size - d_symbol_history.clear(); // Clear all the elements in the buffer - d_make_correlation = true; - d_symbol_counter_corr = 0; + d_symbol_history.set_capacity(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); + d_crc_error_synchronization_counter = 0; + d_current_subframe_symbol = 0; } gps_l1_ca_telemetry_decoder_cc::~gps_l1_ca_telemetry_decoder_cc() { volk_gnsssdr_free(d_preambles_symbols); + d_symbol_history.clear(); if (d_dump_file.is_open() == true) { try @@ -123,13 +117,13 @@ gps_l1_ca_telemetry_decoder_cc::~gps_l1_ca_telemetry_decoder_cc() } -bool gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(unsigned int gpsword) +bool gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(uint32_t gpsword) { - unsigned int d1, d2, d3, d4, d5, d6, d7, t, parity; - /* XOR as many bits in parallel as possible. The magic constants pick - up bits which are to be XOR'ed together to implement the GPS parity - check algorithm described in IS-GPS-200E. This avoids lengthy shift- - and-xor loops. */ + uint32_t d1, d2, d3, d4, d5, d6, d7, t, parity; + // XOR as many bits in parallel as possible. The magic constants pick + // up bits which are to be XOR'ed together to implement the GPS parity + // check algorithm described in IS-GPS-200E. This avoids lengthy shift- + // and-xor loops. d1 = gpsword & 0xFBFFBF00; d2 = _rotl(gpsword, 1) & 0x07FFBF01; d3 = _rotl(gpsword, 2) & 0xFC0F8100; @@ -150,17 +144,18 @@ bool gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(unsigned int gpsword) void gps_l1_ca_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite) { + d_nav.reset(); d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite; - d_GPS_FSM.i_satellite_PRN = d_satellite.get_PRN(); + d_nav.i_satellite_PRN = d_satellite.get_PRN(); DLOG(INFO) << "Navigation Satellite set to " << d_satellite; } -void gps_l1_ca_telemetry_decoder_cc::set_channel(int channel) +void gps_l1_ca_telemetry_decoder_cc::set_channel(int32_t channel) { d_channel = channel; - d_GPS_FSM.i_channel_ID = channel; + d_nav.i_channel_ID = channel; DLOG(INFO) << "Navigation channel set to " << channel; // ############# ENABLE DATA FILE LOG ################# if (d_dump == true) @@ -186,32 +181,165 @@ void gps_l1_ca_telemetry_decoder_cc::set_channel(int channel) } +bool gps_l1_ca_telemetry_decoder_cc::decode_subframe() +{ + char subframe[GPS_SUBFRAME_LENGTH]; + + int32_t symbol_accumulator_counter = 0; + int32_t frame_bit_index = 0; + int32_t word_index = 0; + uint32_t GPS_frame_4bytes = 0; + float symbol_accumulator = 0; + bool subframe_synchro_confirmation = false; + bool CRC_ok = true; + + for (int32_t n = 0; n < GPS_SUBFRAME_MS; n++) + { + // ******* SYMBOL TO BIT ******* + // extended correlation to bit period is enabled in tracking! + symbol_accumulator += d_subframe_symbols[n]; // accumulate the input value in d_symbol_accumulator + symbol_accumulator_counter++; + if (symbol_accumulator_counter == 20) + { + // symbol to bit + if (symbol_accumulator > 0) GPS_frame_4bytes += 1; // insert the telemetry bit in LSB + symbol_accumulator = 0; + symbol_accumulator_counter = 0; + + // ******* bits to words ****** + frame_bit_index++; + if (frame_bit_index == 30) + { + frame_bit_index = 0; + // parity check + // Each word in wordbuff is composed of: + // Bits 0 to 29 = the GPS data word + // Bits 30 to 31 = 2 LSBs of the GPS word ahead. + // prepare the extended frame [-2 -1 0 ... 30] + if (d_prev_GPS_frame_4bytes & 0x00000001) + { + GPS_frame_4bytes = GPS_frame_4bytes | 0x40000000; + } + if (d_prev_GPS_frame_4bytes & 0x00000002) + { + GPS_frame_4bytes = GPS_frame_4bytes | 0x80000000; + } + // Check that the 2 most recently logged words pass parity. Have to first + // invert the data bits according to bit 30 of the previous word. + if (GPS_frame_4bytes & 0x40000000) + { + GPS_frame_4bytes ^= 0x3FFFFFC0; // invert the data bits (using XOR) + } + if (gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(GPS_frame_4bytes)) + { + subframe_synchro_confirmation = true; + } + else + { + // std::cout << "word invalid sat " << this->d_satellite << std::endl; + CRC_ok = false; + } + // add word to subframe + // insert the word in the correct position of the subframe + std::memcpy(&subframe[word_index * GPS_WORD_LENGTH], &GPS_frame_4bytes, sizeof(uint32_t)); + word_index++; + d_prev_GPS_frame_4bytes = GPS_frame_4bytes; // save the actual frame + GPS_frame_4bytes = 0; + } + else + { + GPS_frame_4bytes <<= 1; // shift 1 bit left the telemetry word + } + } + } + + // decode subframe + // NEW GPS SUBFRAME HAS ARRIVED! + if (CRC_ok) + { + int32_t subframe_ID = d_nav.subframe_decoder(subframe); //d ecode the subframe + if (subframe_ID > 0 and subframe_ID < 6) + { + std::cout << "New GPS NAV message received in channel " << this->d_channel << ": " + << "subframe " + << subframe_ID << " from satellite " + << Gnss_Satellite(std::string("GPS"), d_nav.i_satellite_PRN) << std::endl; + + switch (subframe_ID) + { + case 3: // we have a new set of ephemeris data for the current SV + if (d_nav.satellite_validation() == true) + { + // get ephemeris object for this SV (mandatory) + std::shared_ptr tmp_obj = std::make_shared(d_nav.get_ephemeris()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + break; + case 4: // Possible IONOSPHERE and UTC model update (page 18) + if (d_nav.flag_iono_valid == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_nav.get_iono()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + if (d_nav.flag_utc_model_valid == true) + { + std::shared_ptr tmp_obj = std::make_shared(d_nav.get_utc_model()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + break; + case 5: + // get almanac (if available) + //TODO: implement almanac reader in navigation_message + break; + default: + break; + } + d_flag_new_tow_available = true; + } + else + { + return false; + } + } + + return subframe_synchro_confirmation; +} + + int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - int corr_value = 0; - int preamble_diff_ms = 0; + int32_t preamble_diff_ms = 0; Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer - Gnss_Synchro current_symbol; //structure to save the synchronization information and send the output object to the next block - //1. Copy the current tracking output + Gnss_Synchro current_symbol; // structure to save the synchronization information and send the output object to the next block + // 1. Copy the current tracking output current_symbol = in[0][0]; - d_symbol_history.push_back(current_symbol); //add new symbol to the symbol queue + + // record the oldest subframe symbol before inserting a new symbol into the circular buffer + if (d_current_subframe_symbol < GPS_SUBFRAME_MS and d_symbol_history.size() > 0) + { + d_subframe_symbols[d_current_subframe_symbol] = d_symbol_history[0].Prompt_I; + d_current_subframe_symbol++; + } + + d_symbol_history.push_back(current_symbol); // add new symbol to the symbol queue consume_each(1); - unsigned int required_symbols = GPS_CA_PREAMBLE_LENGTH_SYMBOLS; d_flag_preamble = false; - if ((d_symbol_history.size() > required_symbols) and (d_make_correlation or !d_flag_frame_sync)) + // ******* preamble correlation ******** + int32_t corr_value = 0; + if ((d_symbol_history.size() == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)) // and (d_make_correlation or !d_flag_frame_sync)) { - //******* preamble correlation ******** - for (unsigned int i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++) + // std::cout << "-------\n"; + for (uint32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++) { - if (d_symbol_history.at(i).Flag_valid_symbol_output == true) + if (d_symbol_history[i].Flag_valid_symbol_output == true) { - if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping + if (d_symbol_history[i].Prompt_I < 0) // symbols clipping { corr_value -= d_preambles_symbols[i]; } @@ -221,39 +349,27 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__ } } } - if (std::abs(corr_value) >= GPS_CA_PREAMBLE_LENGTH_SYMBOLS) - { - d_symbol_counter_corr++; - } } - //******* frame sync ****************** + // ******* frame sync ****************** if (std::abs(corr_value) == GPS_CA_PREAMBLE_LENGTH_SYMBOLS) { //TODO: Rewrite with state machine if (d_stat == 0) { - d_GPS_FSM.Event_gps_word_preamble(); - //record the preamble sample stamp - d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the preamble sample stamp - DLOG(INFO) << "Preamble detection for SAT " << this->d_satellite << "d_symbol_history.at(0).Tracking_sample_counter=" << d_symbol_history.at(0).Tracking_sample_counter; - //sync the symbol to bits integrator - d_symbol_accumulator = 0; - d_symbol_accumulator_counter = 0; - d_frame_bit_index = 0; + // record the preamble sample stamp + d_preamble_time_samples = d_symbol_history[0].Tracking_sample_counter; // record the preamble sample stamp + DLOG(INFO) << "Preamble detection for SAT " << this->d_satellite << "d_symbol_history[0].Tracking_sample_counter=" << d_symbol_history[0].Tracking_sample_counter; d_stat = 1; // enter into frame pre-detection status } - else if (d_stat == 1) //check 6 seconds of preamble separation + else if (d_stat == 1) // check 6 seconds of preamble separation { - preamble_diff_ms = std::round(((static_cast(d_symbol_history.at(0).Tracking_sample_counter) - d_preamble_time_samples) / static_cast(d_symbol_history.at(0).fs)) * 1000.0); - if (std::abs(preamble_diff_ms - GPS_SUBFRAME_MS) < 1) + preamble_diff_ms = std::round(((static_cast(d_symbol_history[0].Tracking_sample_counter) - static_cast(d_preamble_time_samples)) / static_cast(d_symbol_history[0].fs)) * 1000.0); + if (std::abs(preamble_diff_ms - GPS_SUBFRAME_MS) % GPS_SUBFRAME_MS == 0) { DLOG(INFO) << "Preamble confirmation for SAT " << this->d_satellite; - d_GPS_FSM.Event_gps_word_preamble(); d_flag_preamble = true; - d_make_correlation = false; - d_symbol_counter_corr = 0; - d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the PRN start sample index associated to the preamble + d_preamble_time_samples = d_symbol_history[0].Tracking_sample_counter; // record the PRN start sample index associated to the preamble if (!d_flag_frame_sync) { d_flag_frame_sync = true; @@ -267,173 +383,99 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__ flag_PLL_180_deg_phase_locked = false; } DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " - << static_cast(d_preamble_time_samples) / static_cast(d_symbol_history.at(0).fs) << " [s]"; + << static_cast(d_preamble_time_samples) / static_cast(d_symbol_history[0].fs) << " [s]"; } + + // try to decode the subframe: + if (decode_subframe() == false) + { + d_crc_error_synchronization_counter++; + if (d_crc_error_synchronization_counter > 3) + { + DLOG(INFO) << "TOO MANY CRC ERRORS: Lost of frame sync SAT " << this->d_satellite << std::endl; + d_stat = 0; // lost of frame sync + d_flag_frame_sync = false; + flag_TOW_set = false; + d_crc_error_synchronization_counter = 0; + } + } + d_current_subframe_symbol = 0; } } } else { - d_symbol_counter_corr++; - if (d_symbol_counter_corr > (GPS_SUBFRAME_MS - GPS_CA_TELEMETRY_SYMBOLS_PER_BIT)) - { - d_make_correlation = true; - } if (d_stat == 1) { - preamble_diff_ms = round(((static_cast(d_symbol_history.at(0).Tracking_sample_counter) - static_cast(d_preamble_time_samples)) / static_cast(d_symbol_history.at(0).fs)) * 1000.0); - if (preamble_diff_ms > GPS_SUBFRAME_MS + 1) + preamble_diff_ms = round(((static_cast(d_symbol_history[0].Tracking_sample_counter) - static_cast(d_preamble_time_samples)) / static_cast(d_symbol_history[0].fs)) * 1000.0); + if (preamble_diff_ms > GPS_SUBFRAME_MS) { DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms; - d_stat = 0; //lost of frame sync + // std::cout << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms << std::endl; + d_stat = 0; // lost of frame sync d_flag_frame_sync = false; flag_TOW_set = false; - d_make_correlation = true; - d_symbol_counter_corr = 0; + d_current_subframe_symbol = 0; + d_crc_error_synchronization_counter = 0; + d_TOW_at_current_symbol_ms = 0; } } } - //******* SYMBOL TO BIT ******* - if (d_symbol_history.at(0).Flag_valid_symbol_output == true) - { - // extended correlation to bit period is enabled in tracking! - d_symbol_accumulator += d_symbol_history.at(0).Prompt_I; // accumulate the input value in d_symbol_accumulator - d_symbol_accumulator_counter += d_symbol_history.at(0).correlation_length_ms; - } - if (d_symbol_accumulator_counter >= 20) - { - if (d_symbol_accumulator > 0) - { //symbol to bit - d_GPS_frame_4bytes += 1; //insert the telemetry bit in LSB - } - d_symbol_accumulator = 0; - d_symbol_accumulator_counter = 0; - //******* bits to words ****** - d_frame_bit_index++; - if (d_frame_bit_index == 30) - { - d_frame_bit_index = 0; - // parity check - // Each word in wordbuff is composed of: - // Bits 0 to 29 = the GPS data word - // Bits 30 to 31 = 2 LSBs of the GPS word ahead. - // prepare the extended frame [-2 -1 0 ... 30] - if (d_prev_GPS_frame_4bytes & 0x00000001) - { - d_GPS_frame_4bytes = d_GPS_frame_4bytes | 0x40000000; - } - if (d_prev_GPS_frame_4bytes & 0x00000002) - { - d_GPS_frame_4bytes = d_GPS_frame_4bytes | 0x80000000; - } - /* Check that the 2 most recently logged words pass parity. Have to first - invert the data bits according to bit 30 of the previous word. */ - if (d_GPS_frame_4bytes & 0x40000000) - { - d_GPS_frame_4bytes ^= 0x3FFFFFC0; // invert the data bits (using XOR) - } - if (gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(d_GPS_frame_4bytes)) - { - memcpy(&d_GPS_FSM.d_GPS_frame_4bytes, &d_GPS_frame_4bytes, sizeof(char) * 4); - //d_GPS_FSM.d_preamble_time_ms = d_preamble_time_seconds * 1000.0; - d_GPS_FSM.Event_gps_word_valid(); - // send TLM data to PVT using asynchronous message queues - if (d_GPS_FSM.d_flag_new_subframe == true) - { - switch (d_GPS_FSM.d_subframe_ID) - { - case 3: //we have a new set of ephemeris data for the current SV - if (d_GPS_FSM.d_nav.satellite_validation() == true) - { - // get ephemeris object for this SV (mandatory) - std::shared_ptr tmp_obj = std::make_shared(d_GPS_FSM.d_nav.get_ephemeris()); - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - break; - case 4: // Possible IONOSPHERE and UTC model update (page 18) - if (d_GPS_FSM.d_nav.flag_iono_valid == true) - { - std::shared_ptr tmp_obj = std::make_shared(d_GPS_FSM.d_nav.get_iono()); - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_GPS_FSM.d_nav.flag_utc_model_valid == true) - { - std::shared_ptr tmp_obj = std::make_shared(d_GPS_FSM.d_nav.get_utc_model()); - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - break; - case 5: - // get almanac (if available) - //TODO: implement almanac reader in navigation_message - break; - default: - break; - } - d_GPS_FSM.clear_flag_new_subframe(); - d_flag_new_tow_available = true; - } - - d_flag_parity = true; - } - else - { - d_GPS_FSM.Event_gps_word_invalid(); - d_flag_parity = false; - } - d_prev_GPS_frame_4bytes = d_GPS_frame_4bytes; // save the actual frame - d_GPS_frame_4bytes = d_GPS_frame_4bytes & 0; - } - else - { - d_GPS_frame_4bytes <<= 1; //shift 1 bit left the telemetry word - } - } - - //2. Add the telemetry decoder information + // 2. Add the telemetry decoder information if (this->d_flag_preamble == true and d_flag_new_tow_available == true) { - d_TOW_at_current_symbol_ms = static_cast(d_GPS_FSM.d_nav.d_TOW) * 1000 + GPS_L1_CA_CODE_PERIOD_MS + GPS_CA_PREAMBLE_DURATION_MS; - d_TOW_at_Preamble_ms = d_TOW_at_current_symbol_ms; + d_TOW_at_current_symbol_ms = static_cast(d_nav.d_TOW * 1000.0) + GPS_CA_PREAMBLE_DURATION_MS; + d_TOW_at_Preamble_ms = static_cast(d_nav.d_TOW * 1000.0); flag_TOW_set = true; d_flag_new_tow_available = false; } else { - d_TOW_at_current_symbol_ms += GPS_L1_CA_CODE_PERIOD_MS; - } - - current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; - current_symbol.Flag_valid_word = flag_TOW_set; - - if (flag_PLL_180_deg_phase_locked == true) - { - //correct the accumulated phase for the Costas loop phase shift, if required - current_symbol.Carrier_phase_rads += GPS_PI; - } - - if (d_dump == true) - { - // MULTIPLEXED FILE RECORDING - Record results to file - try + if (flag_TOW_set == true) { - double tmp_double; - unsigned long int tmp_ulong_int; - tmp_double = static_cast(d_TOW_at_current_symbol_ms) / 1000.0; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_ulong_int = current_symbol.Tracking_sample_counter; - d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(unsigned long int)); - tmp_double = static_cast(d_TOW_at_Preamble_ms) * 1000.0; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "Exception writing observables dump file " << e.what(); + d_TOW_at_current_symbol_ms += GPS_L1_CA_CODE_PERIOD_MS; } } - //3. Make the output (copy the object contents to the GNURadio reserved memory) - *out[0] = current_symbol; + if (flag_TOW_set == true) + { + current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; + current_symbol.Flag_valid_word = flag_TOW_set; - return 1; + if (flag_PLL_180_deg_phase_locked == true) + { + // correct the accumulated phase for the Costas loop phase shift, if required + current_symbol.Carrier_phase_rads += GPS_PI; + } + + if (d_dump == true) + { + // MULTIPLEXED FILE RECORDING - Record results to file + try + { + double tmp_double; + uint64_t tmp_ulong_int; + tmp_double = static_cast(d_TOW_at_current_symbol_ms) / 1000.0; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_ulong_int = current_symbol.Tracking_sample_counter; + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); + tmp_double = static_cast(d_TOW_at_Preamble_ms) / 1000.0; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "Exception writing observables dump file " << e.what(); + } + } + + // 3. Make the output (copy the object contents to the GNURadio reserved memory) + *out[0] = current_symbol; + + return 1; + } + else + { + return 0; + } } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.h index 52f1f1049..745128047 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_cc.h @@ -32,7 +32,7 @@ #define GNSS_SDR_GPS_L1_CA_TELEMETRY_DECODER_CC_H #include "GPS_L1_CA.h" -#include "gps_l1_ca_subframe_fsm.h" +#include "gps_navigation_message.h" #include "gnss_satellite.h" #include "gnss_synchro.h" #include @@ -70,45 +70,37 @@ private: gps_l1_ca_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - bool gps_word_parityCheck(unsigned int gpsword); + bool gps_word_parityCheck(uint32_t gpsword); - // class private vars + bool decode_subframe(); + bool new_decoder(); + int d_crc_error_synchronization_counter; int *d_preambles_symbols; - unsigned int d_stat; + uint32_t d_stat; bool d_flag_frame_sync; // symbols boost::circular_buffer d_symbol_history; + float d_subframe_symbols[GPS_SUBFRAME_MS]; // symbols per subframe + int d_current_subframe_symbol; - double d_symbol_accumulator; - short int d_symbol_accumulator_counter; - - // symbol counting - bool d_make_correlation; - unsigned int d_symbol_counter_corr; - - //bits and frame - unsigned short int d_frame_bit_index; - unsigned int d_GPS_frame_4bytes; - unsigned int d_prev_GPS_frame_4bytes; - bool d_flag_parity; + // bits and frame + uint32_t d_prev_GPS_frame_4bytes; bool d_flag_preamble; bool d_flag_new_tow_available; - int d_word_number; // navigation message vars Gps_Navigation_Message d_nav; - GpsL1CaSubframeFsm d_GPS_FSM; bool d_dump; Gnss_Satellite d_satellite; int d_channel; - unsigned long int d_preamble_time_samples; + uint64_t d_preamble_time_samples; - unsigned int d_TOW_at_Preamble_ms; - unsigned int d_TOW_at_current_symbol_ms; + uint32_t d_TOW_at_Preamble_ms; + uint32_t d_TOW_at_current_symbol_ms; bool flag_TOW_set; bool flag_PLL_180_deg_phase_locked; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc index 5cc385207..6790c8559 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.cc @@ -61,7 +61,7 @@ gps_l2c_telemetry_decoder_cc::gps_l2c_telemetry_decoder_cc( d_dump = dump; d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); DLOG(INFO) << "GPS L2C M TELEMETRY PROCESSING: satellite " << d_satellite; - //set_output_multiple (1); + // set_output_multiple (1); d_channel = 0; d_flag_valid_word = false; d_TOW_at_current_symbol = 0; @@ -69,7 +69,7 @@ gps_l2c_telemetry_decoder_cc::gps_l2c_telemetry_decoder_cc( d_state = 0; //initial state d_crc_error_count = 0; - //initialize the CNAV frame decoder (libswiftcnav) + // initialize the CNAV frame decoder (libswiftcnav) cnav_msg_decoder_init(&d_cnav_decoder); } @@ -134,34 +134,34 @@ int gps_l2c_telemetry_decoder_cc::general_work(int noutput_items __attribute__(( bool flag_new_cnav_frame = false; cnav_msg_t msg; - u32 delay = 0; + uint32_t delay = 0; - //add the symbol to the decoder - u8 symbol_clip = static_cast(in[0].Prompt_I > 0) * 255; + // add the symbol to the decoder + uint8_t symbol_clip = static_cast(in[0].Prompt_I > 0) * 255; flag_new_cnav_frame = cnav_msg_decoder_add_symbol(&d_cnav_decoder, symbol_clip, &msg, &delay); - consume_each(1); //one by one + consume_each(1); // one by one // UPDATE GNSS SYNCHRO DATA - Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block + Gnss_Synchro current_synchro_data; // structure to save the synchronization information and send the output object to the next block - //1. Copy the current tracking output + // 1. Copy the current tracking output current_synchro_data = in[0]; - //2. Add the telemetry decoder information - //check if new CNAV frame is available + // 2. Add the telemetry decoder information + // check if new CNAV frame is available if (flag_new_cnav_frame == true) { std::bitset raw_bits; - //Expand packet bits to bitsets. Notice the reverse order of the bits sequence, required by the CNAV message decoder - for (u32 i = 0; i < GPS_L2_CNAV_DATA_PAGE_BITS; i++) + // Expand packet bits to bitsets. Notice the reverse order of the bits sequence, required by the CNAV message decoder + for (uint32_t i = 0; i < GPS_L2_CNAV_DATA_PAGE_BITS; i++) { raw_bits[GPS_L2_CNAV_DATA_PAGE_BITS - 1 - i] = ((msg.raw_msg[i / 8] >> (7 - i % 8)) & 1u); } d_CNAV_Message.decode_page(raw_bits); - //Push the new navigation data to the queues + // Push the new navigation data to the queues if (d_CNAV_Message.have_new_ephemeris() == true) { // get ephemeris object for this SV @@ -183,12 +183,12 @@ int gps_l2c_telemetry_decoder_cc::general_work(int noutput_items __attribute__(( this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); } - //update TOW at the preamble instant + // update TOW at the preamble instant d_TOW_at_Preamble = static_cast(msg.tow); - //* The time of the last input symbol can be computed from the message ToW and - //* delay by the formulae: - //* \code - //* symbolTime_ms = msg->tow * 6000 + *pdelay * 20 + (12 * 20); 12 symbols of the encoder's transitory + // The time of the last input symbol can be computed from the message ToW and + // delay by the formulae: + // \code + // symbolTime_ms = msg->tow * 6000 + *pdelay * 20 + (12 * 20); 12 symbols of the encoder's transitory d_TOW_at_current_symbol = static_cast(msg.tow) * 6.0 + static_cast(delay) * GPS_L2_M_PERIOD + 12 * GPS_L2_M_PERIOD; //d_TOW_at_current_symbol = floor(d_TOW_at_current_symbol * 1000.0) / 1000.0; d_flag_valid_word = true; @@ -210,11 +210,11 @@ int gps_l2c_telemetry_decoder_cc::general_work(int noutput_items __attribute__(( try { double tmp_double; - unsigned long int tmp_ulong_int; + uint64_t tmp_ulong_int; tmp_double = d_TOW_at_current_symbol; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); tmp_ulong_int = current_synchro_data.Tracking_sample_counter; - d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); tmp_double = d_TOW_at_Preamble; d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); } @@ -224,7 +224,7 @@ int gps_l2c_telemetry_decoder_cc::general_work(int noutput_items __attribute__(( } } - //3. Make the output (copy the object contents to the GNURadio reserved memory) + // 3. Make the output (copy the object contents to the GNURadio reserved memory) out[0] = current_synchro_data; return 1; } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.h index 9235c5c2d..932fb6db7 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_cc.h @@ -38,6 +38,7 @@ #include "gps_cnav_iono.h" #include #include // for copy +#include #include #include #include @@ -70,7 +71,7 @@ class gps_l2c_telemetry_decoder_cc : public gr::block public: ~gps_l2c_telemetry_decoder_cc(); void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN - void set_channel(int channel); //!< Set receiver's channel + void set_channel(int32_t channel); //!< Set receiver's channel /*! * \brief This is where all signal processing takes place @@ -78,7 +79,6 @@ public: int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - private: friend gps_l2c_telemetry_decoder_cc_sptr gps_l2c_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); @@ -86,15 +86,15 @@ private: bool d_dump; Gnss_Satellite d_satellite; - int d_channel; + int32_t d_channel; std::string d_dump_filename; std::ofstream d_dump_file; cnav_msg_decoder_t d_cnav_decoder; - int d_state; - int d_crc_error_count; + int32_t d_state; + int32_t d_crc_error_count; double d_TOW_at_current_symbol; double d_TOW_at_Preamble; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc index 87412096e..8aafd598a 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.cc @@ -64,11 +64,11 @@ gps_l5_telemetry_decoder_cc::gps_l5_telemetry_decoder_cc( DLOG(INFO) << "GPS L5 TELEMETRY PROCESSING: satellite " << d_satellite; d_channel = 0; d_flag_valid_word = false; - d_TOW_at_current_symbol = 0.0; - d_TOW_at_Preamble = 0.0; - //initialize the CNAV frame decoder (libswiftcnav) + d_TOW_at_current_symbol_ms = 0U; + d_TOW_at_Preamble_ms = 0U; + // initialize the CNAV frame decoder (libswiftcnav) cnav_msg_decoder_init(&d_cnav_decoder); - for (int aux = 0; aux < GPS_L5i_NH_CODE_LENGTH; aux++) + for (int32_t aux = 0; aux < GPS_L5i_NH_CODE_LENGTH; aux++) { if (GPS_L5i_NH_CODE[aux] == 0) { @@ -108,7 +108,7 @@ void gps_l5_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite) } -void gps_l5_telemetry_decoder_cc::set_channel(int channel) +void gps_l5_telemetry_decoder_cc::set_channel(int32_t channel) { d_channel = channel; d_CNAV_Message.reset(); @@ -146,17 +146,17 @@ int gps_l5_telemetry_decoder_cc::general_work(int noutput_items __attribute__((u // UPDATE GNSS SYNCHRO DATA Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block - //1. Copy the current tracking output + // 1. Copy the current tracking output current_synchro_data = in[0]; consume_each(1); //one by one sym_hist.push_back(in[0].Prompt_I); - int corr_NH = 0; - int symbol_value = 0; + int32_t corr_NH = 0; + int32_t symbol_value = 0; - //Search correlation with Neuman-Hofman Code (see IS-GPS-705D) + // Search correlation with Neuman-Hofman Code (see IS-GPS-705D) if (sym_hist.size() == GPS_L5i_NH_CODE_LENGTH) { - for (int i = 0; i < GPS_L5i_NH_CODE_LENGTH; i++) + for (int32_t i = 0; i < GPS_L5i_NH_CODE_LENGTH; i++) { if ((bits_NH[i] * sym_hist.at(i)) > 0.0) { @@ -191,29 +191,29 @@ int gps_l5_telemetry_decoder_cc::general_work(int noutput_items __attribute__((u bool flag_new_cnav_frame = false; cnav_msg_t msg; - u32 delay = 0; + uint32_t delay = 0; - //add the symbol to the decoder + // add the symbol to the decoder if (new_sym) { - u8 symbol_clip = static_cast(symbol_value > 0) * 255; + uint8_t symbol_clip = static_cast(symbol_value > 0) * 255; flag_new_cnav_frame = cnav_msg_decoder_add_symbol(&d_cnav_decoder, symbol_clip, &msg, &delay); new_sym = false; } - //2. Add the telemetry decoder information - //check if new CNAV frame is available + // 2. Add the telemetry decoder information + // check if new CNAV frame is available if (flag_new_cnav_frame == true) { std::bitset raw_bits; - //Expand packet bits to bitsets. Notice the reverse order of the bits sequence, required by the CNAV message decoder - for (u32 i = 0; i < GPS_L5_CNAV_DATA_PAGE_BITS; i++) + // Expand packet bits to bitsets. Notice the reverse order of the bits sequence, required by the CNAV message decoder + for (uint32_t i = 0; i < GPS_L5_CNAV_DATA_PAGE_BITS; i++) { raw_bits[GPS_L5_CNAV_DATA_PAGE_BITS - 1 - i] = ((msg.raw_msg[i / 8] >> (7 - i % 8)) & 1u); } d_CNAV_Message.decode_page(raw_bits); - //Push the new navigation data to the queues + // Push the new navigation data to the queues if (d_CNAV_Message.have_new_ephemeris() == true) { // get ephemeris object for this SV @@ -235,48 +235,55 @@ int gps_l5_telemetry_decoder_cc::general_work(int noutput_items __attribute__((u this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); } - //update TOW at the preamble instant - d_TOW_at_Preamble = static_cast(msg.tow) * 6.0; - //* The time of the last input symbol can be computed from the message ToW and - //* delay by the formulae: - //* \code - //* symbolTime_ms = msg->tow * 6000 + *pdelay * 10 + (12 * 10); 12 symbols of the encoder's transitory - d_TOW_at_current_symbol = (static_cast(msg.tow) * 6.0) + (static_cast(delay) + 12.0) * GPS_L5i_SYMBOL_PERIOD; - d_TOW_at_current_symbol = floor(d_TOW_at_current_symbol * 1000.0) / 1000.0; + // update TOW at the preamble instant + d_TOW_at_Preamble_ms = msg.tow * 6000; + // The time of the last input symbol can be computed from the message ToW and + // delay by the formulae: + // \code + // symbolTime_ms = msg->tow * 6000 + *pdelay * 10 + (12 * 10); 12 symbols of the encoder's transitory + d_TOW_at_current_symbol_ms = msg.tow * 6000 + (delay + 12) * GPS_L5i_SYMBOL_PERIOD_MS; d_flag_valid_word = true; } else { - d_TOW_at_current_symbol += GPS_L5i_PERIOD; + d_TOW_at_current_symbol_ms += GPS_L5i_PERIOD_MS; if (current_synchro_data.Flag_valid_symbol_output == false) { d_flag_valid_word = false; } } - current_synchro_data.TOW_at_current_symbol_ms = round(d_TOW_at_current_symbol * 1000.0); - current_synchro_data.Flag_valid_word = d_flag_valid_word; - if (d_dump == true) + if (d_flag_valid_word == true) { - // MULTIPLEXED FILE RECORDING - Record results to file - try - { - double tmp_double; - unsigned long int tmp_ulong_int; - tmp_double = d_TOW_at_current_symbol; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_ulong_int = current_synchro_data.Tracking_sample_counter; - d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(unsigned long int)); - tmp_double = d_TOW_at_Preamble; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "Exception writing Telemetry GPS L5 dump file " << e.what(); - } - } + current_synchro_data.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; + current_synchro_data.Flag_valid_word = d_flag_valid_word; - //3. Make the output (copy the object contents to the GNURadio reserved memory) - out[0] = current_synchro_data; - return 1; + if (d_dump == true) + { + // MULTIPLEXED FILE RECORDING - Record results to file + try + { + double tmp_double; + uint64_t tmp_ulong_int; + tmp_double = static_cast(d_TOW_at_current_symbol_ms) / 1000.0; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_ulong_int = current_synchro_data.Tracking_sample_counter; + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); + tmp_double = static_cast(d_TOW_at_Preamble_ms) / 1000.0; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "Exception writing Telemetry GPS L5 dump file " << e.what(); + } + } + + // 3. Make the output (copy the object contents to the GNURadio reserved memory) + out[0] = current_synchro_data; + return 1; + } + else + { + return 0; + } } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h index c5e838382..e5e98cde6 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_cc.h @@ -35,6 +35,7 @@ #include "gps_cnav_navigation_message.h" #include #include +#include #include #include #include @@ -66,11 +67,10 @@ class gps_l5_telemetry_decoder_cc : public gr::block public: ~gps_l5_telemetry_decoder_cc(); void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN - void set_channel(int channel); //!< Set receiver's channel + void set_channel(int32_t channel); //!< Set receiver's channel int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - private: friend gps_l5_telemetry_decoder_cc_sptr gps_l5_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); @@ -78,15 +78,15 @@ private: bool d_dump; Gnss_Satellite d_satellite; - int d_channel; + int32_t d_channel; std::string d_dump_filename; std::ofstream d_dump_file; cnav_msg_decoder_t d_cnav_decoder; - double d_TOW_at_current_symbol; - double d_TOW_at_Preamble; + uint32_t d_TOW_at_current_symbol_ms; + uint32_t d_TOW_at_Preamble_ms; bool d_flag_valid_word; Gps_CNAV_Navigation_Message d_CNAV_Message; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_cc.cc index ba65ce7df..2515788bb 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_cc.cc @@ -94,7 +94,7 @@ void sbas_l1_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite } -void sbas_l1_telemetry_decoder_cc::set_channel(int channel) +void sbas_l1_telemetry_decoder_cc::set_channel(int32_t channel) { d_channel = channel; LOG(INFO) << "SBAS channel set to " << channel; @@ -137,12 +137,12 @@ bool sbas_l1_telemetry_decoder_cc::sample_aligner::get_symbols(const std::vector VLOG(FLOW) << "get_symbols(): " << "d_past_sample=" << d_past_sample << "\tsamples size=" << samples.size(); - for (unsigned int i_sym = 0; i_sym < samples.size() / sbas_l1_telemetry_decoder_cc::d_samples_per_symbol; i_sym++) + for (uint32_t i_sym = 0; i_sym < samples.size() / sbas_l1_telemetry_decoder_cc::d_samples_per_symbol; i_sym++) { // get the next samples - for (int i = 0; i < d_n_smpls_in_history; i++) + for (int32_t i = 0; i < d_n_smpls_in_history; i++) { - smpls[i] = static_cast(i_sym) * sbas_l1_telemetry_decoder_cc::d_samples_per_symbol + i - 1 == -1 ? d_past_sample : samples[i_sym * sbas_l1_telemetry_decoder_cc::d_samples_per_symbol + i - 1]; + smpls[i] = static_cast(i_sym) * sbas_l1_telemetry_decoder_cc::d_samples_per_symbol + i - 1 == -1 ? d_past_sample : samples[i_sym * sbas_l1_telemetry_decoder_cc::d_samples_per_symbol + i - 1]; } // update the pseudo correlations (IIR method) of the two possible alignments @@ -158,7 +158,7 @@ bool sbas_l1_telemetry_decoder_cc::sample_aligner::get_symbols(const std::vector } // sum the correct pair of samples to a symbol, depending on the current alignment d_align - sym = smpls[0 + int(d_aligned) * 2] + smpls[1]; + sym = smpls[0 + int32_t(d_aligned) * 2] + smpls[1]; symbols.push_back(sym); // sample alignment debug output @@ -189,8 +189,8 @@ sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::symbol_aligner_and_dec { // convolutional code properties d_KK = 7; - int nn = 2; - int g_encoder[nn]; + const int32_t nn = 2; + int32_t g_encoder[nn]; g_encoder[0] = 121; g_encoder[1] = 91; @@ -215,11 +215,11 @@ void sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::reset() } -bool sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::get_bits(const std::vector symbols, std::vector &bits) +bool sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::get_bits(const std::vector symbols, std::vector &bits) { - const int traceback_depth = 5 * d_KK; - int nbits_requested = symbols.size() / d_symbols_per_bit; - int nbits_decoded; + const int32_t traceback_depth = 5 * d_KK; + int32_t nbits_requested = symbols.size() / d_symbols_per_bit; + int32_t nbits_decoded; // fill two vectors with the two possible symbol alignments std::vector symbols_vd1(symbols); // aligned symbol vector -> copy input symbol vector std::vector symbols_vd2; // shifted symbol vector -> add past sample in front of input vector @@ -229,13 +229,13 @@ bool sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::get_bits(const st symbols_vd2.push_back(*symbol_it); } // arrays for decoded bits - int *bits_vd1 = new int[nbits_requested]; - int *bits_vd2 = new int[nbits_requested]; + int32_t *bits_vd1 = new int32_t[nbits_requested]; + int32_t *bits_vd2 = new int32_t[nbits_requested]; // decode float metric_vd1 = d_vd1->decode_continuous(symbols_vd1.data(), traceback_depth, bits_vd1, nbits_requested, nbits_decoded); float metric_vd2 = d_vd2->decode_continuous(symbols_vd2.data(), traceback_depth, bits_vd2, nbits_requested, nbits_decoded); // choose the bits with the better metric - for (int i = 0; i < nbits_decoded; i++) + for (int32_t i = 0; i < nbits_decoded; i++) { if (metric_vd1 > metric_vd2) { // symbols aligned @@ -260,35 +260,35 @@ void sbas_l1_telemetry_decoder_cc::frame_detector::reset() } -void sbas_l1_telemetry_decoder_cc::frame_detector::get_frame_candidates(const std::vector bits, std::vector>> &msg_candidates) +void sbas_l1_telemetry_decoder_cc::frame_detector::get_frame_candidates(const std::vector bits, std::vector>> &msg_candidates) { std::stringstream ss; - unsigned int sbas_msg_length = 250; - std::vector> preambles = {{0, 1, 0, 1, 0, 0, 1, 1}, + uint32_t sbas_msg_length = 250; + std::vector> preambles = {{0, 1, 0, 1, 0, 0, 1, 1}, {1, 0, 0, 1, 1, 0, 1, 0}, {1, 1, 0, 0, 0, 1, 1, 0}}; VLOG(FLOW) << "get_frame_candidates(): " << "d_buffer.size()=" << d_buffer.size() << "\tbits.size()=" << bits.size(); ss << "copy bits "; - int count = 0; + int32_t count = 0; // copy new bits into the working buffer - for (std::vector::const_iterator bit_it = bits.cbegin(); bit_it < bits.cend(); ++bit_it) + for (std::vector::const_iterator bit_it = bits.cbegin(); bit_it < bits.cend(); ++bit_it) { d_buffer.push_back(*bit_it); ss << *bit_it; count++; } VLOG(SAMP_SYNC) << ss.str() << " into working buffer (" << count << " bits)"; - int relative_preamble_start = 0; + int32_t relative_preamble_start = 0; while (d_buffer.size() >= sbas_msg_length) { // compare with all preambles - for (std::vector>::iterator preample_it = preambles.begin(); preample_it < preambles.end(); ++preample_it) + for (std::vector>::iterator preample_it = preambles.begin(); preample_it < preambles.end(); ++preample_it) { bool preamble_detected = true; bool inv_preamble_detected = true; // compare the buffer bits with the preamble bits - for (std::vector::iterator preample_bit_it = preample_it->begin(); preample_bit_it < preample_it->end(); ++preample_bit_it) + for (std::vector::iterator preample_bit_it = preample_it->begin(); preample_bit_it < preample_it->end(); ++preample_bit_it) { preamble_detected = *preample_bit_it == d_buffer[preample_bit_it - preample_it->begin()] ? preamble_detected : false; inv_preamble_detected = *preample_bit_it != d_buffer[preample_bit_it - preample_it->begin()] ? inv_preamble_detected : false; @@ -296,18 +296,18 @@ void sbas_l1_telemetry_decoder_cc::frame_detector::get_frame_candidates(const st if (preamble_detected || inv_preamble_detected) { // copy candidate - std::vector candidate; + std::vector candidate; std::copy(d_buffer.begin(), d_buffer.begin() + sbas_msg_length, std::back_inserter(candidate)); if (inv_preamble_detected) { // invert bits - for (std::vector::iterator candidate_bit_it = candidate.begin(); candidate_bit_it != candidate.end(); candidate_bit_it++) + for (std::vector::iterator candidate_bit_it = candidate.begin(); candidate_bit_it != candidate.end(); candidate_bit_it++) *candidate_bit_it = *candidate_bit_it == 0 ? 1 : 0; } - msg_candidates.push_back(std::pair>(relative_preamble_start, candidate)); + msg_candidates.push_back(std::pair>(relative_preamble_start, candidate)); ss.str(""); ss << "preamble " << preample_it - preambles.begin() << (inv_preamble_detected ? " inverted" : " normal") << " detected! candidate="; - for (std::vector::iterator bit_it = candidate.begin(); bit_it < candidate.end(); ++bit_it) + for (std::vector::iterator bit_it = candidate.begin(); bit_it < candidate.end(); ++bit_it) ss << *bit_it; VLOG(EVENT) << ss.str(); } @@ -334,12 +334,12 @@ void sbas_l1_telemetry_decoder_cc::crc_verifier::get_valid_frames(const std::vec for (std::vector::const_iterator candidate_it = msg_candidates.cbegin(); candidate_it < msg_candidates.cend(); ++candidate_it) { // convert to bytes - std::vector candidate_bytes; + std::vector candidate_bytes; zerropad_back_and_convert_to_bytes(candidate_it->second, candidate_bytes); // verify CRC d_checksum_agent.reset(0); d_checksum_agent.process_bytes(candidate_bytes.data(), candidate_bytes.size()); - unsigned int crc = d_checksum_agent.checksum(); + uint32_t crc = d_checksum_agent.checksum(); VLOG(SAMP_SYNC) << "candidate " << candidate_it - msg_candidates.begin() << ": final crc remainder= " << std::hex << crc << std::setfill(' ') << std::resetiosflags(std::ios::hex); @@ -354,66 +354,66 @@ void sbas_l1_telemetry_decoder_cc::crc_verifier::get_valid_frames(const std::vec ss << "Not a valid message."; } ss << " Relbitoffset=" << candidate_it->first << " content="; - for (std::vector::iterator byte_it = candidate_bytes.begin(); byte_it < candidate_bytes.end(); ++byte_it) + for (std::vector::iterator byte_it = candidate_bytes.begin(); byte_it < candidate_bytes.end(); ++byte_it) { - ss << std::setw(2) << std::setfill('0') << std::hex << static_cast((*byte_it)); + ss << std::setw(2) << std::setfill('0') << std::hex << static_cast((*byte_it)); } VLOG(SAMP_SYNC) << ss.str() << std::setfill(' ') << std::resetiosflags(std::ios::hex) << std::endl; } } -void sbas_l1_telemetry_decoder_cc::crc_verifier::zerropad_back_and_convert_to_bytes(const std::vector msg_candidate, std::vector &bytes) +void sbas_l1_telemetry_decoder_cc::crc_verifier::zerropad_back_and_convert_to_bytes(const std::vector msg_candidate, std::vector &bytes) { std::stringstream ss; const size_t bits_per_byte = 8; - unsigned char byte = 0; + uint8_t byte = 0; VLOG(LMORE) << "zerropad_back_and_convert_to_bytes():" << byte; for (std::vector::const_iterator candidate_bit_it = msg_candidate.cbegin(); candidate_bit_it < msg_candidate.cend(); ++candidate_bit_it) { - int idx_bit = candidate_bit_it - msg_candidate.begin(); - int bit_pos_in_current_byte = (bits_per_byte - 1) - (idx_bit % bits_per_byte); - byte |= static_cast(*candidate_bit_it) << bit_pos_in_current_byte; + int32_t idx_bit = candidate_bit_it - msg_candidate.begin(); + int32_t bit_pos_in_current_byte = (bits_per_byte - 1) - (idx_bit % bits_per_byte); + byte |= static_cast(*candidate_bit_it) << bit_pos_in_current_byte; ss << *candidate_bit_it; if (idx_bit % bits_per_byte == bits_per_byte - 1) { bytes.push_back(byte); - VLOG(LMORE) << ss.str() << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << static_cast(byte); + VLOG(LMORE) << ss.str() << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << static_cast(byte); ss.str(""); byte = 0; } } bytes.push_back(byte); // implies: insert 6 zeros at the end to fit the 250bits into a multiple of bytes VLOG(LMORE) << " -> byte=" << std::setw(2) - << std::setfill('0') << std::hex << static_cast(byte) + << std::setfill('0') << std::hex << static_cast(byte) << std::setfill(' ') << std::resetiosflags(std::ios::hex); } -void sbas_l1_telemetry_decoder_cc::crc_verifier::zerropad_front_and_convert_to_bytes(const std::vector msg_candidate, std::vector &bytes) +void sbas_l1_telemetry_decoder_cc::crc_verifier::zerropad_front_and_convert_to_bytes(const std::vector msg_candidate, std::vector &bytes) { std::stringstream ss; const size_t bits_per_byte = 8; - unsigned char byte = 0; - int idx_bit = 6; // insert 6 zeros at the front to fit the 250bits into a multiple of bytes + uint8_t byte = 0; + int32_t idx_bit = 6; // insert 6 zeros at the front to fit the 250bits into a multiple of bytes VLOG(LMORE) << "zerropad_front_and_convert_to_bytes():" << byte; - for (std::vector::const_iterator candidate_bit_it = msg_candidate.cbegin(); candidate_bit_it < msg_candidate.cend(); ++candidate_bit_it) + for (std::vector::const_iterator candidate_bit_it = msg_candidate.cbegin(); candidate_bit_it < msg_candidate.cend(); ++candidate_bit_it) { - int bit_pos_in_current_byte = (bits_per_byte - 1) - (idx_bit % bits_per_byte); - byte |= static_cast(*candidate_bit_it) << bit_pos_in_current_byte; + int32_t bit_pos_in_current_byte = (bits_per_byte - 1) - (idx_bit % bits_per_byte); + byte |= static_cast(*candidate_bit_it) << bit_pos_in_current_byte; ss << *candidate_bit_it; if (idx_bit % bits_per_byte == bits_per_byte - 1) { bytes.push_back(byte); VLOG(LMORE) << ss.str() << " -> byte=" << std::setw(2) - << std::setfill('0') << std::hex << static_cast(byte); + << std::setfill('0') << std::hex << static_cast(byte); ss.str(""); byte = 0; } idx_bit++; } VLOG(LMORE) << " -> byte=" << std::setw(2) - << std::setfill('0') << std::hex << static_cast(byte) + << std::setfill('0') << std::hex << static_cast(byte) << std::setfill(' ') << std::resetiosflags(std::ios::hex); } @@ -427,8 +427,8 @@ int sbas_l1_telemetry_decoder_cc::general_work(int noutput_items __attribute__(( Gnss_Synchro *out = reinterpret_cast(output_items[0]); // Get the output buffer pointer const Gnss_Synchro *in = reinterpret_cast(input_items[0]); // Get the input buffer pointer - Gnss_Synchro current_symbol; //structure to save the synchronization information and send the output object to the next block - //1. Copy the current tracking output + Gnss_Synchro current_symbol; // structure to save the synchronization information and send the output object to the next block + // 1. Copy the current tracking output current_symbol = in[0]; // copy correlation samples into samples vector d_sample_buf.push_back(current_symbol.Prompt_I); //add new symbol to the symbol queue @@ -446,7 +446,7 @@ int sbas_l1_telemetry_decoder_cc::general_work(int noutput_items __attribute__(( // align symbols in pairs // and obtain the bits by decoding the symbol pairs - std::vector bits; + std::vector bits; bool symbol_alignment = d_symbol_aligner_and_decoder.get_bits(symbols, bits); // search for preambles @@ -465,7 +465,7 @@ int sbas_l1_telemetry_decoder_cc::general_work(int noutput_items __attribute__(( for (std::vector::const_iterator it = valid_msgs.cbegin(); it != valid_msgs.cend(); ++it) { - int message_sample_offset = + int32_t message_sample_offset = (sample_alignment ? 0 : -1) + d_samples_per_symbol * (symbol_alignment ? -1 : 0) + d_samples_per_symbol * d_symbols_per_bit * it->first; double message_sample_stamp = sample_stamp + static_cast(message_sample_offset) / 1000.0; VLOG(EVENT) << "message_sample_stamp=" << message_sample_stamp diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_cc.h index 39a315015..27853723f 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_cc.h @@ -36,6 +36,7 @@ #include #include #include // for copy +#include #include #include #include @@ -59,7 +60,7 @@ class sbas_l1_telemetry_decoder_cc : public gr::block public: ~sbas_l1_telemetry_decoder_cc(); void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN - void set_channel(int channel); //!< Set receiver's channel + void set_channel(int32_t channel); //!< Set receiver's channel /*! * \brief This is where all signal processing takes place @@ -72,16 +73,16 @@ private: sbas_l1_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); sbas_l1_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - void viterbi_decoder(double *page_part_symbols, int *page_part_bits); + void viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits); void align_samples(); - static const int d_samples_per_symbol = 2; - static const int d_symbols_per_bit = 2; - static const int d_block_size_in_bits = 30; + static const int32_t d_samples_per_symbol = 2; + static const int32_t d_symbols_per_bit = 2; + static const int32_t d_block_size_in_bits = 30; bool d_dump; Gnss_Satellite d_satellite; - int d_channel; + int32_t d_channel; std::string d_dump_filename; std::ofstream d_dump_file; @@ -89,8 +90,8 @@ private: size_t d_block_size; //!< number of samples which are processed during one invocation of the algorithms std::vector d_sample_buf; //!< input buffer holding the samples to be processed in one block - typedef std::pair> msg_candiate_int_t; - typedef std::pair> msg_candiate_char_t; + typedef std::pair> msg_candiate_int_t; + typedef std::pair> msg_candiate_char_t; // helper class for sample alignment class sample_aligner @@ -106,7 +107,7 @@ private: bool get_symbols(const std::vector samples, std::vector &symbols); private: - int d_n_smpls_in_history; + int32_t d_n_smpls_in_history; double d_iir_par; double d_corr_paired; double d_corr_shifted; @@ -121,10 +122,10 @@ private: symbol_aligner_and_decoder(); ~symbol_aligner_and_decoder(); void reset(); - bool get_bits(const std::vector symbols, std::vector &bits); + bool get_bits(const std::vector symbols, std::vector &bits); private: - int d_KK; + int32_t d_KK; Viterbi_Decoder *d_vd1; Viterbi_Decoder *d_vd2; double d_past_symbol; @@ -136,10 +137,10 @@ private: { public: void reset(); - void get_frame_candidates(const std::vector bits, std::vector>> &msg_candidates); + void get_frame_candidates(const std::vector bits, std::vector>> &msg_candidates); private: - std::deque d_buffer; + std::deque d_buffer; } d_frame_detector; @@ -153,8 +154,8 @@ private: private: typedef boost::crc_optimal<24, 0x1864CFBu, 0x0, 0x0, false, false> crc_24_q_type; crc_24_q_type d_checksum_agent; - void zerropad_front_and_convert_to_bytes(const std::vector msg_candidate, std::vector &bytes); - void zerropad_back_and_convert_to_bytes(const std::vector msg_candidate, std::vector &bytes); + void zerropad_front_and_convert_to_bytes(const std::vector msg_candidate, std::vector &bytes); + void zerropad_back_and_convert_to_bytes(const std::vector msg_candidate, std::vector &bytes); } d_crc_verifier; }; diff --git a/src/algorithms/telemetry_decoder/libs/CMakeLists.txt b/src/algorithms/telemetry_decoder/libs/CMakeLists.txt index 523ef2df2..53a997cc8 100644 --- a/src/algorithms/telemetry_decoder/libs/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/libs/CMakeLists.txt @@ -16,27 +16,36 @@ # along with GNSS-SDR. If not, see . # + add_subdirectory(libswiftcnav) -set(TELEMETRY_DECODER_LIB_SOURCES - gps_l1_ca_subframe_fsm.cc - viterbi_decoder.cc +set(TELEMETRY_DECODER_LIB_SOURCES + viterbi_decoder.cc +) + +set(TELEMETRY_DECODER_LIB_HEADERS + viterbi_decoder.h + convolutional.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/adapters - ${Boost_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/adapters + ${Boost_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} ) -file(GLOB TELEMETRY_DECODER_LIB_HEADERS "*.h") - list(SORT TELEMETRY_DECODER_LIB_HEADERS) -add_library(telemetry_decoder_lib ${TELEMETRY_DECODER_LIB_SOURCES} ${TELEMETRY_DECODER_LIB_HEADERS}) +list(SORT TELEMETRY_DECODER_LIB_SOURCES) + +add_library(telemetry_decoder_lib + ${TELEMETRY_DECODER_LIB_SOURCES} + ${TELEMETRY_DECODER_LIB_HEADERS} +) source_group(Headers FILES ${TELEMETRY_DECODER_LIB_HEADERS}) + target_link_libraries(telemetry_decoder_lib gnss_system_parameters) diff --git a/src/algorithms/telemetry_decoder/libs/gps_l1_ca_subframe_fsm.cc b/src/algorithms/telemetry_decoder/libs/gps_l1_ca_subframe_fsm.cc deleted file mode 100644 index d5317734e..000000000 --- a/src/algorithms/telemetry_decoder/libs/gps_l1_ca_subframe_fsm.cc +++ /dev/null @@ -1,289 +0,0 @@ -/*! - * \file gps_l1_ca_subframe_fsm.cc - * \brief Implementation of a GPS NAV message word-to-subframe decoder state machine - * \author Javier Arribas, 2011. jarribas(at)cttc.es - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) - * - * GNSS-SDR is a software defined Global Navigation - * Satellite Systems receiver - * - * This file is part of GNSS-SDR. - * - * GNSS-SDR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNSS-SDR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . - * - * ------------------------------------------------------------------------- - */ - -#include "gps_l1_ca_subframe_fsm.h" -#include "gnss_satellite.h" -#include -#include -#include -#include -#include -#include - - -//************ GPS WORD TO SUBFRAME DECODER STATE MACHINE ********** -struct Ev_gps_word_valid : sc::event -{ -}; - - -struct Ev_gps_word_invalid : sc::event -{ -}; - - -struct Ev_gps_word_preamble : sc::event -{ -}; - - -struct gps_subframe_fsm_S0 : public sc::state -{ -public: - // sc::transition(event,next_status) - typedef sc::transition reactions; - gps_subframe_fsm_S0(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S0 "< -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - gps_subframe_fsm_S1(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S1 "< -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - gps_subframe_fsm_S2(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S2 "<().gps_word_to_subframe(0); - } -}; - - -struct gps_subframe_fsm_S3 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - gps_subframe_fsm_S3(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S3 "<().gps_word_to_subframe(1); - } -}; - - -struct gps_subframe_fsm_S4 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - gps_subframe_fsm_S4(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S4 "<().gps_word_to_subframe(2); - } -}; - - -struct gps_subframe_fsm_S5 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - gps_subframe_fsm_S5(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S5 "<().gps_word_to_subframe(3); - } -}; - - -struct gps_subframe_fsm_S6 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - gps_subframe_fsm_S6(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S6 "<().gps_word_to_subframe(4); - } -}; - - -struct gps_subframe_fsm_S7 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - gps_subframe_fsm_S7(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S7 "<().gps_word_to_subframe(5); - } -}; - - -struct gps_subframe_fsm_S8 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - gps_subframe_fsm_S8(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S8 "<().gps_word_to_subframe(6); - } -}; - - -struct gps_subframe_fsm_S9 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - gps_subframe_fsm_S9(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S9 "<().gps_word_to_subframe(7); - } -}; - - -struct gps_subframe_fsm_S10 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - gps_subframe_fsm_S10(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S10 "<().gps_word_to_subframe(8); - } -}; - - -struct gps_subframe_fsm_S11 : public sc::state -{ -public: - typedef sc::transition reactions; - - gps_subframe_fsm_S11(my_context ctx) : my_base(ctx) - { - //std::cout<<"Completed GPS Subframe!"<().gps_word_to_subframe(9); - context().gps_subframe_to_nav_msg(); //decode the subframe - // DECODE SUBFRAME - //std::cout<<"Enter S11"<d_subframe); //decode the subframe - std::cout << "New GPS NAV message received in channel " << i_channel_ID << ": " - << "subframe " - << d_subframe_ID << " from satellite " - << Gnss_Satellite(std::string("GPS"), i_satellite_PRN) << std::endl; - d_nav.i_satellite_PRN = i_satellite_PRN; - d_nav.i_channel_ID = i_channel_ID; - - d_flag_new_subframe = true; -} - - -void GpsL1CaSubframeFsm::Event_gps_word_valid() -{ - this->process_event(Ev_gps_word_valid()); -} - - -void GpsL1CaSubframeFsm::Event_gps_word_invalid() -{ - this->process_event(Ev_gps_word_invalid()); -} - - -void GpsL1CaSubframeFsm::Event_gps_word_preamble() -{ - this->process_event(Ev_gps_word_preamble()); -} diff --git a/src/algorithms/telemetry_decoder/libs/gps_l1_ca_subframe_fsm.h b/src/algorithms/telemetry_decoder/libs/gps_l1_ca_subframe_fsm.h deleted file mode 100644 index 9a9a04bd8..000000000 --- a/src/algorithms/telemetry_decoder/libs/gps_l1_ca_subframe_fsm.h +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * \file gps_l1_ca_subframe_fsm.h - * \brief Interface of a GPS NAV message word-to-subframe decoder state machine - * \author Javier Arribas, 2011. jarribas(at)cttc.es - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) - * - * GNSS-SDR is a software defined Global Navigation - * Satellite Systems receiver - * - * This file is part of GNSS-SDR. - * - * GNSS-SDR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNSS-SDR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . - * - * ------------------------------------------------------------------------- - */ - - -#ifndef GNSS_SDR_GPS_L1_CA_SUBFRAME_FSM_H_ -#define GNSS_SDR_GPS_L1_CA_SUBFRAME_FSM_H_ - -#include "GPS_L1_CA.h" -#include "gps_navigation_message.h" -#include "gps_ephemeris.h" -#include "gps_iono.h" -#include "gps_almanac.h" -#include "gps_utc_model.h" -#include - -namespace sc = boost::statechart; -namespace mpl = boost::mpl; - -struct gps_subframe_fsm_S0; -struct gps_subframe_fsm_S1; -struct gps_subframe_fsm_S2; -struct gps_subframe_fsm_S3; -struct gps_subframe_fsm_S4; -struct gps_subframe_fsm_S5; -struct gps_subframe_fsm_S6; -struct gps_subframe_fsm_S7; -struct gps_subframe_fsm_S8; -struct gps_subframe_fsm_S9; -struct gps_subframe_fsm_S10; -struct gps_subframe_fsm_S11; - - -/*! - * \brief This class implements a Finite State Machine that handles the decoding - * of the GPS L1 C/A NAV message - */ -class GpsL1CaSubframeFsm : public sc::state_machine -{ -public: - GpsL1CaSubframeFsm(); //!< The constructor starts the Finite State Machine - void clear_flag_new_subframe(); - // channel and satellite info - int i_channel_ID; //!< Channel id - unsigned int i_satellite_PRN; //!< Satellite PRN number - - Gps_Navigation_Message d_nav; //!< GPS L1 C/A navigation message object - - // GPS SV and System parameters - Gps_Ephemeris ephemeris; //!< Object that handles GPS ephemeris parameters - Gps_Almanac almanac; //!< Object that handles GPS almanac data - Gps_Utc_Model utc_model; //!< Object that handles UTM model parameters - Gps_Iono iono; //!< Object that handles ionospheric parameters - - char d_subframe[GPS_SUBFRAME_LENGTH]; - int d_subframe_ID; - bool d_flag_new_subframe; - char d_GPS_frame_4bytes[GPS_WORD_LENGTH]; - //double d_preamble_time_ms; - - void gps_word_to_subframe(int position); //!< inserts the word in the correct position of the subframe - - /*! - * \brief This function decodes a NAv message subframe and pushes the information to the right queues - */ - void gps_subframe_to_nav_msg(); - - //FSM EVENTS - void Event_gps_word_valid(); //!< FSM event: the received word is valid - void Event_gps_word_invalid(); //!< FSM event: the received word is not valid - void Event_gps_word_preamble(); //!< FSM event: word preamble detected -}; - -#endif diff --git a/src/algorithms/telemetry_decoder/libs/libswiftcnav/CMakeLists.txt b/src/algorithms/telemetry_decoder/libs/libswiftcnav/CMakeLists.txt index a9f7a1622..af753c057 100644 --- a/src/algorithms/telemetry_decoder/libs/libswiftcnav/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/libs/libswiftcnav/CMakeLists.txt @@ -16,20 +16,34 @@ # along with GNSS-SDR. If not, see . # -set(TELEMETRY_DECODER_LIBSWIFTCNAV_SOURCES - cnav_msg.c - bits.c - edc.c - viterbi27.c +set(TELEMETRY_DECODER_LIBSWIFTCNAV_SOURCES + cnav_msg.c + bits.c + edc.c + viterbi27.c +) + +set(TELEMETRY_DECODER_LIBSWIFTCNAV_HEADERS + cnav_msg.h + bits.h + edc.h + swift_common.h + fec.h ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} ) -file(GLOB TELEMETRY_DECODER_LIBSWIFTCNAV_HEADERS "*.h") list(SORT TELEMETRY_DECODER_LIBSWIFTCNAV_HEADERS) +list(SORT TELEMETRY_DECODER_LIBSWIFTCNAV_SOURCES) + +add_library(telemetry_decoder_libswiftcnav STATIC + ${TELEMETRY_DECODER_LIBSWIFTCNAV_SOURCES} + ${TELEMETRY_DECODER_LIBSWIFTCNAV_HEADERS} +) -add_library(telemetry_decoder_libswiftcnav STATIC ${TELEMETRY_DECODER_LIBSWIFTCNAV_SOURCES} ${TELEMETRY_DECODER_LIBSWIFTCNAV_HEADERS}) source_group(Headers FILES ${TELEMETRY_DECODER_LIBSWIFTCNAV_HEADERS}) -set_target_properties(telemetry_decoder_libswiftcnav PROPERTIES LINKER_LANGUAGE C) \ No newline at end of file + +set_target_properties(telemetry_decoder_libswiftcnav + PROPERTIES LINKER_LANGUAGE C) diff --git a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c index 5248c0f7c..bbb52ac4d 100644 --- a/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c +++ b/src/algorithms/telemetry_decoder/libs/libswiftcnav/cnav_msg.c @@ -30,7 +30,6 @@ */ - #include "edc.h" #include "bits.h" #include "cnav_msg.h" @@ -48,26 +47,26 @@ * Block Viterbi decoding parameters. */ /** Viterbi decoder reversed polynomial A */ -#define GPS_L2C_V27_POLY_A (0x4F) /* 0b01001111 - reversed 0171*/ +#define GPS_L2C_V27_POLY_A (0x4F) /* 0b01001111 - reversed 0171*/ /** Viterbi decoder reversed polynomial B */ -#define GPS_L2C_V27_POLY_B (0x6D) /* 0b01101101 - reversed 0133 */ +#define GPS_L2C_V27_POLY_B (0x6D) /* 0b01101101 - reversed 0133 */ /* * GPS L2C message constants. */ /** GPS L2C preamble */ -#define GPS_CNAV_PREAMBLE1 (0b10001011u) +const u32 GPS_CNAV_PREAMBLE1 = 0x8Bu; /* (0b10001011u) */ /** Inverted GPS L2C preamble */ -#define GPS_CNAV_PREAMBLE2 (0b01110100u) +const u32 GPS_CNAV_PREAMBLE2 = 0x74u; /* (0b01110100u) */ /** GPS L2C preamble length in bits */ -#define GPS_CNAV_PREAMBLE_LENGTH (8) +#define GPS_CNAV_PREAMBLE_LENGTH (8) /** GPS L2C CNAV message length in bits */ -#define GPS_CNAV_MSG_LENGTH (300) +#define GPS_CNAV_MSG_LENGTH (300) /** GPS LC2 CNAV CRC length in bits */ -#define GPS_CNAV_MSG_CRC_LENGTH (24) +#define GPS_CNAV_MSG_CRC_LENGTH (24) /** GPS L2C CNAV message payload length in bits */ -#define GPS_CNAV_MSG_DATA_LENGTH (GPS_CNAV_MSG_LENGTH - GPS_CNAV_MSG_CRC_LENGTH) +#define GPS_CNAV_MSG_DATA_LENGTH (GPS_CNAV_MSG_LENGTH - GPS_CNAV_MSG_CRC_LENGTH) /** GPS L2C CNAV message lock detector threshold */ #define GPS_CNAV_LOCK_MAX_CRC_FAILS (10) @@ -85,7 +84,7 @@ static u32 _cnav_compute_crc(cnav_v27_part_t *part) { u32 crc = crc24q_bits(0, part->decoded, GPS_CNAV_MSG_DATA_LENGTH, - part->invert); + part->invert); return crc; } @@ -104,7 +103,7 @@ static u32 _cnav_compute_crc(cnav_v27_part_t *part) static u32 _cnav_extract_crc(const cnav_v27_part_t *part) { u32 crc = getbitu(part->decoded, GPS_CNAV_MSG_DATA_LENGTH, - GPS_CNAV_MSG_CRC_LENGTH); + GPS_CNAV_MSG_CRC_LENGTH); if (part->invert) { crc ^= 0xFFFFFF; @@ -152,7 +151,7 @@ static void _cnav_rescan_preamble(cnav_v27_part_t *part) if (!part->preamble_seen && part->n_decoded >= GPS_CNAV_PREAMBLE_LENGTH) { bitshl(part->decoded, sizeof(part->decoded), - part->n_decoded - GPS_CNAV_PREAMBLE_LENGTH + 1); + part->n_decoded - GPS_CNAV_PREAMBLE_LENGTH + 1); part->n_decoded = GPS_CNAV_PREAMBLE_LENGTH - 1; } } @@ -200,11 +199,12 @@ static void _cnav_add_symbol(cnav_v27_part_t *part, u8 ch) * - N - Number of bits to put into decoded buffer * - M - Number of bits in the tail to ignore. */ - unsigned char tmp_bits[ (GPS_L2C_V27_DECODE_BITS + GPS_L2C_V27_DELAY_BITS + - CHAR_BIT - 1) / CHAR_BIT]; + unsigned char tmp_bits[(GPS_L2C_V27_DECODE_BITS + GPS_L2C_V27_DELAY_BITS + + CHAR_BIT - 1) / + CHAR_BIT]; v27_chainback_likely(&part->dec, tmp_bits, - GPS_L2C_V27_DECODE_BITS + GPS_L2C_V27_DELAY_BITS); + GPS_L2C_V27_DECODE_BITS + GPS_L2C_V27_DELAY_BITS); /* Read decoded bits and add them to the decoded buffer */ bitcopy(part->decoded, part->n_decoded, tmp_bits, 0, GPS_L2C_V27_DECODE_BITS); @@ -238,10 +238,9 @@ static void _cnav_add_symbol(cnav_v27_part_t *part, u8 ch) } if (part->preamble_seen && GPS_CNAV_MSG_LENGTH <= part->n_decoded) { - /* We have collected 300 bits starting from message preamble. Now try * to compute CRC-24Q */ - u32 crc = _cnav_compute_crc(part); + u32 crc = _cnav_compute_crc(part); u32 crc2 = _cnav_extract_crc(part); if (part->message_lock) @@ -260,8 +259,8 @@ static void _cnav_add_symbol(cnav_v27_part_t *part, u8 ch) if (part->n_crc_fail > GPS_CNAV_LOCK_MAX_CRC_FAILS) { /* CRC has failed too many times - drop the lock. */ - part->n_crc_fail = 0; - part->message_lock = false; + part->n_crc_fail = 0; + part->message_lock = false; part->preamble_seen = false; /* Try to find a new preamble, reuse data from buffer. */ retry = true; @@ -272,8 +271,8 @@ static void _cnav_add_symbol(cnav_v27_part_t *part, u8 ch) { /* CRC match - message can be decoded */ part->message_lock = true; - part->crc_ok = true; - part->n_crc_fail = 0; + part->crc_ok = true; + part->n_crc_fail = 0; } else { @@ -346,13 +345,13 @@ static bool _cnav_msg_decode(cnav_v27_part_t *part, cnav_msg_t *msg, u32 *delay) _cnav_msg_invert(part); } - msg->prn = getbitu(part->decoded, 8, 6); + msg->prn = getbitu(part->decoded, 8, 6); msg->msg_id = getbitu(part->decoded, 14, 6); - msg->tow = getbitu(part->decoded, 20, 17); - msg->alert = getbitu(part->decoded, 37, 1) ? true : false; + msg->tow = getbitu(part->decoded, 20, 17); + msg->alert = getbitu(part->decoded, 37, 1) ? true : false; /* copy RAW message for GNSS-SDR */ - memcpy(msg->raw_msg,part->decoded,GPS_L2C_V27_DECODE_BITS + GPS_L2C_V27_DELAY_BITS); + memcpy(msg->raw_msg, part->decoded, GPS_L2C_V27_DECODE_BITS + GPS_L2C_V27_DELAY_BITS); *delay = (part->n_decoded - GPS_CNAV_MSG_LENGTH + GPS_L2C_V27_DELAY_BITS) * 2 + part->n_symbols; @@ -388,15 +387,15 @@ void cnav_msg_decoder_init(cnav_msg_decoder_t *dec) { memset(dec, 0, sizeof(*dec)); v27_init(&dec->part1.dec, - dec->part1.decisions, - GPS_L2_V27_HISTORY_LENGTH_BITS, - cnav_msg_decoder_get_poly(), - 0); + dec->part1.decisions, + GPS_L2_V27_HISTORY_LENGTH_BITS, + cnav_msg_decoder_get_poly(), + 0); v27_init(&dec->part2.dec, - dec->part2.decisions, - GPS_L2_V27_HISTORY_LENGTH_BITS, - cnav_msg_decoder_get_poly(), - 0); + dec->part2.decisions, + GPS_L2_V27_HISTORY_LENGTH_BITS, + cnav_msg_decoder_get_poly(), + 0); dec->part1.init = true; dec->part2.init = true; _cnav_add_symbol(&dec->part2, 0x80); @@ -426,9 +425,9 @@ void cnav_msg_decoder_init(cnav_msg_decoder_t *dec) * \retval false More data is required. */ bool cnav_msg_decoder_add_symbol(cnav_msg_decoder_t *dec, - u8 symbol, - cnav_msg_t *msg, - u32 *pdelay) + u8 symbol, + cnav_msg_t *msg, + u32 *pdelay) { _cnav_add_symbol(&dec->part1, symbol); _cnav_add_symbol(&dec->part2, symbol); @@ -470,7 +469,7 @@ const v27_poly_t *cnav_msg_decoder_get_poly(void) if (!initialized) { /* Coefficients for polynomial object */ - const signed char coeffs[2] = { GPS_L2C_V27_POLY_A, GPS_L2C_V27_POLY_B }; + const signed char coeffs[2] = {GPS_L2C_V27_POLY_A, GPS_L2C_V27_POLY_B}; /* Racing condition handling: the data can be potential initialized more * than once in case multiple threads request concurrent access. However, diff --git a/src/algorithms/tracking/adapters/CMakeLists.txt b/src/algorithms/tracking/adapters/CMakeLists.txt index 8a992b599..5150aa400 100644 --- a/src/algorithms/tracking/adapters/CMakeLists.txt +++ b/src/algorithms/tracking/adapters/CMakeLists.txt @@ -16,48 +16,103 @@ # along with GNSS-SDR. If not, see . # + if(ENABLE_CUDA) - set(OPT_TRACKING_ADAPTERS ${OPT_TRACKING_ADAPTERS} gps_l1_ca_dll_pll_tracking_gpu.cc) - set(OPT_TRACKING_INCLUDE_DIRS ${OPT_TRACKING_INCLUDE_DIRS} ${CUDA_INCLUDE_DIRS}) -endif(ENABLE_CUDA) + set(OPT_TRACKING_ADAPTERS_SOURCES + ${OPT_TRACKING_ADAPTERS_SOURCES} + gps_l1_ca_dll_pll_tracking_gpu.cc + ) + set(OPT_TRACKING_ADAPTERS_HEADERS + ${OPT_TRACKING_ADAPTERS_HEADERS} + gps_l1_ca_dll_pll_tracking_gpu.h + ) + set(OPT_TRACKING_INCLUDE_DIRS + ${OPT_TRACKING_INCLUDE_DIRS} + ${CUDA_INCLUDE_DIRS} + ) +endif() if(ENABLE_FPGA) - SET(OPT_TRACKING_ADAPTERS ${OPT_TRACKING_ADAPTERS} gps_l1_ca_dll_pll_tracking_fpga.cc) -endif(ENABLE_FPGA) + set(OPT_TRACKING_ADAPTERS_SOURCES + ${OPT_TRACKING_ADAPTERS_SOURCES} + gps_l1_ca_dll_pll_tracking_fpga.cc + gps_l2_m_dll_pll_tracking_fpga.cc + galileo_e1_dll_pll_veml_tracking_fpga.cc + galileo_e5a_dll_pll_tracking_fpga.cc + gps_l5_dll_pll_tracking_fpga.cc + ) + set(OPT_TRACKING_ADAPTERS_HEADERS + ${OPT_TRACKING_ADAPTERS_HEADERS} + gps_l1_ca_dll_pll_tracking_fpga.h + gps_l2_m_dll_pll_tracking_fpga.h + galileo_e1_dll_pll_veml_tracking_fpga.h + galileo_e5a_dll_pll_tracking_fpga.h + gps_l5_dll_pll_tracking_fpga.h + ) +endif() set(TRACKING_ADAPTER_SOURCES - galileo_e1_dll_pll_veml_tracking.cc - galileo_e1_tcp_connector_tracking.cc - gps_l1_ca_dll_pll_tracking.cc - gps_l1_ca_dll_pll_c_aid_tracking.cc - gps_l1_ca_tcp_connector_tracking.cc - galileo_e5a_dll_pll_tracking.cc - gps_l2_m_dll_pll_tracking.cc - glonass_l1_ca_dll_pll_tracking.cc - glonass_l1_ca_dll_pll_c_aid_tracking.cc - gps_l5_dll_pll_tracking.cc - glonass_l2_ca_dll_pll_tracking.cc - glonass_l2_ca_dll_pll_c_aid_tracking.cc - ${OPT_TRACKING_ADAPTERS} + galileo_e1_dll_pll_veml_tracking.cc + galileo_e1_tcp_connector_tracking.cc + gps_l1_ca_dll_pll_tracking.cc + gps_l1_ca_dll_pll_c_aid_tracking.cc + gps_l1_ca_tcp_connector_tracking.cc + galileo_e5a_dll_pll_tracking.cc + gps_l2_m_dll_pll_tracking.cc + glonass_l1_ca_dll_pll_tracking.cc + glonass_l1_ca_dll_pll_c_aid_tracking.cc + gps_l1_ca_kf_tracking.cc + gps_l5_dll_pll_tracking.cc + glonass_l2_ca_dll_pll_tracking.cc + glonass_l2_ca_dll_pll_c_aid_tracking.cc + ${OPT_TRACKING_ADAPTERS_SOURCES} +) + +set(TRACKING_ADAPTER_HEADERS + galileo_e1_dll_pll_veml_tracking.h + galileo_e1_tcp_connector_tracking.h + gps_l1_ca_dll_pll_tracking.h + gps_l1_ca_dll_pll_c_aid_tracking.h + gps_l1_ca_tcp_connector_tracking.h + galileo_e5a_dll_pll_tracking.h + gps_l2_m_dll_pll_tracking.h + glonass_l1_ca_dll_pll_tracking.h + glonass_l1_ca_dll_pll_c_aid_tracking.h + gps_l1_ca_kf_tracking.h + gps_l5_dll_pll_tracking.h + glonass_l2_ca_dll_pll_tracking.h + glonass_l2_ca_dll_pll_c_aid_tracking.h + ${OPT_TRACKING_ADAPTERS_HEADERS} ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${VOLK_GNSSSDR_INCLUDE_DIRS} - ${OPT_TRACKING_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${ARMADILLO_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_GNSSSDR_INCLUDE_DIRS} + ${OPT_TRACKING_INCLUDE_DIRS} ) -file(GLOB TRACKING_ADAPTER_HEADERS "*.h") list(SORT TRACKING_ADAPTER_HEADERS) -add_library(tracking_adapters ${TRACKING_ADAPTER_SOURCES} ${TRACKING_ADAPTER_HEADERS}) +list(SORT TRACKING_ADAPTER_SOURCES) + +add_library(tracking_adapters + ${TRACKING_ADAPTER_SOURCES} + ${TRACKING_ADAPTER_HEADERS} +) + source_group(Headers FILES ${TRACKING_ADAPTER_HEADERS}) -target_link_libraries(tracking_adapters tracking_gr_blocks gnss_sp_libs gnss_sdr_flags) + +target_link_libraries(tracking_adapters + tracking_gr_blocks + gnss_sp_libs + gnss_sdr_flags +) diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc index 48e821674..bb1ff89cd 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GalileoE1DllPllVemlTracking::stop_tracking() +{ +} + GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -59,6 +63,21 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( trk_param.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param.dump_mat = dump_mat; + trk_param.high_dyn = configuration->property(role + ".high_dyn", false); + if (configuration->property(role + ".smoother_length", 10) < 1) + { + trk_param.smoother_length = 1; + std::cout << TEXT_RED << "WARNING: Gal. E1. smoother_length must be bigger than 0. It has been set to 1" << TEXT_RESET << std::endl; + } + else + { + trk_param.smoother_length = configuration->property(role + ".smoother_length", 10); + } float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 5.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param.pll_bw_hz = pll_bw_hz; @@ -95,9 +114,6 @@ GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( } trk_param.track_pilot = track_pilot; trk_param.extend_correlation_symbols = extend_correlation_symbols; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param.dump_filename = dump_filename; int vector_length = std::round(fs_in / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)); trk_param.vector_length = vector_length; trk_param.system = 'E'; diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h index 7904b958d..f6193fde5 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.h @@ -92,6 +92,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: dll_pll_veml_tracking_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.cc new file mode 100644 index 000000000..179e19f3c --- /dev/null +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.cc @@ -0,0 +1,271 @@ +/*! + * \file galileo_e1_dll_pll_veml_tracking.cc + * \brief Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block + * to a TrackingInterface for Galileo E1 signals + * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkhauser, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "galileo_e1_dll_pll_veml_tracking_fpga.h" +#include "configuration_interface.h" +#include "Galileo_E1.h" +#include "galileo_e1_signal_processing.h" +#include "gnss_sdr_flags.h" +#include "display.h" +#include + +//#define NUM_PRNs_GALILEO_E1 50 + +using google::LogMessage; + +void GalileoE1DllPllVemlTrackingFpga::stop_tracking() +{ +} + +GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga( + ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + //dllpllconf_t trk_param; + Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); + DLOG(INFO) << "role " << role; + //################# CONFIGURATION PARAMETERS ######################## + std::string default_item_type = "gr_complex"; + std::string item_type = configuration->property(role + ".item_type", default_item_type); + int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); + int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + trk_param_fpga.fs_in = fs_in; + bool dump = configuration->property(role + ".dump", false); + trk_param_fpga.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param_fpga.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param_fpga.dump_mat = dump_mat; + float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 5.0); + if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); + trk_param_fpga.pll_bw_hz = pll_bw_hz; + float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 0.5); + if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast(FLAGS_dll_bw_hz); + trk_param_fpga.dll_bw_hz = dll_bw_hz; + float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 2.0); + trk_param_fpga.pll_bw_narrow_hz = pll_bw_narrow_hz; + float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 0.25); + trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz; + int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); + float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.15); + trk_param_fpga.early_late_space_chips = early_late_space_chips; + float very_early_late_space_chips = configuration->property(role + ".very_early_late_space_chips", 0.6); + trk_param_fpga.very_early_late_space_chips = very_early_late_space_chips; + float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15); + trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips; + float very_early_late_space_narrow_chips = configuration->property(role + ".very_early_late_space_narrow_chips", 0.6); + trk_param_fpga.very_early_late_space_narrow_chips = very_early_late_space_narrow_chips; + bool track_pilot = configuration->property(role + ".track_pilot", false); + if (extend_correlation_symbols < 1) + { + extend_correlation_symbols = 1; + std::cout << TEXT_RED << "WARNING: Galileo E1. extend_correlation_symbols must be bigger than 0. Coherent integration has been set to 1 symbol (4 ms)" << TEXT_RESET << std::endl; + } + else if (!track_pilot and extend_correlation_symbols > 1) + { + extend_correlation_symbols = 1; + std::cout << TEXT_RED << "WARNING: Galileo E1. Extended coherent integration is not allowed when tracking the data component. Coherent integration has been set to 4 ms (1 symbol)" << TEXT_RESET << std::endl; + } + if ((extend_correlation_symbols > 1) and (pll_bw_narrow_hz > pll_bw_hz or dll_bw_narrow_hz > dll_bw_hz)) + { + std::cout << TEXT_RED << "WARNING: Galileo E1. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << std::endl; + } + trk_param_fpga.track_pilot = track_pilot; + d_track_pilot = track_pilot; + trk_param_fpga.extend_correlation_symbols = extend_correlation_symbols; + int vector_length = std::round(fs_in / (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS)); + trk_param_fpga.vector_length = vector_length; + trk_param_fpga.system = 'E'; + char sig_[3] = "1B"; + std::memcpy(trk_param_fpga.signal, sig_, 3); + int cn0_samples = configuration->property(role + ".cn0_samples", 20); + if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; + trk_param_fpga.cn0_samples = cn0_samples; + int cn0_min = configuration->property(role + ".cn0_min", 25); + if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; + trk_param_fpga.cn0_min = cn0_min; + int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); + if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; + trk_param_fpga.max_lock_fail = max_lock_fail; + double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); + if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; + trk_param_fpga.carrier_lock_th = carrier_lock_th; + + // FPGA configuration parameters + std::string default_device_name = "/dev/uio"; + std::string device_name = configuration->property(role + ".devicename", default_device_name); + trk_param_fpga.device_name = device_name; + unsigned int device_base = configuration->property(role + ".device_base", 1); + trk_param_fpga.device_base = device_base; + //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 1); + trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> 5 correlators + + //################# PRE-COMPUTE ALL THE CODES ################# + unsigned int code_samples_per_chip = 2; + d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) * code_samples_per_chip * Galileo_E1_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); + float* ca_codes_f; + float* data_codes_f; + + if (trk_param_fpga.track_pilot) + { + d_data_codes = static_cast(volk_gnsssdr_malloc((static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * Galileo_E1_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); + } + ca_codes_f = static_cast(volk_gnsssdr_malloc(static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) * code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment())); + + if (trk_param_fpga.track_pilot) + { + data_codes_f = static_cast(volk_gnsssdr_malloc((static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)) * code_samples_per_chip * sizeof(float), volk_gnsssdr_get_alignment())); + } + + //printf("pppppppp trk_param_fpga.track_pilot = %d\n", trk_param_fpga.track_pilot); + + //int kk; + + for (unsigned int PRN = 1; PRN <= Galileo_E1_NUMBER_OF_CODES; PRN++) + { + char data_signal[3] = "1B"; + if (trk_param_fpga.track_pilot) + { + //printf("yes tracking pilot !!!!!!!!!!!!!!!\n"); + char pilot_signal[3] = "1C"; + galileo_e1_code_gen_sinboc11_float(ca_codes_f, pilot_signal, PRN); + galileo_e1_code_gen_sinboc11_float(data_codes_f, data_signal, PRN); + + for (unsigned int s = 0; s < 2 * Galileo_E1_B_CODE_LENGTH_CHIPS; s++) + { + d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) * 2 * (PRN - 1) + s] = static_cast(ca_codes_f[s]); + d_data_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) * 2 * (PRN - 1) + s] = static_cast(data_codes_f[s]); + //printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); + } + //printf("\n next \n"); + //scanf ("%d",&kk); + } + else + { + //printf("no tracking pilot\n"); + galileo_e1_code_gen_sinboc11_float(ca_codes_f, data_signal, PRN); + + for (unsigned int s = 0; s < 2 * Galileo_E1_B_CODE_LENGTH_CHIPS; s++) + { + d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS) * 2 * (PRN - 1) + s] = static_cast(ca_codes_f[s]); + //printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); + } + //printf("\n next \n"); + //scanf ("%d",&kk); + } + } + + delete[] ca_codes_f; + if (trk_param_fpga.track_pilot) + { + delete[] data_codes_f; + } + trk_param_fpga.ca_codes = d_ca_codes; + trk_param_fpga.data_codes = d_data_codes; + trk_param_fpga.code_length_chips = Galileo_E1_B_CODE_LENGTH_CHIPS; + trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip + //################# MAKE TRACKING GNURadio object ################### + tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); + channel_ = 0; + DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; +} + + +GalileoE1DllPllVemlTrackingFpga::~GalileoE1DllPllVemlTrackingFpga() +{ + delete[] d_ca_codes; + if (d_track_pilot) + { + delete[] d_data_codes; + } +} + +void GalileoE1DllPllVemlTrackingFpga::start_tracking() +{ + //tracking_->start_tracking(); + tracking_fpga_sc->start_tracking(); +} + + +/* + * Set tracking channel unique ID + */ +void GalileoE1DllPllVemlTrackingFpga::set_channel(unsigned int channel) +{ + channel_ = channel; + //tracking_->set_channel(channel); + tracking_fpga_sc->set_channel(channel); +} + + +void GalileoE1DllPllVemlTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +{ + //tracking_->set_gnss_synchro(p_gnss_synchro); + tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); +} + + +void GalileoE1DllPllVemlTrackingFpga::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + //nothing to connect, now the tracking uses gr_sync_decimator +} + + +void GalileoE1DllPllVemlTrackingFpga::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + //nothing to disconnect, now the tracking uses gr_sync_decimator +} + + +gr::basic_block_sptr GalileoE1DllPllVemlTrackingFpga::get_left_block() +{ + //return tracking_; + return tracking_fpga_sc; +} + + +gr::basic_block_sptr GalileoE1DllPllVemlTrackingFpga::get_right_block() +{ + //return tracking_; + return tracking_fpga_sc; +} diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h new file mode 100644 index 000000000..55d8127ee --- /dev/null +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h @@ -0,0 +1,116 @@ +/*! + * \file galileo_e1_dll_pll_veml_tracking.h + * \brief Adapts a DLL+PLL VEML (Very Early Minus Late) tracking loop block + * to a TrackingInterface for Galileo E1 signals + * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkhauser, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_FPGA_H_ +#define GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_FPGA_H_ + +#include "tracking_interface.h" +#include "dll_pll_veml_tracking_fpga.h" +#include + + +class ConfigurationInterface; + +/*! + * \brief This class Adapts a DLL+PLL VEML (Very Early Minus Late) tracking + * loop block to a TrackingInterface for Galileo E1 signals + */ +class GalileoE1DllPllVemlTrackingFpga : public TrackingInterface +{ +public: + GalileoE1DllPllVemlTrackingFpga(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams); + + virtual ~GalileoE1DllPllVemlTrackingFpga(); + + inline std::string role() override + { + return role_; + } + + //! Returns "Galileo_E1_DLL_PLL_VEML_Tracking" + inline std::string implementation() override + { + return "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"; + } + + 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; + + /*! + * \brief Set tracking channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and + * tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + void start_tracking() override; + + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + + +private: + //dll_pll_veml_tracking_sptr tracking_; + dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; + size_t item_size_; + unsigned int channel_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + int* d_ca_codes; + int* d_data_codes; + bool d_track_pilot; +}; + + +#endif // GNSS_SDR_GALILEO_E1_DLL_PLL_VEML_TRACKING_FPGA_H_ diff --git a/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc b/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc index 51e526173..5b21f41ee 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc @@ -44,6 +44,10 @@ using google::LogMessage; +void GalileoE1TcpConnectorTracking::stop_tracking() +{ +} + GalileoE1TcpConnectorTracking::GalileoE1TcpConnectorTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.h b/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.h index ae4b38220..8a75834d6 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.h +++ b/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.h @@ -93,6 +93,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: galileo_e1_tcp_connector_tracking_cc_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc index fe6f4a7d6..c3a8244e2 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GalileoE5aDllPllTracking::stop_tracking() +{ +} + GalileoE5aDllPllTracking::GalileoE5aDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -59,6 +63,21 @@ GalileoE5aDllPllTracking::GalileoE5aDllPllTracking( trk_param.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param.dump_mat = dump_mat; + trk_param.high_dyn = configuration->property(role + ".high_dyn", false); + if (configuration->property(role + ".smoother_length", 10) < 1) + { + trk_param.smoother_length = 1; + std::cout << TEXT_RED << "WARNING: Gal. E5a. smoother_length must be bigger than 0. It has been set to 1" << TEXT_RESET << std::endl; + } + else + { + trk_param.smoother_length = configuration->property(role + ".smoother_length", 10); + } float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 20.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param.pll_bw_hz = pll_bw_hz; @@ -71,9 +90,6 @@ GalileoE5aDllPllTracking::GalileoE5aDllPllTracking( trk_param.dll_bw_narrow_hz = dll_bw_narrow_hz; float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); trk_param.early_late_space_chips = early_late_space_chips; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param.dump_filename = dump_filename; int vector_length = std::round(fs_in / (Galileo_E5a_CODE_CHIP_RATE_HZ / Galileo_E5a_CODE_LENGTH_CHIPS)); trk_param.vector_length = vector_length; int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.h b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.h index 484754b23..c9444f503 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.h @@ -91,6 +91,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: dll_pll_veml_tracking_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc new file mode 100644 index 000000000..d4fa38d2f --- /dev/null +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc @@ -0,0 +1,288 @@ +/*! + * \file galileo_e5a_dll_pll_tracking.cc + * \brief Adapts a code DLL + carrier PLL + * tracking block to a TrackingInterface for Galileo E5a signals + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Galileo E5a data and pilot Signals + * \author Marc Sales, 2014. marcsales92(at)gmail.com + * \based on work from: + *
        + *
      • Javier Arribas, 2011. jarribas(at)cttc.es + *
      • Luis Esteve, 2012. luis(at)epsilon-formacion.com + *
      + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "galileo_e5a_dll_pll_tracking_fpga.h" +#include "configuration_interface.h" +#include "Galileo_E5a.h" +#include "galileo_e5_signal_processing.h" +#include "gnss_sdr_flags.h" +#include "display.h" +#include + +using google::LogMessage; + +void GalileoE5aDllPllTrackingFpga::stop_tracking() +{ +} + +GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( + ConfigurationInterface *configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + //printf("creating the E5A tracking"); + + + Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); + DLOG(INFO) << "role " << role; + //################# CONFIGURATION PARAMETERS ######################## + std::string default_item_type = "gr_complex"; + std::string item_type = configuration->property(role + ".item_type", default_item_type); + int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 12000000); + int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + trk_param_fpga.fs_in = fs_in; + bool dump = configuration->property(role + ".dump", false); + trk_param_fpga.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param_fpga.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param_fpga.dump_mat = dump_mat; + float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 20.0); + if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); + trk_param_fpga.pll_bw_hz = pll_bw_hz; + float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 20.0); + if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast(FLAGS_dll_bw_hz); + trk_param_fpga.dll_bw_hz = dll_bw_hz; + float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 5.0); + trk_param_fpga.pll_bw_narrow_hz = pll_bw_narrow_hz; + float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 2.0); + trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz; + float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); + trk_param_fpga.early_late_space_chips = early_late_space_chips; + int vector_length = std::round(fs_in / (Galileo_E5a_CODE_CHIP_RATE_HZ / Galileo_E5a_CODE_LENGTH_CHIPS)); + trk_param_fpga.vector_length = vector_length; + int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); + float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15); + trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips; + bool track_pilot = configuration->property(role + ".track_pilot", false); + d_track_pilot = track_pilot; + if (extend_correlation_symbols < 1) + { + extend_correlation_symbols = 1; + std::cout << TEXT_RED << "WARNING: Galileo E5a. extend_correlation_symbols must be bigger than 0. Coherent integration has been set to 1 symbol (1 ms)" << TEXT_RESET << std::endl; + } + else if (!track_pilot and extend_correlation_symbols > Galileo_E5a_I_SECONDARY_CODE_LENGTH) + { + extend_correlation_symbols = Galileo_E5a_I_SECONDARY_CODE_LENGTH; + std::cout << TEXT_RED << "WARNING: Galileo E5a. extend_correlation_symbols must be lower than 21 when tracking the data component. Coherent integration has been set to 20 symbols (20 ms)" << TEXT_RESET << std::endl; + } + if ((extend_correlation_symbols > 1) and (pll_bw_narrow_hz > pll_bw_hz or dll_bw_narrow_hz > dll_bw_hz)) + { + std::cout << TEXT_RED << "WARNING: Galileo E5a. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << std::endl; + } + trk_param_fpga.extend_correlation_symbols = extend_correlation_symbols; + trk_param_fpga.track_pilot = track_pilot; + trk_param_fpga.very_early_late_space_chips = 0.0; + trk_param_fpga.very_early_late_space_narrow_chips = 0.0; + trk_param_fpga.system = 'E'; + char sig_[3] = "5X"; + std::memcpy(trk_param_fpga.signal, sig_, 3); + int cn0_samples = configuration->property(role + ".cn0_samples", 20); + if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; + trk_param_fpga.cn0_samples = cn0_samples; + int cn0_min = configuration->property(role + ".cn0_min", 25); + if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; + trk_param_fpga.cn0_min = cn0_min; + int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); + if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; + trk_param_fpga.max_lock_fail = max_lock_fail; + double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); + if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; + trk_param_fpga.carrier_lock_th = carrier_lock_th; + + // FPGA configuration parameters + std::string default_device_name = "/dev/uio"; + std::string device_name = configuration->property(role + ".devicename", default_device_name); + trk_param_fpga.device_name = device_name; + unsigned int device_base = configuration->property(role + ".device_base", 1); + trk_param_fpga.device_base = device_base; + //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 1); + trk_param_fpga.multicorr_type = 1; // 0 -> 3 correlators, 1 -> up to 5+1 correlators + + //################# PRE-COMPUTE ALL THE CODES ################# + unsigned int code_samples_per_chip = 1; + unsigned int code_length_chips = static_cast(Galileo_E5a_CODE_LENGTH_CHIPS); + + gr_complex *aux_code = static_cast(volk_gnsssdr_malloc(sizeof(gr_complex) * code_length_chips * code_samples_per_chip, volk_gnsssdr_get_alignment())); + + float *tracking_code; + float *data_code; + + if (trk_param_fpga.track_pilot) + { + data_code = static_cast(volk_gnsssdr_malloc(code_samples_per_chip * code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); + } + tracking_code = static_cast(volk_gnsssdr_malloc(code_samples_per_chip * code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); + + d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(code_length_chips) * code_samples_per_chip * Galileo_E5a_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); + + if (trk_param_fpga.track_pilot) + { + d_data_codes = static_cast(volk_gnsssdr_malloc((static_cast(code_length_chips)) * code_samples_per_chip * Galileo_E5a_NUMBER_OF_CODES * sizeof(int), volk_gnsssdr_get_alignment())); + } + + + for (unsigned int PRN = 1; PRN <= Galileo_E5a_NUMBER_OF_CODES; PRN++) + { + //galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast(trk_param_fpga.signal.c_str())); + galileo_e5_a_code_gen_complex_primary(aux_code, PRN, const_cast(sig_)); + if (trk_param_fpga.track_pilot) + { + //d_secondary_code_string = const_cast(&Galileo_E5a_Q_SECONDARY_CODE[PRN - 1]); + for (unsigned int i = 0; i < code_length_chips; i++) + { + tracking_code[i] = aux_code[i].imag(); + data_code[i] = aux_code[i].real(); + } + for (unsigned int s = 0; s < code_length_chips; s++) + { + d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(tracking_code[s]); + d_data_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(data_code[s]); + //printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); + } + } + else + { + for (unsigned int i = 0; i < code_length_chips; i++) + { + tracking_code[i] = aux_code[i].real(); + } + + for (unsigned int s = 0; s < code_length_chips; s++) + { + d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(tracking_code[s]); + //printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); + } + } + } + + volk_gnsssdr_free(aux_code); + volk_gnsssdr_free(tracking_code); + if (trk_param_fpga.track_pilot) + { + volk_gnsssdr_free(data_code); + } + trk_param_fpga.ca_codes = d_ca_codes; + trk_param_fpga.data_codes = d_data_codes; + trk_param_fpga.code_length_chips = code_length_chips; + trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip + //################# MAKE TRACKING GNURadio object ################### + tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); + // if (item_type.compare("gr_complex") == 0) + // { + // item_size_ = sizeof(gr_complex); + // tracking_ = dll_pll_veml_make_tracking(trk_param_fpga); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // LOG(WARNING) << item_type << " unknown tracking item type."; + // } + channel_ = 0; + + //DLOG(INFO) << "tracking(" << tracking_->unique_id() << ")"; + DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; +} + + +GalileoE5aDllPllTrackingFpga::~GalileoE5aDllPllTrackingFpga() +{ + delete[] d_ca_codes; + if (d_track_pilot) + { + delete[] d_data_codes; + } +} + + +void GalileoE5aDllPllTrackingFpga::start_tracking() +{ + //tracking_->start_tracking(); + tracking_fpga_sc->start_tracking(); +} + + +/* + * Set tracking channel unique ID + */ +void GalileoE5aDllPllTrackingFpga::set_channel(unsigned int channel) +{ + //printf("blabla channel = %d\n", channel); + channel_ = channel; + //tracking_->set_channel(channel); + tracking_fpga_sc->set_channel(channel); +} + + +void GalileoE5aDllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) +{ + //tracking_->set_gnss_synchro(p_gnss_synchro); + tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); +} + + +void GalileoE5aDllPllTrackingFpga::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + //nothing to connect, now the tracking uses gr_sync_decimator +} + + +void GalileoE5aDllPllTrackingFpga::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + //nothing to disconnect, now the tracking uses gr_sync_decimator +} + + +gr::basic_block_sptr GalileoE5aDllPllTrackingFpga::get_left_block() +{ + //return tracking_; + return tracking_fpga_sc; +} + + +gr::basic_block_sptr GalileoE5aDllPllTrackingFpga::get_right_block() +{ + //return tracking_; + return tracking_fpga_sc; +} diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h new file mode 100644 index 000000000..45325d458 --- /dev/null +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h @@ -0,0 +1,113 @@ +/*! + * \file galileo_e5a_dll_pll_tracking.h + * \brief Adapts a code DLL + carrier PLL + * tracking block to a TrackingInterface for Galileo E5a signals + * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for + * Galileo E5a data and pilot Signals + * \author Marc Sales, 2014. marcsales92(at)gmail.com + * \based on work from: + *
        + *
      • Javier Arribas, 2011. jarribas(at)cttc.es + *
      • Luis Esteve, 2012. luis(at)epsilon-formacion.com + *
      + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GALILEO_E5A_DLL_PLL_TRACKING_FPGA_H_ +#define GNSS_SDR_GALILEO_E5A_DLL_PLL_TRACKING_FPGA_H_ + +#include "tracking_interface.h" +#include "dll_pll_veml_tracking_fpga.h" +#include + +class ConfigurationInterface; + +/*! + * \brief This class implements a code DLL + carrier PLL tracking loop + */ +class GalileoE5aDllPllTrackingFpga : public TrackingInterface +{ +public: + GalileoE5aDllPllTrackingFpga(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams); + + virtual ~GalileoE5aDllPllTrackingFpga(); + + inline std::string role() override + { + return role_; + } + + //! Returns "Galileo_E5a_DLL_PLL_Tracking" + inline std::string implementation() override + { + return "Galileo_E5a_DLL_PLL_Tracking"; + } + + 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; + + /*! + * \brief Set tracking channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + +private: + dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; + size_t item_size_; + unsigned int channel_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + + + int* d_ca_codes; + int* d_data_codes; + bool d_track_pilot; +}; + +#endif /* GNSS_SDR_GALILEO_E5A_DLL_PLL_TRACKING_FPGA_H_ */ diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc index 16e212a9c..2287f53ba 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc @@ -46,6 +46,10 @@ using google::LogMessage; +void GlonassL1CaDllPllCAidTracking::stop_tracking() +{ +} + GlonassL1CaDllPllCAidTracking::GlonassL1CaDllPllCAidTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h index 3f75715dc..26e1f0db9 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h @@ -93,6 +93,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr tracking_cc; diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc index c616595d5..eb5f35176 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GlonassL1CaDllPllTracking::stop_tracking() +{ +} + GlonassL1CaDllPllTracking::GlonassL1CaDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.h b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.h index f752239d3..d5e1a4544 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.h @@ -91,6 +91,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: glonass_l1_ca_dll_pll_tracking_cc_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc index be2bb41d3..d4d0d0e98 100644 --- a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc @@ -44,6 +44,10 @@ using google::LogMessage; +void GlonassL2CaDllPllCAidTracking::stop_tracking() +{ +} + GlonassL2CaDllPllCAidTracking::GlonassL2CaDllPllCAidTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.h b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.h index bdd377b75..085cf73ac 100644 --- a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.h +++ b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.h @@ -91,6 +91,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: glonass_l2_ca_dll_pll_c_aid_tracking_cc_sptr tracking_cc; diff --git a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc index 6d9a9f1ea..a6a49aa1c 100644 --- a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc @@ -43,6 +43,10 @@ using google::LogMessage; +void GlonassL2CaDllPllTracking::stop_tracking() +{ +} + GlonassL2CaDllPllTracking::GlonassL2CaDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.h b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.h index 66346bd71..1c2b715ed 100644 --- a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.h @@ -90,6 +90,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: glonass_l2_ca_dll_pll_tracking_cc_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.cc index 9ce706ef3..c821d311d 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GpsL1CaDllPllCAidTracking::stop_tracking() +{ +} + GpsL1CaDllPllCAidTracking::GpsL1CaDllPllCAidTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.h index 357a5a0c1..6b4dec2e5 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_c_aid_tracking.h @@ -92,6 +92,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: gps_l1_ca_dll_pll_c_aid_tracking_cc_sptr tracking_cc; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc index ffa6e1000..b0fff7263 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc @@ -45,6 +45,11 @@ using google::LogMessage; +void GpsL1CaDllPllTracking::stop_tracking() +{ + tracking_->stop_tracking(); +} + GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -57,8 +62,23 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); trk_param.fs_in = fs_in; + trk_param.high_dyn = configuration->property(role + ".high_dyn", false); + if (configuration->property(role + ".smoother_length", 10) < 1) + { + trk_param.smoother_length = 1; + std::cout << TEXT_RED << "WARNING: GPS L1 C/A. smoother_length must be bigger than 0. It has been set to 1" << TEXT_RESET << std::endl; + } + else + { + trk_param.smoother_length = configuration->property(role + ".smoother_length", 10); + } bool dump = configuration->property(role + ".dump", false); trk_param.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param.dump_mat = dump_mat; float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param.pll_bw_hz = pll_bw_hz; @@ -73,9 +93,6 @@ GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( trk_param.early_late_space_chips = early_late_space_chips; float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.5); trk_param.early_late_space_narrow_chips = early_late_space_narrow_chips; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param.dump_filename = dump_filename; int vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); trk_param.vector_length = vector_length; int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h index b85147b58..cbd4797f2 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.h @@ -91,6 +91,11 @@ public: void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + private: dll_pll_veml_tracking_sptr tracking_; size_t item_size_; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc index f9d3aa587..37f946e9f 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc @@ -1,5 +1,5 @@ /*! - * \file gps_l1_ca_dll_pll_tracking.cc + * \file gps_l1_ca_dll_pll_tracking_fpga.cc * \brief Implementation of an adapter of a DLL+PLL tracking loop block * for GPS L1 C/A to a TrackingInterface that uses the FPGA * \author Marc Majoral, 2018, mmajoral(at)cttc.es @@ -13,7 +13,7 @@ * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -31,37 +31,47 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ +#include +#include "gps_sdr_signal_processing.h" #include "gps_l1_ca_dll_pll_tracking_fpga.h" #include "configuration_interface.h" -#include "display.h" -#include "gnss_sdr_flags.h" #include "GPS_L1_CA.h" -#include "gps_sdr_signal_processing.h" -#include - +#include "gnss_sdr_flags.h" +#include "display.h" #define NUM_PRNs 32 using google::LogMessage; +void GpsL1CaDllPllTrackingFpga::stop_tracking() +{ +} + GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) { - dllpllconf_fpga_t trk_param_fpga; + Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); DLOG(INFO) << "role " << role; //################# CONFIGURATION PARAMETERS ######################## + //std::string default_item_type = "gr_complex"; + //std::string item_type = configuration->property(role + ".item_type", default_item_type); int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); trk_param_fpga.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param_fpga.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param_fpga.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param_fpga.dump_mat = dump_mat; float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param_fpga.pll_bw_hz = pll_bw_hz; @@ -76,9 +86,6 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga( trk_param_fpga.early_late_space_chips = early_late_space_chips; float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.5); trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param_fpga.dump_filename = dump_filename; int vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); trk_param_fpga.vector_length = vector_length; int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); @@ -127,6 +134,8 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga( trk_param_fpga.device_name = device_name; unsigned int device_base = configuration->property(role + ".device_base", 1); trk_param_fpga.device_base = device_base; + //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0); + trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators //################# PRE-COMPUTE ALL THE CODES ################# d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS * NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); @@ -135,35 +144,25 @@ GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga( gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0); } trk_param_fpga.ca_codes = d_ca_codes; - trk_param_fpga.code_length = GPS_L1_CA_CODE_LENGTH_CHIPS; + trk_param_fpga.code_length_chips = GPS_L1_CA_CODE_LENGTH_CHIPS; + trk_param_fpga.code_samples_per_chip = 1; // 1 sample per chip //################# MAKE TRACKING GNURadio object ################### tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); channel_ = 0; DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one output stream"; - } } - GpsL1CaDllPllTrackingFpga::~GpsL1CaDllPllTrackingFpga() { delete[] d_ca_codes; } - void GpsL1CaDllPllTrackingFpga::start_tracking() { tracking_fpga_sc->start_tracking(); } - /* * Set tracking channel unique ID */ @@ -173,13 +172,11 @@ void GpsL1CaDllPllTrackingFpga::set_channel(unsigned int channel) tracking_fpga_sc->set_channel(channel); } - void GpsL1CaDllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) { tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); } - void GpsL1CaDllPllTrackingFpga::connect(gr::top_block_sptr top_block) { if (top_block) diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h index de77dff2e..80b998246 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h @@ -1,5 +1,5 @@ /*! - * \file gps_l1_ca_dll_pll_tracking.h + * \file gps_l1_ca_dll_pll_tracking_fpga.h * \brief Interface of an adapter of a DLL+PLL tracking loop block * for GPS L1 C/A to a TrackingInterface that uses the FPGA * \author Marc Majoral, 2018. mmajoral(at)cttc.es @@ -13,7 +13,7 @@ * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -31,7 +31,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ @@ -39,9 +39,10 @@ #ifndef GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_H_ #define GNSS_SDR_GPS_L1_CA_DLL_PLL_TRACKING_FPGA_H_ +#include #include "tracking_interface.h" #include "dll_pll_veml_tracking_fpga.h" -#include + class ConfigurationInterface; @@ -92,6 +93,11 @@ public: void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + private: dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; size_t item_size_; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc index 0cccd8e26..c82f228b5 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc @@ -44,6 +44,10 @@ using google::LogMessage; +void GpsL1CaDllPllTrackingGPU::stop_tracking() +{ +} + GpsL1CaDllPllTrackingGPU::GpsL1CaDllPllTrackingGPU( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.h index 9c77f4743..794152bb8 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.h @@ -91,6 +91,11 @@ public: void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + private: gps_l1_ca_dll_pll_tracking_gpu_cc_sptr tracking_; size_t item_size_; diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.cc new file mode 100644 index 000000000..2c33723e6 --- /dev/null +++ b/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.cc @@ -0,0 +1,178 @@ +/*! + * \file gps_l1_ca_kf_tracking.cc + * \brief Implementation of an adapter of a DLL + Kalman carrier + * tracking loop block for GPS L1 C/A signals + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * \author Jordi Vila-Valls 2018. jvila(at)cttc.es + * \author Carles Fernandez-Prades 2018. cfernandez(at)cttc.es + * + * Reference: + * J. Vila-Valls, P. Closas, M. Navarro and C. Fernández-Prades, + * "Are PLLs Dead? A Tutorial on Kalman Filter-based Techniques for Digital + * Carrier Synchronization", IEEE Aerospace and Electronic Systems Magazine, + * Vol. 32, No. 7, pp. 28–45, July 2017. DOI: 10.1109/MAES.2017.150260 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "gps_l1_ca_kf_tracking.h" +#include "gnss_sdr_flags.h" +#include "GPS_L1_CA.h" +#include "configuration_interface.h" +#include + + +using google::LogMessage; + +void GpsL1CaKfTracking::stop_tracking() +{ +} + +GpsL1CaKfTracking::GpsL1CaKfTracking( + ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + DLOG(INFO) << "role " << role; + //################# CONFIGURATION PARAMETERS ######################## + int order; + int fs_in; + int vector_length; + int f_if; + bool dump; + std::string dump_filename; + std::string item_type; + std::string default_item_type = "gr_complex"; + float dll_bw_hz; + float early_late_space_chips; + bool bce_run; + unsigned int bce_ptrans; + unsigned int bce_strans; + int bce_nu; + int bce_kappa; + + item_type = configuration->property(role + ".item_type", default_item_type); + order = configuration->property(role + ".order", 2); + int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); + fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + f_if = configuration->property(role + ".if", 0); + dump = configuration->property(role + ".dump", false); + dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); + if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast(FLAGS_dll_bw_hz); + early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); + std::string default_dump_filename = "./track_ch"; + dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + vector_length = std::round(fs_in / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); + + bce_run = configuration->property(role + ".bce_run", false); + bce_ptrans = configuration->property(role + ".p_transient", 0); + bce_strans = configuration->property(role + ".s_transient", 0); + bce_nu = configuration->property(role + ".bce_nu", 0); + bce_kappa = configuration->property(role + ".bce_kappa", 0); + + //################# MAKE TRACKING GNURadio object ################### + if (item_type.compare("gr_complex") == 0) + { + item_size_ = sizeof(gr_complex); + tracking_ = gps_l1_ca_kf_make_tracking_cc( + order, + f_if, + fs_in, + vector_length, + dump, + dump_filename, + dll_bw_hz, + early_late_space_chips, + bce_run, + bce_ptrans, + bce_strans, + bce_nu, + bce_kappa); + } + else + { + item_size_ = sizeof(gr_complex); + LOG(WARNING) << item_type << " unknown tracking item type."; + } + channel_ = 0; + DLOG(INFO) << "tracking(" << tracking_->unique_id() << ")"; +} + + +GpsL1CaKfTracking::~GpsL1CaKfTracking() +{ +} + + +void GpsL1CaKfTracking::start_tracking() +{ + tracking_->start_tracking(); +} + + +/* + * Set tracking channel unique ID + */ +void GpsL1CaKfTracking::set_channel(unsigned int channel) +{ + channel_ = channel; + tracking_->set_channel(channel); +} + + +void GpsL1CaKfTracking::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +{ + tracking_->set_gnss_synchro(p_gnss_synchro); +} + + +void GpsL1CaKfTracking::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + //nothing to connect, now the tracking uses gr_sync_decimator +} + + +void GpsL1CaKfTracking::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + //nothing to disconnect, now the tracking uses gr_sync_decimator +} + + +gr::basic_block_sptr GpsL1CaKfTracking::get_left_block() +{ + return tracking_; +} + + +gr::basic_block_sptr GpsL1CaKfTracking::get_right_block() +{ + return tracking_; +} diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.h b/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.h new file mode 100644 index 000000000..d8af76ce8 --- /dev/null +++ b/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.h @@ -0,0 +1,110 @@ +/*! + * \file gps_l1_ca_kf_tracking.h + * \brief Interface of an adapter of a DLL + Kalman carrier + * tracking loop block for GPS L1 C/A signals + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * \author Jordi Vila-Valls 2018. jvila(at)cttc.es + * \author Carles Fernandez-Prades 2018. cfernandez(at)cttc.es + * + * Reference: + * J. Vila-Valls, P. Closas, M. Navarro and C. Fernandez-Prades, + * "Are PLLs Dead? A Tutorial on Kalman Filter-based Techniques for Digital + * Carrier Synchronization", IEEE Aerospace and Electronic Systems Magazine, + * Vol. 32, No. 7, pp. 28–45, July 2017. DOI: 10.1109/MAES.2017.150260 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GPS_L1_CA_KF_TRACKING_H_ +#define GNSS_SDR_GPS_L1_CA_KF_TRACKING_H_ + +#include "gps_l1_ca_kf_tracking_cc.h" +#include "tracking_interface.h" +#include + +class ConfigurationInterface; + +/*! + * \brief This class implements a code DLL + carrier PLL tracking loop + */ +class GpsL1CaKfTracking : public TrackingInterface +{ +public: + GpsL1CaKfTracking(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams); + + virtual ~GpsL1CaKfTracking(); + + inline std::string role() override + { + return role_; + } + + //! Returns "GPS_L1_CA_KF_Tracking" + inline std::string implementation() override + { + return "GPS_L1_CA_KF_Tracking"; + } + + 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; + + /*! + * \brief Set tracking channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + void start_tracking() override; + + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + +private: + gps_l1_ca_kf_tracking_cc_sptr tracking_; + size_t item_size_; + unsigned int channel_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; +}; + +#endif // GNSS_SDR_GPS_L1_CA_KF_TRACKING_H_ diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc index d0303867c..9e3cf4bfa 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc @@ -43,6 +43,10 @@ using google::LogMessage; +void GpsL1CaTcpConnectorTracking::stop_tracking() +{ +} + GpsL1CaTcpConnectorTracking::GpsL1CaTcpConnectorTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.h b/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.h index 75a986cfc..f2fb94b3a 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.h @@ -91,6 +91,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: gps_l1_ca_tcp_connector_tracking_cc_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc index 499427dfa..f4bb44321 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GpsL2MDllPllTracking::stop_tracking() +{ +} + GpsL2MDllPllTracking::GpsL2MDllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -59,6 +63,11 @@ GpsL2MDllPllTracking::GpsL2MDllPllTracking( trk_param.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param.dump_mat = dump_mat; float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 2.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param.pll_bw_hz = pll_bw_hz; @@ -68,9 +77,6 @@ GpsL2MDllPllTracking::GpsL2MDllPllTracking( float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); trk_param.early_late_space_chips = early_late_space_chips; trk_param.early_late_space_narrow_chips = 0.0; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param.dump_filename = dump_filename; int vector_length = std::round(static_cast(fs_in) / (static_cast(GPS_L2_M_CODE_RATE_HZ) / static_cast(GPS_L2_M_CODE_LENGTH_CHIPS))); trk_param.vector_length = vector_length; int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.h b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.h index 68305ad6a..23835c405 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.h @@ -90,6 +90,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: dll_pll_veml_tracking_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.cc new file mode 100644 index 000000000..f10d876dc --- /dev/null +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.cc @@ -0,0 +1,229 @@ +/*! + * \file gps_l2_m_dll_pll_tracking.cc + * \brief Implementation of an adapter of a DLL+PLL tracking loop block + * for GPS L1 C/A to a TrackingInterface + * \author Javier Arribas, 2015. jarribas(at)cttc.es + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkhauser, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "gps_l2_m_dll_pll_tracking_fpga.h" +#include "configuration_interface.h" +#include "GPS_L2C.h" +#include "gps_l2c_signal.h" +#include "gnss_sdr_flags.h" +#include "display.h" +#include + +#define NUM_PRNs 32 + +using google::LogMessage; + +void GpsL2MDllPllTrackingFpga::stop_tracking() +{ +} + +GpsL2MDllPllTrackingFpga::GpsL2MDllPllTrackingFpga( + ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + //dllpllconf_t trk_param; + Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); + DLOG(INFO) << "role " << role; + //################# CONFIGURATION PARAMETERS ######################## + //std::string default_item_type = "gr_complex"; + //std::string item_type = configuration->property(role + ".item_type", default_item_type); + int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); + int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + trk_param_fpga.fs_in = fs_in; + bool dump = configuration->property(role + ".dump", false); + trk_param_fpga.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param_fpga.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param_fpga.dump_mat = dump_mat; + float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 2.0); + if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); + trk_param_fpga.pll_bw_hz = pll_bw_hz; + float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 0.75); + if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast(FLAGS_dll_bw_hz); + trk_param_fpga.dll_bw_hz = dll_bw_hz; + float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); + trk_param_fpga.early_late_space_chips = early_late_space_chips; + trk_param_fpga.early_late_space_narrow_chips = 0.0; + int vector_length = std::round(static_cast(fs_in) / (static_cast(GPS_L2_M_CODE_RATE_HZ) / static_cast(GPS_L2_M_CODE_LENGTH_CHIPS))); + trk_param_fpga.vector_length = vector_length; + int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); + if (symbols_extended_correlator != 1) + { + std::cout << TEXT_RED << "WARNING: Extended coherent integration is not allowed in GPS L2. Coherent integration has been set to 20 ms (1 symbol)" << TEXT_RESET << std::endl; + } + trk_param_fpga.extend_correlation_symbols = 1; + bool track_pilot = configuration->property(role + ".track_pilot", false); + if (track_pilot) + { + std::cout << TEXT_RED << "WARNING: GPS L2 does not have pilot signal. Data tracking has been enabled" << TEXT_RESET << std::endl; + } + trk_param_fpga.track_pilot = false; + trk_param_fpga.very_early_late_space_chips = 0.0; + trk_param_fpga.very_early_late_space_narrow_chips = 0.0; + trk_param_fpga.pll_bw_narrow_hz = 0.0; + trk_param_fpga.dll_bw_narrow_hz = 0.0; + trk_param_fpga.system = 'G'; + char sig_[3] = "2S"; + std::memcpy(trk_param_fpga.signal, sig_, 3); + int cn0_samples = configuration->property(role + ".cn0_samples", 20); + if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; + trk_param_fpga.cn0_samples = cn0_samples; + int cn0_min = configuration->property(role + ".cn0_min", 25); + if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; + trk_param_fpga.cn0_min = cn0_min; + int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); + if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; + trk_param_fpga.max_lock_fail = max_lock_fail; + double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); + if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; + trk_param_fpga.carrier_lock_th = carrier_lock_th; + + // FPGA configuration parameters + std::string default_device_name = "/dev/uio"; + std::string device_name = configuration->property(role + ".devicename", default_device_name); + trk_param_fpga.device_name = device_name; + unsigned int device_base = configuration->property(role + ".device_base", 1); + trk_param_fpga.device_base = device_base; + //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0); + trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators + + //d_tracking_code = static_cast(volk_gnsssdr_malloc(2 * static_cast(GPS_L2_M_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); + d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L2_M_CODE_LENGTH_CHIPS) * NUM_PRNs * sizeof(int), volk_gnsssdr_get_alignment())); + float* ca_codes_f = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L2_M_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); + + //################# PRE-COMPUTE ALL THE CODES ################# + d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L2_M_CODE_LENGTH_CHIPS * NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); + for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) + { + //gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0); + gps_l2c_m_code_gen_float(ca_codes_f, PRN); + for (unsigned int s = 0; s < 2 * static_cast(GPS_L2_M_CODE_LENGTH_CHIPS); s++) + { + d_ca_codes[static_cast(GPS_L2_M_CODE_LENGTH_CHIPS) * (PRN - 1) + s] = static_cast(ca_codes_f[s]); + } + } + + delete[] ca_codes_f; + + trk_param_fpga.ca_codes = d_ca_codes; + trk_param_fpga.code_length_chips = GPS_L2_M_CODE_LENGTH_CHIPS; + trk_param_fpga.code_samples_per_chip = 1; // 1 sample per chip + + //################# MAKE TRACKING GNURadio object ################### + + // //################# MAKE TRACKING GNURadio object ################### + // if (item_type.compare("gr_complex") == 0) + // { + // item_size_ = sizeof(gr_complex); + // tracking_ = dll_pll_veml_make_tracking(trk_param); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // LOG(WARNING) << item_type << " unknown tracking item type."; + // } + + //################# MAKE TRACKING GNURadio object ################### + tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); + + channel_ = 0; + DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; +} + + +GpsL2MDllPllTrackingFpga::~GpsL2MDllPllTrackingFpga() +{ +} + + +void GpsL2MDllPllTrackingFpga::start_tracking() +{ + //tracking_->start_tracking(); + tracking_fpga_sc->start_tracking(); +} + + +/* + * Set tracking channel unique ID + */ +void GpsL2MDllPllTrackingFpga::set_channel(unsigned int channel) +{ + channel_ = channel; + //tracking_->set_channel(channel); + tracking_fpga_sc->set_channel(channel); +} + + +void GpsL2MDllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) +{ + //tracking_->set_gnss_synchro(p_gnss_synchro); + tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); +} + + +void GpsL2MDllPllTrackingFpga::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + //nothing to connect, now the tracking uses gr_sync_decimator +} + + +void GpsL2MDllPllTrackingFpga::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + //nothing to disconnect, now the tracking uses gr_sync_decimator +} + + +gr::basic_block_sptr GpsL2MDllPllTrackingFpga::get_left_block() +{ + //return tracking_; + return tracking_fpga_sc; +} + + +gr::basic_block_sptr GpsL2MDllPllTrackingFpga::get_right_block() +{ + //return tracking_; + return tracking_fpga_sc; +} diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h new file mode 100644 index 000000000..2cde19cd7 --- /dev/null +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h @@ -0,0 +1,110 @@ +/*! + * \file gps_l2_m_dll_pll_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for GPS L1 C/A to a TrackingInterface + * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com + * Javier Arribas, 2011. jarribas(at)cttc.es + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkhauser, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_gps_l2_m_dll_pll_tracking_FPGA_H_ +#define GNSS_SDR_gps_l2_m_dll_pll_tracking_FPGA_H_ + +#include "tracking_interface.h" +//#include "dll_pll_veml_tracking.h" +#include "dll_pll_veml_tracking_fpga.h" +#include + +class ConfigurationInterface; + +/*! + * \brief This class implements a code DLL + carrier PLL tracking loop + */ +class GpsL2MDllPllTrackingFpga : public TrackingInterface +{ +public: + GpsL2MDllPllTrackingFpga(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams); + + virtual ~GpsL2MDllPllTrackingFpga(); + + inline std::string role() override + { + return role_; + } + + //! Returns "GPS_L2_M_DLL_PLL_Tracking" + inline std::string implementation() override + { + return "GPS_L2_M_DLL_PLL_Tracking_Fpga"; + } + + 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; + + /*! + * \brief Set tracking channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + +private: + //dll_pll_veml_tracking_sptr tracking_; + dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; + size_t item_size_; + unsigned int channel_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + int* d_ca_codes; +}; + +#endif // GNSS_SDR_gps_l2_m_dll_pll_tracking_FPGA_H_ diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc index 8fbd56531..9954777ec 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc @@ -45,6 +45,10 @@ using google::LogMessage; +void GpsL5DllPllTracking::stop_tracking() +{ +} + GpsL5DllPllTracking::GpsL5DllPllTracking( ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) @@ -59,6 +63,21 @@ GpsL5DllPllTracking::GpsL5DllPllTracking( trk_param.fs_in = fs_in; bool dump = configuration->property(role + ".dump", false); trk_param.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param.dump_mat = dump_mat; + trk_param.high_dyn = configuration->property(role + ".high_dyn", false); + if (configuration->property(role + ".smoother_length", 10) < 1) + { + trk_param.smoother_length = 1; + std::cout << TEXT_RED << "WARNING: GPS L5. smoother_length must be bigger than 0. It has been set to 1" << TEXT_RESET << std::endl; + } + else + { + trk_param.smoother_length = configuration->property(role + ".smoother_length", 10); + } float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); trk_param.pll_bw_hz = pll_bw_hz; @@ -71,9 +90,6 @@ GpsL5DllPllTracking::GpsL5DllPllTracking( trk_param.dll_bw_narrow_hz = dll_bw_narrow_hz; float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); trk_param.early_late_space_chips = early_late_space_chips; - std::string default_dump_filename = "./track_ch"; - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - trk_param.dump_filename = dump_filename; int vector_length = std::round(static_cast(fs_in) / (static_cast(GPS_L5i_CODE_RATE_HZ) / static_cast(GPS_L5i_CODE_LENGTH_CHIPS))); trk_param.vector_length = vector_length; int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); @@ -110,7 +126,7 @@ GpsL5DllPllTracking::GpsL5DllPllTracking( int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; trk_param.max_lock_fail = max_lock_fail; - double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); + double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.75); if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; trk_param.carrier_lock_th = carrier_lock_th; diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.h b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.h index 9cfbd58fa..59a8983fc 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.h +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.h @@ -89,6 +89,10 @@ public: void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; private: dll_pll_veml_tracking_sptr tracking_; diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc new file mode 100644 index 000000000..bbc5c17bb --- /dev/null +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc @@ -0,0 +1,276 @@ +/*! + * \file gps_l5_dll_pll_tracking.cc + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for GPS L5 to a TrackingInterface + * \author Javier Arribas, 2017. jarribas(at)cttc.es + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkhauser, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "gps_l5_dll_pll_tracking_fpga.h" +#include "configuration_interface.h" +#include "GPS_L5.h" +#include "gps_l5_signal.h" +#include "gnss_sdr_flags.h" +#include "display.h" +#include + +#define NUM_PRNs 32 + +using google::LogMessage; + +void GpsL5DllPllTrackingFpga::stop_tracking() +{ +} + +GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( + ConfigurationInterface *configuration, std::string role, + unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) +{ + //printf("L5 TRK CLASS CREATED\n"); + //dllpllconf_t trk_param; + Dll_Pll_Conf_Fpga trk_param_fpga = Dll_Pll_Conf_Fpga(); + DLOG(INFO) << "role " << role; + //################# CONFIGURATION PARAMETERS ######################## + //std::string default_item_type = "gr_complex"; + //std::string item_type = configuration->property(role + ".item_type", default_item_type); + int fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); + int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + trk_param_fpga.fs_in = fs_in; + bool dump = configuration->property(role + ".dump", false); + trk_param_fpga.dump = dump; + std::string default_dump_filename = "./track_ch"; + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + trk_param_fpga.dump_filename = dump_filename; + bool dump_mat = configuration->property(role + ".dump_mat", true); + trk_param_fpga.dump_mat = dump_mat; + float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); + if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); + trk_param_fpga.pll_bw_hz = pll_bw_hz; + float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); + if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast(FLAGS_dll_bw_hz); + trk_param_fpga.dll_bw_hz = dll_bw_hz; + float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 2.0); + trk_param_fpga.pll_bw_narrow_hz = pll_bw_narrow_hz; + float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 0.25); + trk_param_fpga.dll_bw_narrow_hz = dll_bw_narrow_hz; + float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); + trk_param_fpga.early_late_space_chips = early_late_space_chips; + int vector_length = std::round(static_cast(fs_in) / (static_cast(GPS_L5i_CODE_RATE_HZ) / static_cast(GPS_L5i_CODE_LENGTH_CHIPS))); + trk_param_fpga.vector_length = vector_length; + int extend_correlation_symbols = configuration->property(role + ".extend_correlation_symbols", 1); + float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.15); + trk_param_fpga.early_late_space_narrow_chips = early_late_space_narrow_chips; + bool track_pilot = configuration->property(role + ".track_pilot", false); + if (extend_correlation_symbols < 1) + { + extend_correlation_symbols = 1; + std::cout << TEXT_RED << "WARNING: GPS L5. extend_correlation_symbols must be bigger than 0. Coherent integration has been set to 1 symbol (1 ms)" << TEXT_RESET << std::endl; + } + else if (!track_pilot and extend_correlation_symbols > GPS_L5i_NH_CODE_LENGTH) + { + extend_correlation_symbols = GPS_L5i_NH_CODE_LENGTH; + std::cout << TEXT_RED << "WARNING: GPS L5. extend_correlation_symbols must be lower than 11 when tracking the data component. Coherent integration has been set to 10 symbols (10 ms)" << TEXT_RESET << std::endl; + } + if ((extend_correlation_symbols > 1) and (pll_bw_narrow_hz > pll_bw_hz or dll_bw_narrow_hz > dll_bw_hz)) + { + std::cout << TEXT_RED << "WARNING: GPS L5. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << std::endl; + } + trk_param_fpga.extend_correlation_symbols = extend_correlation_symbols; + trk_param_fpga.track_pilot = track_pilot; + d_track_pilot = track_pilot; + trk_param_fpga.very_early_late_space_chips = 0.0; + trk_param_fpga.very_early_late_space_narrow_chips = 0.0; + trk_param_fpga.system = 'G'; + char sig_[3] = "L5"; + std::memcpy(trk_param_fpga.signal, sig_, 3); + int cn0_samples = configuration->property(role + ".cn0_samples", 20); + if (FLAGS_cn0_samples != 20) cn0_samples = FLAGS_cn0_samples; + trk_param_fpga.cn0_samples = cn0_samples; + int cn0_min = configuration->property(role + ".cn0_min", 25); + if (FLAGS_cn0_min != 25) cn0_min = FLAGS_cn0_min; + trk_param_fpga.cn0_min = cn0_min; + int max_lock_fail = configuration->property(role + ".max_lock_fail", 50); + if (FLAGS_max_lock_fail != 50) max_lock_fail = FLAGS_max_lock_fail; + trk_param_fpga.max_lock_fail = max_lock_fail; + double carrier_lock_th = configuration->property(role + ".carrier_lock_th", 0.85); + if (FLAGS_carrier_lock_th != 0.85) carrier_lock_th = FLAGS_carrier_lock_th; + trk_param_fpga.carrier_lock_th = carrier_lock_th; + + // FPGA configuration parameters + std::string default_device_name = "/dev/uio"; + std::string device_name = configuration->property(role + ".devicename", default_device_name); + trk_param_fpga.device_name = device_name; + unsigned int device_base = configuration->property(role + ".device_base", 1); + trk_param_fpga.device_base = device_base; + //unsigned int multicorr_type = configuration->property(role + ".multicorr_type", 0); + trk_param_fpga.multicorr_type = 0; //multicorr_type : 0 -> 3 correlators, 1 -> 5 correlators + + //################# PRE-COMPUTE ALL THE CODES ################# + unsigned int code_samples_per_chip = 1; + unsigned int code_length_chips = static_cast(GPS_L5i_CODE_LENGTH_CHIPS); + //printf("TRK code_length_chips = %d\n", code_length_chips); + + float *tracking_code; + float *data_code; + + tracking_code = static_cast(volk_gnsssdr_malloc(code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); + + if (trk_param_fpga.track_pilot) + { + data_code = static_cast(volk_gnsssdr_malloc(code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); + } + + d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(code_length_chips * NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); + + if (trk_param_fpga.track_pilot) + { + d_data_codes = static_cast(volk_gnsssdr_malloc((static_cast(code_length_chips)) * NUM_PRNs * sizeof(int), volk_gnsssdr_get_alignment())); + } + + //printf("start \n"); + for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) + { + if (track_pilot) + { + gps_l5q_code_gen_float(tracking_code, PRN); + gps_l5i_code_gen_float(data_code, PRN); + + + for (unsigned int s = 0; s < code_length_chips; s++) + { + d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(tracking_code[s]); + d_data_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(data_code[s]); + //printf("%f %d | ", data_codes_f[s], d_data_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); + } + } + + else + { + gps_l5i_code_gen_float(tracking_code, PRN); + for (unsigned int s = 0; s < code_length_chips; s++) + { + d_ca_codes[static_cast(code_length_chips) * (PRN - 1) + s] = static_cast(data_code[s]); + //printf("%f %d | ", ca_codes_f[s], d_ca_codes[static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS)* 2 * (PRN - 1) + s]); + } + } + } + //printf("end \n"); + + + delete[] tracking_code; + if (trk_param_fpga.track_pilot) + { + delete[] data_code; + } + trk_param_fpga.ca_codes = d_ca_codes; + trk_param_fpga.data_codes = d_data_codes; + trk_param_fpga.code_length_chips = code_length_chips; + trk_param_fpga.code_samples_per_chip = code_samples_per_chip; // 2 sample per chip + //################# MAKE TRACKING GNURadio object ################### + // if (item_type.compare("gr_complex") == 0) + // { + // item_size_ = sizeof(gr_complex); + // tracking_ = dll_pll_veml_make_tracking(trk_param_fpga); + // } + // else + // { + // item_size_ = sizeof(gr_complex); + // LOG(WARNING) << item_type << " unknown tracking item type."; + // } + //printf("call \n"); + tracking_fpga_sc = dll_pll_veml_make_tracking_fpga(trk_param_fpga); + //printf("end2 \n"); + channel_ = 0; + DLOG(INFO) << "tracking(" << tracking_fpga_sc->unique_id() << ")"; +} + + +GpsL5DllPllTrackingFpga::~GpsL5DllPllTrackingFpga() +{ + delete[] d_ca_codes; + if (d_track_pilot) + { + delete[] d_data_codes; + } +} + + +void GpsL5DllPllTrackingFpga::start_tracking() +{ + tracking_fpga_sc->start_tracking(); +} + + +/* + * Set tracking channel unique ID + */ +void GpsL5DllPllTrackingFpga::set_channel(unsigned int channel) +{ + channel_ = channel; + tracking_fpga_sc->set_channel(channel); +} + + +void GpsL5DllPllTrackingFpga::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) +{ + tracking_fpga_sc->set_gnss_synchro(p_gnss_synchro); +} + + +void GpsL5DllPllTrackingFpga::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + //nothing to connect, now the tracking uses gr_sync_decimator +} + + +void GpsL5DllPllTrackingFpga::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + //nothing to disconnect, now the tracking uses gr_sync_decimator +} + + +gr::basic_block_sptr GpsL5DllPllTrackingFpga::get_left_block() +{ + return tracking_fpga_sc; +} + + +gr::basic_block_sptr GpsL5DllPllTrackingFpga::get_right_block() +{ + return tracking_fpga_sc; +} diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h new file mode 100644 index 000000000..64043fb70 --- /dev/null +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h @@ -0,0 +1,110 @@ +/*! + * \file gps_l5_dll_pll_tracking.h + * \brief Interface of an adapter of a DLL+PLL tracking loop block + * for GPS L5 to a TrackingInterface + * \author Javier Arribas, 2017. jarribas(at)cttc.es + * + * Code DLL + carrier PLL according to the algorithms described in: + * K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, + * A Software-Defined GPS and Galileo Receiver. A Single-Frequency + * Approach, Birkhauser, 2007 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GPS_L5_DLL_PLL_TRACKING_FPGA_H_ +#define GNSS_SDR_GPS_L5_DLL_PLL_TRACKING_FPGA_H_ + +#include "tracking_interface.h" +#include "dll_pll_veml_tracking_fpga.h" +#include + +class ConfigurationInterface; + +/*! + * \brief This class implements a code DLL + carrier PLL tracking loop + */ +class GpsL5DllPllTrackingFpga : public TrackingInterface +{ +public: + GpsL5DllPllTrackingFpga(ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams); + + virtual ~GpsL5DllPllTrackingFpga(); + + inline std::string role() override + { + return role_; + } + + //! Returns "GPS_L5_DLL_PLL_Tracking" + inline std::string implementation() override + { + return "GPS_L5_DLL_PLL_Tracking"; + } + + 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; + + /*! + * \brief Set tracking channel unique ID + */ + void set_channel(unsigned int channel) override; + + /*! + * \brief Set acquisition/tracking common Gnss_Synchro object pointer + * to efficiently exchange synchronization data between acquisition and tracking blocks + */ + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; + + void start_tracking() override; + /*! + * \brief Stop running tracking + */ + void stop_tracking() override; + +private: + //dll_pll_veml_tracking_sptr tracking_; + dll_pll_veml_tracking_fpga_sptr tracking_fpga_sc; + size_t item_size_; + unsigned int channel_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + bool d_track_pilot; + int* d_ca_codes; + int* d_data_codes; +}; + +#endif // GNSS_SDR_GPS_L5_DLL_PLL_TRACKING_FPGA_H_ diff --git a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt index a0bd80004..2dd5b494f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt @@ -17,65 +17,120 @@ # if(ENABLE_CUDA) - set(OPT_TRACKING_BLOCKS ${OPT_TRACKING_BLOCKS} gps_l1_ca_dll_pll_tracking_gpu_cc.cc) - set(OPT_TRACKING_INCLUDES ${OPT_TRACKING_INCLUDES} ${CUDA_INCLUDE_DIRS}) - set(OPT_TRACKING_LIBRARIES ${OPT_TRACKING_LIBRARIES} ${CUDA_LIBRARIES}) -endif(ENABLE_CUDA) + set(OPT_TRACKING_BLOCKS_SOURCES + ${OPT_TRACKING_BLOCKS_SOURCES} + gps_l1_ca_dll_pll_tracking_gpu_cc.cc + ) + set(OPT_TRACKING_BLOCKS_HEADERS + ${OPT_TRACKING_BLOCKS_HEADERS} + gps_l1_ca_dll_pll_tracking_gpu_cc.h + ) + set(OPT_TRACKING_INCLUDES + ${OPT_TRACKING_INCLUDES} + ${CUDA_INCLUDE_DIRS} + ) + set(OPT_TRACKING_LIBRARIES + ${OPT_TRACKING_LIBRARIES} + ${CUDA_LIBRARIES} + ) +endif() if(ENABLE_FPGA) - set(OPT_TRACKING_BLOCKS ${OPT_TRACKING_BLOCKS} dll_pll_veml_tracking_fpga.cc) -endif(ENABLE_FPGA) + set(OPT_TRACKING_BLOCKS_SOURCES + ${OPT_TRACKING_BLOCKS_SOURCES} + dll_pll_veml_tracking_fpga.cc + ) + set(OPT_TRACKING_BLOCKS_HEADERS + ${OPT_TRACKING_BLOCKS_HEADERS} + dll_pll_veml_tracking_fpga.h + ) +endif() set(TRACKING_GR_BLOCKS_SOURCES - galileo_e1_tcp_connector_tracking_cc.cc - gps_l1_ca_tcp_connector_tracking_cc.cc - gps_l1_ca_dll_pll_c_aid_tracking_cc.cc - gps_l1_ca_dll_pll_c_aid_tracking_sc.cc - glonass_l1_ca_dll_pll_tracking_cc.cc - glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc - glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc - glonass_l2_ca_dll_pll_tracking_cc.cc - glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc - glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc - dll_pll_veml_tracking.cc - ${OPT_TRACKING_BLOCKS} + galileo_e1_tcp_connector_tracking_cc.cc + gps_l1_ca_tcp_connector_tracking_cc.cc + gps_l1_ca_dll_pll_c_aid_tracking_cc.cc + gps_l1_ca_dll_pll_c_aid_tracking_sc.cc + glonass_l1_ca_dll_pll_tracking_cc.cc + glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc + glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc + gps_l1_ca_kf_tracking_cc.cc + glonass_l2_ca_dll_pll_tracking_cc.cc + glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc + glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc + dll_pll_veml_tracking.cc + ${OPT_TRACKING_BLOCKS_SOURCES} +) + +set(TRACKING_GR_BLOCKS_HEADERS + galileo_e1_tcp_connector_tracking_cc.h + gps_l1_ca_tcp_connector_tracking_cc.h + gps_l1_ca_dll_pll_c_aid_tracking_cc.h + gps_l1_ca_dll_pll_c_aid_tracking_sc.h + glonass_l1_ca_dll_pll_tracking_cc.h + glonass_l1_ca_dll_pll_c_aid_tracking_cc.h + glonass_l1_ca_dll_pll_c_aid_tracking_sc.h + gps_l1_ca_kf_tracking_cc.h + glonass_l2_ca_dll_pll_tracking_cc.h + glonass_l2_ca_dll_pll_c_aid_tracking_cc.h + glonass_l2_ca_dll_pll_c_aid_tracking_sc.h + dll_pll_veml_tracking.h + ${OPT_TRACKING_BLOCKS_HEADERS} ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${VOLK_GNSSSDR_INCLUDE_DIRS} - ${OPT_TRACKING_INCLUDES} - ${MATIO_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${ARMADILLO_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_GNSSSDR_INCLUDE_DIRS} + ${OPT_TRACKING_INCLUDES} + ${MATIO_INCLUDE_DIRS} ) if(ENABLE_GENERIC_ARCH) - add_definitions( -DGENERIC_ARCH=1 ) -endif(ENABLE_GENERIC_ARCH) + add_definitions(-DGENERIC_ARCH=1) +endif() -file(GLOB TRACKING_GR_BLOCKS_HEADERS "*.h") list(SORT TRACKING_GR_BLOCKS_HEADERS) -add_library(tracking_gr_blocks ${TRACKING_GR_BLOCKS_SOURCES} ${TRACKING_GR_BLOCKS_HEADERS}) +list(SORT TRACKING_GR_BLOCKS_SOURCES) + +add_library(tracking_gr_blocks + ${TRACKING_GR_BLOCKS_SOURCES} + ${TRACKING_GR_BLOCKS_HEADERS} +) + source_group(Headers FILES ${TRACKING_GR_BLOCKS_HEADERS}) -target_link_libraries(tracking_gr_blocks tracking_lib ${GNURADIO_RUNTIME_LIBRARIES} gnss_sdr_flags gnss_sp_libs ${Boost_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${MATIO_LIBRARIES} ${OPT_TRACKING_LIBRARIES}) +target_link_libraries(tracking_gr_blocks + tracking_lib + ${GNURADIO_RUNTIME_LIBRARIES} + gnss_sdr_flags gnss_sp_libs + ${Boost_LIBRARIES} + ${VOLK_GNSSSDR_LIBRARIES} + ${MATIO_LIBRARIES} + ${OPT_TRACKING_LIBRARIES} +) -if(NOT VOLK_GNSSSDR_FOUND) +if(NOT VOLKGNSSSDR_FOUND) if(MATIO_FOUND) add_dependencies(tracking_gr_blocks volk_gnsssdr_module) - else(MATIO_FOUND) - add_dependencies(tracking_gr_blocks volk_gnsssdr_module matio-${GNSSSDR_MATIO_LOCAL_VERSION}) - endif(MATIO_FOUND) -else(NOT VOLK_GNSSSDR_FOUND) + else() + add_dependencies(tracking_gr_blocks volk_gnsssdr_module + matio-${GNSSSDR_MATIO_LOCAL_VERSION} + ) + endif() +else() if(NOT MATIO_FOUND) - add_dependencies(tracking_gr_blocks matio-${GNSSSDR_MATIO_LOCAL_VERSION}) - endif(NOT MATIO_FOUND) -endif(NOT VOLK_GNSSSDR_FOUND) + add_dependencies(tracking_gr_blocks + matio-${GNSSSDR_MATIO_LOCAL_VERSION} + ) + endif() +endif() diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index bd822c74c..0801d6862 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -1,6 +1,7 @@ /*! * \file dll_pll_veml_tracking.cc * \brief Implementation of a code DLL + carrier PLL tracking block. + * \author Javier Arribas, 2018. jarribas(at)cttc.es * \author Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com * * Code DLL + carrier PLL according to the algorithms described in: @@ -48,7 +49,8 @@ #include "gps_l2c_signal.h" #include "GPS_L5.h" #include "gps_l5_signal.h" -#include +#include "gnss_sdr_create_directory.h" +#include #include #include #include @@ -57,6 +59,7 @@ #include #include #include +#include using google::LogMessage; @@ -71,7 +74,7 @@ void dll_pll_veml_tracking::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(trk_parameters.vector_length) * 2; + ninput_items_required[0] = static_cast(trk_parameters.vector_length) * 2; } } @@ -84,13 +87,16 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl this->message_port_register_out(pmt::mp("events")); this->set_relative_rate(1.0 / static_cast(trk_parameters.vector_length)); + // Telemetry bit synchronization message port input (mainly for GPS L1 CA) + this->message_port_register_in(pmt::mp("preamble_samplestamp")); + // initialize internal vars d_veml = false; d_cloop = true; - d_synchonizing = false; d_code_chip_rate = 0.0; - d_secondary_code_length = 0; + d_secondary_code_length = 0U; d_secondary_code_string = nullptr; + d_gps_l1ca_preambles_symbols = nullptr; signal_type = std::string(trk_parameters.signal); std::map map_signal_pretty_name; @@ -115,18 +121,42 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_symbols_per_bit = GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; d_correlation_length_ms = 1; d_code_samples_per_chip = 1; - d_code_length_chips = static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS); + d_code_length_chips = static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS); // GPS L1 C/A does not have pilot component nor secondary code d_secondary = false; trk_parameters.track_pilot = false; interchange_iq = false; + + // set the preamble + uint16_t preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE; + + // preamble bits to sampled symbols + d_gps_l1ca_preambles_symbols = static_cast(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int32_t), volk_gnsssdr_get_alignment())); + int32_t n = 0; + for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++) + { + for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++) + { + if (preambles_bits[i] == 1) + { + d_gps_l1ca_preambles_symbols[n] = 1; + } + else + { + d_gps_l1ca_preambles_symbols[n] = -1; + } + n++; + } + } + d_symbol_history.resize(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); // Change fixed buffer size + d_symbol_history.clear(); // Clear all the elements in the buffer } else if (signal_type.compare("2S") == 0) { d_signal_carrier_freq = GPS_L2_FREQ_HZ; d_code_period = GPS_L2_M_PERIOD; d_code_chip_rate = GPS_L2_M_CODE_RATE_HZ; - d_code_length_chips = static_cast(GPS_L2_M_CODE_LENGTH_CHIPS); + d_code_length_chips = static_cast(GPS_L2_M_CODE_LENGTH_CHIPS); d_symbols_per_bit = GPS_L2_SAMPLES_PER_SYMBOL; d_correlation_length_ms = 20; d_code_samples_per_chip = 1; @@ -143,18 +173,18 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_symbols_per_bit = GPS_L5_SAMPLES_PER_SYMBOL; d_correlation_length_ms = 1; d_code_samples_per_chip = 1; - d_code_length_chips = static_cast(GPS_L5i_CODE_LENGTH_CHIPS); + d_code_length_chips = static_cast(GPS_L5i_CODE_LENGTH_CHIPS); d_secondary = true; if (trk_parameters.track_pilot) { - d_secondary_code_length = static_cast(GPS_L5q_NH_CODE_LENGTH); + d_secondary_code_length = static_cast(GPS_L5q_NH_CODE_LENGTH); d_secondary_code_string = const_cast(&GPS_L5q_NH_CODE_STR); signal_pretty_name = signal_pretty_name + "Q"; interchange_iq = true; } else { - d_secondary_code_length = static_cast(GPS_L5i_NH_CODE_LENGTH); + d_secondary_code_length = static_cast(GPS_L5i_NH_CODE_LENGTH); d_secondary_code_string = const_cast(&GPS_L5i_NH_CODE_STR); signal_pretty_name = signal_pretty_name + "I"; interchange_iq = false; @@ -169,8 +199,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl interchange_iq = false; d_signal_carrier_freq = 0.0; d_code_period = 0.0; - d_code_length_chips = 0; - d_code_samples_per_chip = 0; + d_code_length_chips = 0U; + d_code_samples_per_chip = 0U; d_symbols_per_bit = 0; } } @@ -182,7 +212,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_signal_carrier_freq = Galileo_E1_FREQ_HZ; d_code_period = Galileo_E1_CODE_PERIOD; d_code_chip_rate = Galileo_E1_CODE_CHIP_RATE_HZ; - d_code_length_chips = static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS); + d_code_length_chips = static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS); d_symbols_per_bit = 1; d_correlation_length_ms = 4; d_code_samples_per_chip = 2; // CBOC disabled: 2 samples per chip. CBOC enabled: 12 samples per chip @@ -190,7 +220,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl if (trk_parameters.track_pilot) { d_secondary = true; - d_secondary_code_length = static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); + d_secondary_code_length = static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); d_secondary_code_string = const_cast(&Galileo_E1_C_SECONDARY_CODE); signal_pretty_name = signal_pretty_name + "C"; } @@ -209,18 +239,19 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_symbols_per_bit = 20; d_correlation_length_ms = 1; d_code_samples_per_chip = 1; - d_code_length_chips = static_cast(Galileo_E5a_CODE_LENGTH_CHIPS); - d_secondary = true; + d_code_length_chips = static_cast(Galileo_E5a_CODE_LENGTH_CHIPS); + if (trk_parameters.track_pilot) { - d_secondary_code_length = static_cast(Galileo_E5a_Q_SECONDARY_CODE_LENGTH); + d_secondary = true; + d_secondary_code_length = static_cast(Galileo_E5a_Q_SECONDARY_CODE_LENGTH); signal_pretty_name = signal_pretty_name + "Q"; interchange_iq = true; } else { - d_secondary_code_length = static_cast(Galileo_E5a_I_SECONDARY_CODE_LENGTH); - d_secondary_code_string = const_cast(&Galileo_E5a_I_SECONDARY_CODE); + //Do not acquire secondary code in data component. It is done in telemetry decoder + d_secondary = false; signal_pretty_name = signal_pretty_name + "I"; interchange_iq = false; } @@ -234,8 +265,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl interchange_iq = false; d_signal_carrier_freq = 0.0; d_code_period = 0.0; - d_code_length_chips = 0; - d_code_samples_per_chip = 0; + d_code_length_chips = 0U; + d_code_samples_per_chip = 0U; d_symbols_per_bit = 0; } } @@ -248,8 +279,8 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl interchange_iq = false; d_signal_carrier_freq = 0.0; d_code_period = 0.0; - d_code_length_chips = 0; - d_code_samples_per_chip = 0; + d_code_length_chips = 0U; + d_code_samples_per_chip = 0U; d_symbols_per_bit = 0; } T_chip_seconds = 0.0; @@ -258,7 +289,6 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl K_blk_samples = 0.0; // Initialize tracking ========================================== - d_code_loop_filter.set_DLL_BW(trk_parameters.dll_bw_hz); d_carrier_loop_filter.set_PLL_BW(trk_parameters.pll_bw_hz); d_code_loop_filter = Tracking_2nd_DLL_filter(static_cast(d_code_period)); @@ -282,7 +312,6 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_local_code_shift_chips = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(float), volk_gnsssdr_get_alignment())); - // map memory pointers of correlator outputs if (d_veml) { @@ -328,6 +357,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl { // Extra correlator for the data component correlator_data_cpu.init(2 * trk_parameters.vector_length, 1); + correlator_data_cpu.set_high_dynamics_resampler(trk_parameters.high_dyn); d_data_code = static_cast(volk_gnsssdr_malloc(2 * d_code_length_chips * sizeof(float), volk_gnsssdr_get_alignment())); } else @@ -336,6 +366,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl } // --- Initializations --- + multicorrelator_cpu.set_high_dynamics_resampler(trk_parameters.high_dyn); // Initial code frequency basis of NCO d_code_freq_chips = d_code_chip_rate; // Residual code phase (in chips) @@ -344,10 +375,10 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_rem_carr_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; - d_acq_sample_stamp = 0; + d_sample_counter = 0ULL; + d_acq_sample_stamp = 0ULL; - d_current_prn_length_samples = static_cast(trk_parameters.vector_length); + d_current_prn_length_samples = static_cast(trk_parameters.vector_length); // CN0 estimation and lock detector buffers d_cn0_estimation_counter = 0; @@ -367,13 +398,59 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl d_extend_correlation_symbols_count = 0; d_code_phase_step_chips = 0.0; + d_code_phase_rate_step_chips = 0.0; d_carrier_phase_step_rad = 0.0; + d_carrier_phase_rate_step_rad = 0.0; d_rem_code_phase_chips = 0.0; - d_K_blk_samples = 0.0; - d_code_phase_samples = 0.0; d_last_prompt = gr_complex(0.0, 0.0); d_state = 0; // initial state: standby clear_tracking_vars(); + if (trk_parameters.smoother_length > 0) + { + d_carr_ph_history.resize(trk_parameters.smoother_length * 2); + d_code_ph_history.resize(trk_parameters.smoother_length * 2); + } + else + { + d_carr_ph_history.resize(1); + d_code_ph_history.resize(1); + } + + d_dump = trk_parameters.dump; + d_dump_mat = trk_parameters.dump_mat and d_dump; + if (d_dump) + { + d_dump_filename = trk_parameters.dump_filename; + std::string dump_path; + // Get path + if (d_dump_filename.find_last_of("/") != std::string::npos) + { + std::string dump_filename_ = d_dump_filename.substr(d_dump_filename.find_last_of("/") + 1); + dump_path = d_dump_filename.substr(0, d_dump_filename.find_last_of("/")); + d_dump_filename = dump_filename_; + } + else + { + dump_path = std::string("."); + } + if (d_dump_filename.empty()) + { + d_dump_filename = "trk_channel_"; + } + // remove extension if any + if (d_dump_filename.substr(1).find_last_of(".") != std::string::npos) + { + d_dump_filename = d_dump_filename.substr(0, d_dump_filename.find_last_of(".")); + } + + d_dump_filename = dump_path + boost::filesystem::path::preferred_separator + d_dump_filename; + // create directory + if (!gnss_sdr_create_directory(dump_path)) + { + std::cerr << "GNSS-SDR cannot create dump files for the tracking block. Wrong permissions?" << std::endl; + d_dump = false; + } + } } @@ -386,37 +463,11 @@ void dll_pll_veml_tracking::start_tracking() d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; - long int acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); - double acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / trk_parameters.fs_in; - DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples; - DLOG(INFO) << "Number of seconds between Acquisition and Tracking = " << acq_trk_diff_seconds; - // Doppler effect Fd = (C / (C + Vr)) * F - double radial_velocity = (d_signal_carrier_freq + d_acq_carrier_doppler_hz) / d_signal_carrier_freq; - // new chip and PRN sequence periods based on acq Doppler - d_code_freq_chips = radial_velocity * d_code_chip_rate; - d_code_phase_step_chips = d_code_freq_chips / trk_parameters.fs_in; - double T_chip_mod_seconds = 1.0 / d_code_freq_chips; - double T_prn_mod_seconds = T_chip_mod_seconds * static_cast(d_code_length_chips); - double T_prn_mod_samples = T_prn_mod_seconds * trk_parameters.fs_in; - - d_current_prn_length_samples = std::round(T_prn_mod_samples); - - double T_prn_true_seconds = static_cast(d_code_length_chips) / d_code_chip_rate; - double T_prn_true_samples = T_prn_true_seconds * trk_parameters.fs_in; - double T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds; - double N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds; - double corrected_acq_phase_samples = std::fmod(d_acq_code_phase_samples + T_prn_diff_seconds * N_prn_diff * trk_parameters.fs_in, T_prn_true_samples); - if (corrected_acq_phase_samples < 0.0) - { - corrected_acq_phase_samples += T_prn_mod_samples; - } - double delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples; - - d_acq_code_phase_samples = corrected_acq_phase_samples; - d_carrier_doppler_hz = d_acq_carrier_doppler_hz; d_carrier_phase_step_rad = PI_2 * d_carrier_doppler_hz / trk_parameters.fs_in; - + d_carrier_phase_rate_step_rad = 0.0; + d_carr_ph_history.clear(); + d_code_ph_history.clear(); // DLL/PLL filter initialization d_carrier_loop_filter.initialize(); // initialize the carrier filter d_code_loop_filter.initialize(); // initialize the code filter @@ -465,17 +516,17 @@ void dll_pll_veml_tracking::start_tracking() if (trk_parameters.track_pilot) { d_secondary_code_string = const_cast(&Galileo_E5a_Q_SECONDARY_CODE[d_acquisition_gnss_synchro->PRN - 1]); - for (unsigned int i = 0; i < d_code_length_chips; i++) + for (uint32_t i = 0; i < d_code_length_chips; i++) { d_tracking_code[i] = aux_code[i].imag(); - d_data_code[i] = aux_code[i].real(); + d_data_code[i] = aux_code[i].real(); //the same because it is generated the full signal (E5aI + E5aQ) } d_Prompt_Data[0] = gr_complex(0.0, 0.0); correlator_data_cpu.set_local_code_and_taps(d_code_length_chips, d_data_code, d_prompt_data_shift); } else { - for (unsigned int i = 0; i < d_code_length_chips; i++) + for (uint32_t i = 0; i < d_code_length_chips; i++) { d_tracking_code[i] = aux_code[i].real(); } @@ -508,7 +559,6 @@ void dll_pll_veml_tracking::start_tracking() d_local_code_shift_chips[2] = trk_parameters.early_late_space_chips * static_cast(d_code_samples_per_chip); } - d_code_phase_samples = d_acq_code_phase_samples; d_code_loop_filter.set_DLL_BW(trk_parameters.dll_bw_hz); d_carrier_loop_filter.set_PLL_BW(trk_parameters.pll_bw_hz); d_carrier_loop_filter.set_pdi(static_cast(d_code_period)); @@ -516,22 +566,23 @@ void dll_pll_veml_tracking::start_tracking() // DEBUG OUTPUT std::cout << "Tracking of " << systemName << " " << signal_pretty_name << " signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; - LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; + DLOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; // enable tracking pull-in d_state = 1; - d_synchonizing = false; d_cloop = true; d_Prompt_buffer_deque.clear(); d_last_prompt = gr_complex(0.0, 0.0); - LOG(INFO) << "PULL-IN Doppler [Hz] = " << d_carrier_doppler_hz - << ". Code Phase correction [samples] = " << delay_correction_samples - << ". PULL-IN Code Phase [samples] = " << d_acq_code_phase_samples; } dll_pll_veml_tracking::~dll_pll_veml_tracking() { + if (signal_type.compare("1C") == 0) + { + volk_gnsssdr_free(d_gps_l1ca_preambles_symbols); + } + if (d_dump_file.is_open()) { try @@ -543,17 +594,9 @@ dll_pll_veml_tracking::~dll_pll_veml_tracking() LOG(WARNING) << "Exception in destructor " << ex.what(); } } - if (trk_parameters.dump) + if (d_dump_mat) { - if (d_channel == 0) - { - std::cout << "Writing .mat files ..."; - } save_matfile(); - if (d_channel == 0) - { - std::cout << " done." << std::endl; - } } try { @@ -579,8 +622,8 @@ dll_pll_veml_tracking::~dll_pll_veml_tracking() bool dll_pll_veml_tracking::acquire_secondary() { // ******* preamble correlation ******** - int corr_value = 0; - for (unsigned int i = 0; i < d_secondary_code_length; i++) + int32_t corr_value = 0; + for (uint32_t i = 0; i < d_secondary_code_length; i++) { if (d_Prompt_buffer_deque.at(i).real() < 0.0) // symbols clipping { @@ -606,7 +649,7 @@ bool dll_pll_veml_tracking::acquire_secondary() } } - if (abs(corr_value) == static_cast(d_secondary_code_length)) + if (abs(corr_value) == static_cast(d_secondary_code_length)) { return true; } @@ -672,9 +715,10 @@ void dll_pll_veml_tracking::do_correlation_step(const gr_complex *input_samples) multicorrelator_cpu.set_input_output_vectors(d_correlator_outs, input_samples); multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler( d_rem_carr_phase_rad, - d_carrier_phase_step_rad, + d_carrier_phase_step_rad, d_carrier_phase_rate_step_rad, static_cast(d_rem_code_phase_chips) * static_cast(d_code_samples_per_chip), static_cast(d_code_phase_step_chips) * static_cast(d_code_samples_per_chip), + static_cast(d_code_phase_rate_step_chips) * static_cast(d_code_samples_per_chip), trk_parameters.vector_length); // DATA CORRELATOR (if tracking tracks the pilot signal) @@ -683,9 +727,10 @@ void dll_pll_veml_tracking::do_correlation_step(const gr_complex *input_samples) correlator_data_cpu.set_input_output_vectors(d_Prompt_Data, input_samples); correlator_data_cpu.Carrier_wipeoff_multicorrelator_resampler( d_rem_carr_phase_rad, - d_carrier_phase_step_rad, + d_carrier_phase_step_rad, d_carrier_phase_rate_step_rad, static_cast(d_rem_code_phase_chips) * static_cast(d_code_samples_per_chip), static_cast(d_code_phase_step_chips) * static_cast(d_code_samples_per_chip), + static_cast(d_code_phase_rate_step_chips) * static_cast(d_code_samples_per_chip), trk_parameters.vector_length); } } @@ -710,8 +755,7 @@ void dll_pll_veml_tracking::run_dll_pll() d_carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(d_carr_error_hz); // New carrier Doppler frequency estimation d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_carr_error_filt_hz; - // New code Doppler frequency estimation - d_code_freq_chips = (1.0 + (d_carrier_doppler_hz / d_signal_carrier_freq)) * d_code_chip_rate; + // ################## DLL ########################################################## // DLL discriminator @@ -725,6 +769,9 @@ void dll_pll_veml_tracking::run_dll_pll() } // Code discriminator filter d_code_error_filt_chips = d_code_loop_filter.get_code_nco(d_code_error_chips); // [chips/second] + + // New code Doppler frequency estimation + d_code_freq_chips = (1.0 + (d_carrier_doppler_hz / d_signal_carrier_freq)) * d_code_chip_rate - d_code_error_filt_chips; } @@ -739,6 +786,10 @@ void dll_pll_veml_tracking::clear_tracking_vars() d_current_symbol = 0; d_Prompt_buffer_deque.clear(); d_last_prompt = gr_complex(0.0, 0.0); + d_carrier_phase_rate_step_rad = 0.0; + d_code_phase_rate_step_chips = 0.0; + d_carr_ph_history.clear(); + d_code_ph_history.clear(); } @@ -746,27 +797,72 @@ void dll_pll_veml_tracking::update_tracking_vars() { T_chip_seconds = 1.0 / d_code_freq_chips; T_prn_seconds = T_chip_seconds * static_cast(d_code_length_chips); - double code_error_filt_secs = T_prn_seconds * d_code_error_filt_chips * T_chip_seconds; //[seconds] // ################## CARRIER AND CODE NCO BUFFER ALIGNMENT ####################### // keep alignment parameters for the next input buffer // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation T_prn_samples = T_prn_seconds * trk_parameters.fs_in; - K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * trk_parameters.fs_in; - d_current_prn_length_samples = static_cast(round(K_blk_samples)); // round to a discrete number of samples + K_blk_samples = T_prn_samples + d_rem_code_phase_samples; + //d_current_prn_length_samples = static_cast(round(K_blk_samples)); // round to a discrete number of samples + d_current_prn_length_samples = static_cast(std::floor(K_blk_samples)); // round to a discrete number of samples //################### PLL COMMANDS ################################################# // carrier phase step (NCO phase increment per sample) [rads/sample] d_carrier_phase_step_rad = PI_2 * d_carrier_doppler_hz / trk_parameters.fs_in; + // carrier phase rate step (NCO phase increment rate per sample) [rads/sample^2] + if (trk_parameters.high_dyn) + { + d_carr_ph_history.push_back(std::pair(d_carrier_phase_step_rad, static_cast(d_current_prn_length_samples))); + if (d_carr_ph_history.full()) + { + double tmp_cp1 = 0.0; + double tmp_cp2 = 0.0; + double tmp_samples = 0.0; + for (unsigned int k = 0; k < trk_parameters.smoother_length; k++) + { + tmp_cp1 += d_carr_ph_history.at(k).first; + tmp_cp2 += d_carr_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).first; + tmp_samples += d_carr_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).second; + } + tmp_cp1 /= static_cast(trk_parameters.smoother_length); + tmp_cp2 /= static_cast(trk_parameters.smoother_length); + d_carrier_phase_rate_step_rad = (tmp_cp2 - tmp_cp1) / tmp_samples; + } + } + //std::cout << d_carrier_phase_rate_step_rad * trk_parameters.fs_in * trk_parameters.fs_in / PI_2 << std::endl; // remnant carrier phase to prevent overflow in the code NCO - d_rem_carr_phase_rad += d_carrier_phase_step_rad * static_cast(d_current_prn_length_samples); + d_rem_carr_phase_rad += static_cast(d_carrier_phase_step_rad * static_cast(d_current_prn_length_samples) + 0.5 * d_carrier_phase_rate_step_rad * static_cast(d_current_prn_length_samples) * static_cast(d_current_prn_length_samples)); d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, PI_2); + + // carrier phase accumulator - d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * static_cast(d_current_prn_length_samples); + //double a = d_carrier_phase_step_rad * static_cast(d_current_prn_length_samples); + //double b = 0.5 * d_carrier_phase_rate_step_rad * static_cast(d_current_prn_length_samples) * static_cast(d_current_prn_length_samples); + //std::cout << fmod(b, PI_2) / fmod(a, PI_2) << std::endl; + d_acc_carrier_phase_rad -= (d_carrier_phase_step_rad * static_cast(d_current_prn_length_samples) + 0.5 * d_carrier_phase_rate_step_rad * static_cast(d_current_prn_length_samples) * static_cast(d_current_prn_length_samples)); //################### DLL COMMANDS ################################################# // code phase step (Code resampler phase increment per sample) [chips/sample] d_code_phase_step_chips = d_code_freq_chips / trk_parameters.fs_in; + if (trk_parameters.high_dyn) + { + d_code_ph_history.push_back(std::pair(d_code_phase_step_chips, static_cast(d_current_prn_length_samples))); + if (d_code_ph_history.full()) + { + double tmp_cp1 = 0.0; + double tmp_cp2 = 0.0; + double tmp_samples = 0.0; + for (unsigned int k = 0; k < trk_parameters.smoother_length; k++) + { + tmp_cp1 += d_code_ph_history.at(k).first; + tmp_cp2 += d_code_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).first; + tmp_samples += d_code_ph_history.at(trk_parameters.smoother_length * 2 - k - 1).second; + } + tmp_cp1 /= static_cast(trk_parameters.smoother_length); + tmp_cp2 /= static_cast(trk_parameters.smoother_length); + d_code_phase_rate_step_chips = (tmp_cp2 - tmp_cp1) / tmp_samples; + } + } // remnant code phase [chips] d_rem_code_phase_samples = K_blk_samples - static_cast(d_current_prn_length_samples); // rounding error < 1 sample d_rem_code_phase_chips = d_code_freq_chips * d_rem_code_phase_samples / trk_parameters.fs_in; @@ -826,7 +922,7 @@ void dll_pll_veml_tracking::save_correlation_results() void dll_pll_veml_tracking::log_data(bool integrating) { - if (trk_parameters.dump) + if (d_dump) { // Dump results to file float prompt_I; @@ -834,6 +930,7 @@ void dll_pll_veml_tracking::log_data(bool integrating) float tmp_VE, tmp_E, tmp_P, tmp_L, tmp_VL; float tmp_float; double tmp_double; + uint64_t tmp_long_int; if (trk_parameters.track_pilot) { if (interchange_iq) @@ -900,15 +997,22 @@ void dll_pll_veml_tracking::log_data(bool integrating) d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + tmp_long_int = d_sample_counter + static_cast(d_current_prn_length_samples); + d_dump_file.write(reinterpret_cast(&tmp_long_int), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_rad; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); // carrier and code frequency tmp_float = d_carrier_doppler_hz; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // carrier phase rate [Hz/s] + tmp_float = d_carrier_phase_rate_step_rad * trk_parameters.fs_in * trk_parameters.fs_in / PI_2; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); tmp_float = d_code_freq_chips; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // code phase rate [chips/s^2] + tmp_float = d_code_phase_rate_step_chips * trk_parameters.fs_in * trk_parameters.fs_in; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); // PLL commands tmp_float = d_carr_error_hz; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -930,8 +1034,8 @@ void dll_pll_veml_tracking::log_data(bool integrating) tmp_double = static_cast(d_sample_counter + d_current_prn_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure &e) { @@ -941,19 +1045,25 @@ void dll_pll_veml_tracking::log_data(bool integrating) } -int dll_pll_veml_tracking::save_matfile() +int32_t dll_pll_veml_tracking::save_matfile() { // READ DUMP FILE std::ifstream::pos_type size; - int number_of_double_vars = 1; - int number_of_float_vars = 17; - int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + - sizeof(float) * number_of_float_vars + sizeof(unsigned int); + int32_t number_of_double_vars = 1; + int32_t number_of_float_vars = 19; + int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + // add channel number to the filename + dump_filename_.append(std::to_string(d_channel)); + // add extension + dump_filename_.append(".dat"); + std::cout << "Generating .mat file for " << dump_filename_ << std::endl; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { - dump_file.open(trk_parameters.dump_filename.c_str(), std::ios::binary | std::ios::ate); + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); } catch (const std::ifstream::failure &e) { @@ -961,11 +1071,11 @@ int dll_pll_veml_tracking::save_matfile() return 1; } // count number of epochs and rewind - long int num_epoch = 0; + int64_t num_epoch = 0; if (dump_file.is_open()) { size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); dump_file.seekg(0, std::ios::beg); } else @@ -979,10 +1089,12 @@ int dll_pll_veml_tracking::save_matfile() float *abs_VL = new float[num_epoch]; float *Prompt_I = new float[num_epoch]; float *Prompt_Q = new float[num_epoch]; - unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch]; + uint64_t *PRN_start_sample_count = new uint64_t[num_epoch]; float *acc_carrier_phase_rad = new float[num_epoch]; float *carrier_doppler_hz = new float[num_epoch]; + float *carrier_doppler_rate_hz = new float[num_epoch]; float *code_freq_chips = new float[num_epoch]; + float *code_freq_rate_chips = new float[num_epoch]; float *carr_error_hz = new float[num_epoch]; float *carr_error_filt_hz = new float[num_epoch]; float *code_error_chips = new float[num_epoch]; @@ -991,13 +1103,13 @@ int dll_pll_veml_tracking::save_matfile() float *carrier_lock_test = new float[num_epoch]; float *aux1 = new float[num_epoch]; double *aux2 = new double[num_epoch]; - unsigned int *PRN = new unsigned int[num_epoch]; + uint32_t *PRN = new uint32_t[num_epoch]; try { if (dump_file.is_open()) { - for (long int i = 0; i < num_epoch; i++) + for (int64_t i = 0; i < num_epoch; i++) { dump_file.read(reinterpret_cast(&abs_VE[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); @@ -1006,10 +1118,12 @@ int dll_pll_veml_tracking::save_matfile() dump_file.read(reinterpret_cast(&abs_VL[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(uint64_t)); dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(float)); dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carrier_doppler_rate_hz[i]), sizeof(float)); dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_freq_rate_chips[i]), sizeof(float)); dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(float)); dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(float)); dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(float)); @@ -1018,7 +1132,7 @@ int dll_pll_veml_tracking::save_matfile() dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(float)); dump_file.read(reinterpret_cast(&aux1[i]), sizeof(float)); dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(uint32_t)); } } dump_file.close(); @@ -1036,7 +1150,9 @@ int dll_pll_veml_tracking::save_matfile() delete[] PRN_start_sample_count; delete[] acc_carrier_phase_rad; delete[] carrier_doppler_hz; + delete[] carrier_doppler_rate_hz; delete[] code_freq_chips; + delete[] code_freq_rate_chips; delete[] carr_error_hz; delete[] carr_error_filt_hz; delete[] code_error_chips; @@ -1052,11 +1168,11 @@ int dll_pll_veml_tracking::save_matfile() // WRITE MAT FILE mat_t *matfp; matvar_t *matvar; - std::string filename = trk_parameters.dump_filename; + std::string filename = dump_filename_; filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (reinterpret_cast(matfp) != NULL) + if (reinterpret_cast(matfp) != NULL) { size_t dims[2] = {1, static_cast(num_epoch)}; matvar = Mat_VarCreate("abs_VE", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_VE, 0); @@ -1099,10 +1215,18 @@ int dll_pll_veml_tracking::save_matfile() Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarFree(matvar); + matvar = Mat_VarCreate("carrier_doppler_rate_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_doppler_rate_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + matvar = Mat_VarCreate("code_freq_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_freq_chips, 0); Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarFree(matvar); + matvar = Mat_VarCreate("code_freq_rate_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_freq_rate_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + matvar = Mat_VarCreate("carr_error_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_hz, 0); Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarFree(matvar); @@ -1150,7 +1274,9 @@ int dll_pll_veml_tracking::save_matfile() delete[] PRN_start_sample_count; delete[] acc_carrier_phase_rad; delete[] carrier_doppler_hz; + delete[] carrier_doppler_rate_hz; delete[] code_freq_chips; + delete[] code_freq_rate_chips; delete[] carr_error_hz; delete[] carr_error_filt_hz; delete[] code_error_chips; @@ -1164,23 +1290,29 @@ int dll_pll_veml_tracking::save_matfile() } -void dll_pll_veml_tracking::set_channel(unsigned int channel) +void dll_pll_veml_tracking::set_channel(uint32_t channel) { gr::thread::scoped_lock l(d_setlock); d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; // ############# ENABLE DATA FILE LOG ################# - if (trk_parameters.dump) + if (d_dump) { + std::string dump_filename_ = d_dump_filename; + // add channel number to the filename + dump_filename_.append(std::to_string(d_channel)); + // add extension + dump_filename_.append(".dat"); + if (!d_dump_file.is_open()) { try { - trk_parameters.dump_filename.append(boost::lexical_cast(d_channel)); - trk_parameters.dump_filename.append(".dat"); + //trk_parameters.dump_filename.append(boost::lexical_cast(d_channel)); + //trk_parameters.dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(trk_parameters.dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << trk_parameters.dump_filename.c_str(); + d_dump_file.open(dump_filename_.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << dump_filename_.c_str(); } catch (const std::ifstream::failure &e) { @@ -1198,6 +1330,12 @@ void dll_pll_veml_tracking::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) } +void dll_pll_veml_tracking::stop_tracking() +{ + gr::thread::scoped_lock l(d_setlock); + d_state = 0; +} + int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { @@ -1210,7 +1348,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) { case 0: // Standby - Consume samples at full throttle, do nothing { - d_sample_counter += ninput_items[0]; + d_sample_counter += static_cast(ninput_items[0]); consume_each(ninput_items[0]); return 0; break; @@ -1218,17 +1356,34 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) case 1: // Pull-in { // Signal alignment (skip samples until the incoming signal is aligned with local replica) - unsigned long int acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; - double acq_trk_shif_correction_samples = static_cast(d_current_prn_length_samples) - std::fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); - int samples_offset = std::round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - if (samples_offset < 0) - { - samples_offset = 0; - } - d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * d_acq_code_phase_samples; + int64_t acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); + double acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / trk_parameters.fs_in; + double delta_trk_to_acq_prn_start_samples = static_cast(acq_trk_diff_samples) - d_acq_code_phase_samples; + + // Doppler effect Fd = (C / (C + Vr)) * F + double radial_velocity = (d_signal_carrier_freq + d_acq_carrier_doppler_hz) / d_signal_carrier_freq; + // new chip and PRN sequence periods based on acq Doppler + d_code_freq_chips = radial_velocity * d_code_chip_rate; + d_code_freq_chips = d_code_chip_rate; + d_code_phase_step_chips = d_code_freq_chips / trk_parameters.fs_in; + d_code_phase_rate_step_chips = 0.0; + double T_chip_mod_seconds = 1.0 / d_code_freq_chips; + double T_prn_mod_seconds = T_chip_mod_seconds * static_cast(d_code_length_chips); + double T_prn_mod_samples = T_prn_mod_seconds * trk_parameters.fs_in; + + d_acq_code_phase_samples = T_prn_mod_samples - std::fmod(delta_trk_to_acq_prn_start_samples, T_prn_mod_samples); + d_current_prn_length_samples = round(T_prn_mod_samples); + + int32_t samples_offset = round(d_acq_code_phase_samples); + d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * static_cast(samples_offset); d_state = 2; d_sample_counter += samples_offset; // count for the processed samples - consume_each(samples_offset); // shift input to perform alignment with local replica + + DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples << " ( " << acq_trk_diff_seconds << " s)"; + DLOG(INFO) << "PULL-IN Doppler [Hz] = " << d_carrier_doppler_hz + << ". PULL-IN Code Phase [samples] = " << d_acq_code_phase_samples; + + consume_each(samples_offset); // shift input to perform alignment with local replica return 0; } case 2: // Wide tracking and symbol synchronization @@ -1277,39 +1432,82 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) } else if (d_symbols_per_bit > 1) //Signal does not have secondary code. Search a bit transition by sign change { - if (d_synchonizing) + float current_tracking_time_s = static_cast(d_sample_counter - d_acq_sample_stamp) / trk_parameters.fs_in; + if (current_tracking_time_s > 10) { - if (d_Prompt->real() * d_last_prompt.real() > 0.0) + d_symbol_history.push_back(d_Prompt->real()); + //******* preamble correlation ******** + int32_t corr_value = 0; + if ((d_symbol_history.size() == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)) // and (d_make_correlation or !d_flag_frame_sync)) { - d_current_symbol++; + for (uint32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++) + { + if (d_symbol_history.at(i) < 0) // symbols clipping + { + corr_value -= d_gps_l1ca_preambles_symbols[i]; + } + else + { + corr_value += d_gps_l1ca_preambles_symbols[i]; + } + } } - else if (d_current_symbol > d_symbols_per_bit) + if (corr_value == GPS_CA_PREAMBLE_LENGTH_SYMBOLS) { - d_synchonizing = false; - d_current_symbol = 1; + //std::cout << "Preamble detected at tracking!" << std::endl; + next_state = true; } else { - d_current_symbol = 1; - d_last_prompt = *d_Prompt; + next_state = false; } } - else if (d_last_prompt.real() != 0.0) - { - d_current_symbol++; - if (d_current_symbol == d_symbols_per_bit) next_state = true; - } else { - d_last_prompt = *d_Prompt; - d_synchonizing = true; - d_current_symbol = 1; + next_state = false; } } else { next_state = true; } + + // ########### Output the tracking results to Telemetry block ########## + if (interchange_iq) + { + if (trk_parameters.track_pilot) + { + // Note that data and pilot components are in quadrature. I and Q are interchanged + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).imag()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).real()); + } + else + { + current_synchro_data.Prompt_I = static_cast((*d_Prompt).imag()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).real()); + } + } + else + { + if (trk_parameters.track_pilot) + { + // Note that data and pilot components are in quadrature. I and Q are interchanged + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); + } + else + { + current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); + } + } + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + current_synchro_data.Flag_valid_symbol_output = true; + current_synchro_data.correlation_length_ms = d_correlation_length_ms; + if (next_state) { // reset extended correlator d_VE_accu = gr_complex(0.0, 0.0); @@ -1320,7 +1518,6 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) d_last_prompt = gr_complex(0.0, 0.0); d_Prompt_buffer_deque.clear(); d_current_symbol = 0; - d_synchonizing = false; if (d_enable_extended_integration) { @@ -1330,10 +1527,10 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) d_carrier_loop_filter.set_pdi(new_correlation_time); d_code_loop_filter.set_pdi(new_correlation_time); d_state = 3; // next state is the extended correlator integrator - LOG(INFO) << "Enabled " << trk_parameters.extend_correlation_symbols * static_cast(d_code_period * 1000.0) << " ms extended correlator in channel " + LOG(INFO) << "Enabled " << trk_parameters.extend_correlation_symbols * static_cast(d_code_period * 1000.0) << " ms extended correlator in channel " << d_channel << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN); - std::cout << "Enabled " << trk_parameters.extend_correlation_symbols * static_cast(d_code_period * 1000.0) << " ms extended correlator in channel " + std::cout << "Enabled " << trk_parameters.extend_correlation_symbols * static_cast(d_code_period * 1000.0) << " ms extended correlator in channel " << d_channel << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; // Set narrow taps delay values [chips] @@ -1484,10 +1681,10 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) } } consume_each(d_current_prn_length_samples); - d_sample_counter += d_current_prn_length_samples; + d_sample_counter += static_cast(d_current_prn_length_samples); if (current_synchro_data.Flag_valid_symbol_output) { - current_synchro_data.fs = static_cast(trk_parameters.fs_in); + current_synchro_data.fs = static_cast(trk_parameters.fs_in); current_synchro_data.Tracking_sample_counter = d_sample_counter; *out[0] = current_synchro_data; return 1; diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h index 0437e8a35..59a980b31 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h @@ -1,6 +1,7 @@ /*! * \file dll_pll_veml_tracking.h * \brief Implementation of a code DLL + carrier PLL tracking block. + * \author Javier Arribas, 2018. jarribas(at)cttc.es * \author Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com * * ------------------------------------------------------------------------- @@ -41,6 +42,8 @@ #include #include #include +#include +#include class dll_pll_veml_tracking; @@ -56,9 +59,10 @@ class dll_pll_veml_tracking : public gr::block public: ~dll_pll_veml_tracking(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro); void start_tracking(); + void stop_tracking(); int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); @@ -69,6 +73,7 @@ private: friend dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(const Dll_Pll_Conf &conf_); dll_pll_veml_tracking(const Dll_Pll_Conf &conf_); + void msg_handler_preamble_index(pmt::pmt_t msg); bool cn0_and_tracking_lock_status(double coh_integration_time_s); bool acquire_secondary(); @@ -78,13 +83,13 @@ private: void clear_tracking_vars(); void save_correlation_results(); void log_data(bool integrating); - int save_matfile(); + int32_t save_matfile(); // tracking configuration vars Dll_Pll_Conf trk_parameters; bool d_veml; bool d_cloop; - unsigned int d_channel; + uint32_t d_channel; Gnss_Synchro *d_acquisition_gnss_synchro; //Signal parameters @@ -93,21 +98,23 @@ private: double d_signal_carrier_freq; double d_code_period; double d_code_chip_rate; - unsigned int d_secondary_code_length; - unsigned int d_code_length_chips; - unsigned int d_code_samples_per_chip; // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled) - int d_symbols_per_bit; + uint32_t d_secondary_code_length; + uint32_t d_code_length_chips; + uint32_t d_code_samples_per_chip; // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled) + int32_t d_symbols_per_bit; std::string systemName; std::string signal_type; std::string *d_secondary_code_string; std::string signal_pretty_name; + int32_t *d_gps_l1ca_preambles_symbols; + boost::circular_buffer d_symbol_history; + //tracking state machine - int d_state; - bool d_synchonizing; + int32_t d_state; //Integration period in samples - int d_correlation_length_ms; - int d_n_correlator_taps; + int32_t d_correlation_length_ms; + int32_t d_n_correlator_taps; float *d_tracking_code; float *d_data_code; @@ -128,8 +135,8 @@ private: gr_complex *d_Very_Late; bool d_enable_extended_integration; - int d_extend_correlation_symbols_count; - int d_current_symbol; + int32_t d_extend_correlation_symbols_count; + int32_t d_current_symbol; gr_complex d_VE_accu; gr_complex d_E_accu; @@ -141,10 +148,14 @@ private: gr_complex *d_Prompt_Data; double d_code_phase_step_chips; + double d_code_phase_rate_step_chips; + boost::circular_buffer> d_code_ph_history; double d_carrier_phase_step_rad; + double d_carrier_phase_rate_step_rad; + boost::circular_buffer> d_carr_ph_history; // remaining code phase and carrier phase between tracking loops double d_rem_code_phase_samples; - double d_rem_carr_phase_rad; + float d_rem_carr_phase_rad; // PLL and DLL filter library Tracking_2nd_DLL_filter d_code_loop_filter; @@ -159,25 +170,23 @@ private: double d_carr_error_filt_hz; double d_code_error_chips; double d_code_error_filt_chips; - double d_K_blk_samples; double d_code_freq_chips; double d_carrier_doppler_hz; double d_acc_carrier_phase_rad; double d_rem_code_phase_chips; - double d_code_phase_samples; double T_chip_seconds; double T_prn_seconds; double T_prn_samples; double K_blk_samples; // PRN period in samples - int d_current_prn_length_samples; + int32_t d_current_prn_length_samples; // processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; - int d_carrier_lock_fail_counter; + int32_t d_cn0_estimation_counter; + int32_t d_carrier_lock_fail_counter; std::deque d_carrier_lock_detector_queue; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; @@ -187,6 +196,9 @@ private: // file dump std::ofstream d_dump_file; + std::string d_dump_filename; + bool d_dump; + bool d_dump_mat; }; #endif // GNSS_SDR_DLL_PLL_VEML_TRACKING_H diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc index 6dd2af0f7..f73ed6c90 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc @@ -1,8 +1,9 @@ /*! - * \file dll_pll_veml_tracking.cc + * \file dll_pll_veml_tracking_fpga.cc * \brief Implementation of a code DLL + carrier PLL tracking block using an FPGA * \author Marc Majoral, 2018. marc.majoral(at)cttc.es * Antonio Ramos, 2018 antonio.ramosdet(at)gmail.com + * Javier Arribas, 2018. jarribas(at)cttc.es * * Code DLL + carrier PLL according to the algorithms described in: * [1] K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen, @@ -46,7 +47,8 @@ #include "gps_l2c_signal.h" #include "GPS_L5.h" #include "gps_l5_signal.h" -#include +#include "gnss_sdr_create_directory.h" +#include #include #include #include @@ -56,22 +58,26 @@ #include #include + using google::LogMessage; -dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(dllpllconf_fpga_t conf_) +dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_) { return dll_pll_veml_tracking_fpga_sptr(new dll_pll_veml_tracking_fpga(conf_)); } -dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) : gr::block("dll_pll_veml_tracking_fpga", gr::io_signature::make(0, 0, sizeof(lv_16sc_t)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) +dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_) : gr::block("dll_pll_veml_tracking_fpga", gr::io_signature::make(0, 0, sizeof(lv_16sc_t)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { trk_parameters = conf_; // Telemetry bit synchronization message port input this->message_port_register_out(pmt::mp("events")); this->set_relative_rate(1.0 / static_cast(trk_parameters.vector_length)); + // Telemetry bit synchronization message port input (mainly for GPS L1 CA) + this->message_port_register_in(pmt::mp("preamble_samplestamp")); + // initialize internal vars d_veml = false; d_cloop = true; @@ -92,6 +98,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) signal_pretty_name = map_signal_pretty_name[signal_type]; + d_prompt_data_shift = nullptr; + if (trk_parameters.system == 'G') { systemName = "GPS"; @@ -102,22 +110,47 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) d_code_chip_rate = GPS_L1_CA_CODE_RATE_HZ; d_symbols_per_bit = GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; d_correlation_length_ms = 1; - d_code_samples_per_chip = 1; - d_code_length_chips = static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS); + //d_code_samples_per_chip = 1; + //d_code_length_chips = static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS); // GPS L1 C/A does not have pilot component nor secondary code d_secondary = false; trk_parameters.track_pilot = false; interchange_iq = false; + + + // set the preamble + uint16_t preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE; + + // preamble bits to sampled symbols + d_gps_l1ca_preambles_symbols = static_cast(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int32_t), volk_gnsssdr_get_alignment())); + int32_t n = 0; + for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++) + { + for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++) + { + if (preambles_bits[i] == 1) + { + d_gps_l1ca_preambles_symbols[n] = 1; + } + else + { + d_gps_l1ca_preambles_symbols[n] = -1; + } + n++; + } + } + d_symbol_history.resize(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); // Change fixed buffer size + d_symbol_history.clear(); // Clear all the elements in the buffer } else if (signal_type.compare("2S") == 0) { d_signal_carrier_freq = GPS_L2_FREQ_HZ; d_code_period = GPS_L2_M_PERIOD; d_code_chip_rate = GPS_L2_M_CODE_RATE_HZ; - d_code_length_chips = static_cast(GPS_L2_M_CODE_LENGTH_CHIPS); + //d_code_length_chips = static_cast(GPS_L2_M_CODE_LENGTH_CHIPS); d_symbols_per_bit = GPS_L2_SAMPLES_PER_SYMBOL; d_correlation_length_ms = 20; - d_code_samples_per_chip = 1; + //d_code_samples_per_chip = 1; // GPS L2 does not have pilot component nor secondary code d_secondary = false; trk_parameters.track_pilot = false; @@ -130,19 +163,20 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) d_code_chip_rate = GPS_L5i_CODE_RATE_HZ; d_symbols_per_bit = GPS_L5_SAMPLES_PER_SYMBOL; d_correlation_length_ms = 1; - d_code_samples_per_chip = 1; - d_code_length_chips = static_cast(GPS_L5i_CODE_LENGTH_CHIPS); + //d_code_samples_per_chip = 1; + //d_code_length_chips = static_cast(GPS_L5i_CODE_LENGTH_CHIPS); d_secondary = true; + // interchange_iq = false; if (trk_parameters.track_pilot) { - d_secondary_code_length = static_cast(GPS_L5q_NH_CODE_LENGTH); + d_secondary_code_length = static_cast(GPS_L5q_NH_CODE_LENGTH); d_secondary_code_string = const_cast(&GPS_L5q_NH_CODE_STR); signal_pretty_name = signal_pretty_name + "Q"; interchange_iq = true; } else { - d_secondary_code_length = static_cast(GPS_L5i_NH_CODE_LENGTH); + d_secondary_code_length = static_cast(GPS_L5i_NH_CODE_LENGTH); d_secondary_code_string = const_cast(&GPS_L5i_NH_CODE_STR); signal_pretty_name = signal_pretty_name + "I"; interchange_iq = false; @@ -157,8 +191,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) interchange_iq = false; d_signal_carrier_freq = 0.0; d_code_period = 0.0; - d_code_length_chips = 0; - d_code_samples_per_chip = 0; + //d_code_length_chips = 0; + //d_code_samples_per_chip = 0; d_symbols_per_bit = 0; } } @@ -170,15 +204,15 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) d_signal_carrier_freq = Galileo_E1_FREQ_HZ; d_code_period = Galileo_E1_CODE_PERIOD; d_code_chip_rate = Galileo_E1_CODE_CHIP_RATE_HZ; - d_code_length_chips = static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS); + //d_code_length_chips = static_cast(Galileo_E1_B_CODE_LENGTH_CHIPS); d_symbols_per_bit = 1; d_correlation_length_ms = 4; - d_code_samples_per_chip = 2; // CBOC disabled: 2 samples per chip. CBOC enabled: 12 samples per chip + //d_code_samples_per_chip = 2; // CBOC disabled: 2 samples per chip. CBOC enabled: 12 samples per chip d_veml = true; if (trk_parameters.track_pilot) { d_secondary = true; - d_secondary_code_length = static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); + d_secondary_code_length = static_cast(Galileo_E1_C_SECONDARY_CODE_LENGTH); d_secondary_code_string = const_cast(&Galileo_E1_C_SECONDARY_CODE); signal_pretty_name = signal_pretty_name + "C"; } @@ -196,18 +230,19 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) d_code_chip_rate = Galileo_E5a_CODE_CHIP_RATE_HZ; d_symbols_per_bit = 20; d_correlation_length_ms = 1; - d_code_samples_per_chip = 1; - d_code_length_chips = static_cast(Galileo_E5a_CODE_LENGTH_CHIPS); + //d_code_samples_per_chip = 1; + //d_code_length_chips = static_cast(Galileo_E5a_CODE_LENGTH_CHIPS); d_secondary = true; + //interchange_iq = false; if (trk_parameters.track_pilot) { - d_secondary_code_length = static_cast(Galileo_E5a_Q_SECONDARY_CODE_LENGTH); + d_secondary_code_length = static_cast(Galileo_E5a_Q_SECONDARY_CODE_LENGTH); signal_pretty_name = signal_pretty_name + "Q"; interchange_iq = true; } else { - d_secondary_code_length = static_cast(Galileo_E5a_I_SECONDARY_CODE_LENGTH); + d_secondary_code_length = static_cast(Galileo_E5a_I_SECONDARY_CODE_LENGTH); d_secondary_code_string = const_cast(&Galileo_E5a_I_SECONDARY_CODE); signal_pretty_name = signal_pretty_name + "I"; interchange_iq = false; @@ -222,8 +257,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) interchange_iq = false; d_signal_carrier_freq = 0.0; d_code_period = 0.0; - d_code_length_chips = 0; - d_code_samples_per_chip = 0; + //d_code_length_chips = 0; + //d_code_samples_per_chip = 0; d_symbols_per_bit = 0; } } @@ -236,8 +271,8 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) interchange_iq = false; d_signal_carrier_freq = 0.0; d_code_period = 0.0; - d_code_length_chips = 0; - d_code_samples_per_chip = 0; + //d_code_length_chips = 0; + //d_code_samples_per_chip = 0; d_symbols_per_bit = 0; } T_chip_seconds = 0.0; @@ -264,7 +299,9 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_local_code_shift_chips = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(float), volk_gnsssdr_get_alignment())); - std::fill_n(d_correlator_outs, d_n_correlator_taps, gr_complex(0.0, 0.0)); + //std::fill_n(d_correlator_outs, d_n_correlator_taps, gr_complex(0.0, 0.0)); + + d_code_samples_per_chip = trk_parameters.code_samples_per_chip; // number of samples per chip // map memory pointers of correlator outputs if (d_veml) @@ -274,6 +311,11 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) d_Prompt = &d_correlator_outs[2]; d_Late = &d_correlator_outs[3]; d_Very_Late = &d_correlator_outs[4]; + // printf("aaaa very early %f\n",-trk_parameters.very_early_late_space_chips); + // printf("aaaa early %f\n",-trk_parameters.early_late_space_chips); + // printf("aaaa normal %f\n",0); + // printf("aaaa late %f\n",trk_parameters.early_late_space_chips); + // printf("aaaa very late %f\n",trk_parameters.very_early_late_space_chips); d_local_code_shift_chips[0] = -trk_parameters.very_early_late_space_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[1] = -trk_parameters.early_late_space_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[2] = 0.0; @@ -288,6 +330,10 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) d_Prompt = &d_correlator_outs[1]; d_Late = &d_correlator_outs[2]; d_Very_Late = nullptr; + // printf("aaaa early %f\n",-trk_parameters.early_late_space_chips); + // printf("aaaa normal %f\n",0); + // printf("aaaa late %f\n",trk_parameters.early_late_space_chips); + d_local_code_shift_chips[0] = -trk_parameters.early_late_space_chips * static_cast(d_code_samples_per_chip); d_local_code_shift_chips[1] = 0.0; d_local_code_shift_chips[2] = trk_parameters.early_late_space_chips * static_cast(d_code_samples_per_chip); @@ -308,12 +354,12 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) if (trk_parameters.track_pilot) { // Extra correlator for the data component - d_Prompt_Data = static_cast(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); - d_Prompt_Data[0] = gr_complex(0.0, 0.0); + //d_Prompt_Data = static_cast(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); + //d_Prompt_Data[0] = gr_complex(0.0, 0.0); } else { - d_Prompt_Data = nullptr; + //d_Prompt_Data = nullptr; } //--- Initializations ---// @@ -325,12 +371,13 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) d_rem_carr_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; - d_acq_sample_stamp = 0; + d_sample_counter = 0ULL; + d_acq_sample_stamp = 0ULL; + d_absolute_samples_offset = 0ULL; - d_current_prn_length_samples = static_cast(trk_parameters.vector_length); + d_current_prn_length_samples = static_cast(trk_parameters.vector_length); d_next_prn_length_samples = d_current_prn_length_samples; - d_correlation_length_samples = static_cast(trk_parameters.vector_length); // this one is only for initialisation and does not change its value (MM) + d_correlation_length_samples = static_cast(trk_parameters.vector_length); // this one is only for initialisation and does not change its value (MM) // CN0 estimation and lock detector buffers d_cn0_estimation_counter = 0; @@ -339,8 +386,9 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) d_CN0_SNV_dB_Hz = 0.0; d_carrier_lock_fail_counter = 0; d_carrier_lock_threshold = trk_parameters.carrier_lock_th; + d_Prompt_Data = static_cast(volk_gnsssdr_malloc(sizeof(gr_complex), volk_gnsssdr_get_alignment())); - clear_tracking_vars(); + //clear_tracking_vars(); d_acquisition_gnss_synchro = nullptr; d_channel = 0; @@ -357,23 +405,64 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_) d_code_phase_samples = 0.0; d_last_prompt = gr_complex(0.0, 0.0); d_state = 0; // initial state: standby + clear_tracking_vars(); + + //printf("hhhhhhhhhhh d_n_correlator_taps = %d\n", d_n_correlator_taps); // create multicorrelator class std::string device_name = trk_parameters.device_name; - unsigned int device_base = trk_parameters.device_base; - int *ca_codes = trk_parameters.ca_codes; - unsigned int code_length = trk_parameters.code_length; - multicorrelator_fpga = std::make_shared(d_n_correlator_taps, device_name, device_base, ca_codes, code_length); - multicorrelator_fpga->set_output_vectors(d_correlator_outs); + uint32_t device_base = trk_parameters.device_base; + int32_t *ca_codes = trk_parameters.ca_codes; + int32_t *data_codes = trk_parameters.data_codes; + //uint32_t code_length = trk_parameters.code_length_chips; + d_code_length_chips = trk_parameters.code_length_chips; + uint32_t multicorr_type = trk_parameters.multicorr_type; + multicorrelator_fpga = std::make_shared(d_n_correlator_taps, device_name, device_base, ca_codes, data_codes, d_code_length_chips, trk_parameters.track_pilot, multicorr_type, d_code_samples_per_chip); + multicorrelator_fpga->set_output_vectors(d_correlator_outs, d_Prompt_Data); d_pull_in = 0; + + d_dump = trk_parameters.dump; + d_dump_mat = trk_parameters.dump_mat and d_dump; + if (d_dump) + { + d_dump_filename = trk_parameters.dump_filename; + std::string dump_path; + if (d_dump_filename.find_last_of("/") != std::string::npos) + { + std::string dump_filename_ = d_dump_filename.substr(d_dump_filename.find_last_of("/") + 1); + dump_path = d_dump_filename.substr(0, d_dump_filename.find_last_of("/")); + d_dump_filename = dump_filename_; + } + else + { + dump_path = std::string("."); + } + if (d_dump_filename.empty()) + { + d_dump_filename = "trk_channel_"; + } + // remove extension if any + if (d_dump_filename.substr(1).find_last_of(".") != std::string::npos) + { + d_dump_filename = d_dump_filename.substr(0, d_dump_filename.find_last_of(".")); + } + + d_dump_filename = dump_path + boost::filesystem::path::preferred_separator + d_dump_filename; + + // create directory + if (!gnss_sdr_create_directory(dump_path)) + { + std::cerr << "GNSS-SDR cannot create dump files for the tracking block. Wrong permissions?" << std::endl; + d_dump = false; + }; + } } + void dll_pll_veml_tracking_fpga::start_tracking() { - /* - * correct the code phase according to the delay between acq and trk - */ + // correct the code phase according to the delay between acq and trk d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples; d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; @@ -381,14 +470,16 @@ void dll_pll_veml_tracking_fpga::start_tracking() double acq_trk_diff_seconds = 0; // when using the FPGA we don't use the global sample counter // Doppler effect Fd = (C / (C + Vr)) * F double radial_velocity = (d_signal_carrier_freq + d_acq_carrier_doppler_hz) / d_signal_carrier_freq; - // new chip and prn sequence periods based on acq Doppler + // new chip and PRN sequence periods based on acq Doppler d_code_freq_chips = radial_velocity * d_code_chip_rate; d_code_phase_step_chips = d_code_freq_chips / trk_parameters.fs_in; + double T_chip_mod_seconds = 1.0 / d_code_freq_chips; double T_prn_mod_seconds = T_chip_mod_seconds * static_cast(d_code_length_chips); double T_prn_mod_samples = T_prn_mod_seconds * trk_parameters.fs_in; - d_current_prn_length_samples = std::round(T_prn_mod_samples); + //d_current_prn_length_samples = std::round(T_prn_mod_samples); + d_current_prn_length_samples = std::floor(T_prn_mod_samples); d_next_prn_length_samples = d_current_prn_length_samples; double T_prn_true_seconds = static_cast(d_code_length_chips) / d_code_chip_rate; double T_prn_true_samples = T_prn_true_seconds * trk_parameters.fs_in; @@ -433,7 +524,9 @@ void dll_pll_veml_tracking_fpga::start_tracking() { if (trk_parameters.track_pilot) { + //char pilot_signal[3] = "1C"; d_Prompt_Data[0] = gr_complex(0.0, 0.0); + // MISSING _: set_local_code_and_taps for the data correlator } else { @@ -445,7 +538,7 @@ void dll_pll_veml_tracking_fpga::start_tracking() if (trk_parameters.track_pilot) { d_secondary_code_string = const_cast(&Galileo_E5a_Q_SECONDARY_CODE[d_acquisition_gnss_synchro->PRN - 1]); - for (unsigned int i = 0; i < d_code_length_chips; i++) + for (uint32_t i = 0; i < d_code_length_chips; i++) { // nothing to compute : the local codes are pre-computed in the adapter class } @@ -453,7 +546,7 @@ void dll_pll_veml_tracking_fpga::start_tracking() } else { - for (unsigned int i = 0; i < d_code_length_chips; i++) + for (uint32_t i = 0; i < d_code_length_chips; i++) { // nothing to compute : the local codes are pre-computed in the adapter class } @@ -501,14 +594,21 @@ void dll_pll_veml_tracking_fpga::start_tracking() LOG(INFO) << "PULL-IN Doppler [Hz] = " << d_carrier_doppler_hz << ". Code Phase correction [samples] = " << delay_correction_samples << ". PULL-IN Code Phase [samples] = " << d_acq_code_phase_samples; - multicorrelator_fpga->set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_local_code_shift_chips, d_acquisition_gnss_synchro->PRN); + //multicorrelator_fpga->set_local_code_and_taps(d_code_length_chips, d_local_code_shift_chips, d_acquisition_gnss_synchro->PRN); + multicorrelator_fpga->set_local_code_and_taps(d_local_code_shift_chips, d_prompt_data_shift, d_acquisition_gnss_synchro->PRN); d_pull_in = 1; // enable tracking pull-in and d_state at the end to avoid general work from starting pull-in before the start tracking function is finished d_state = 1; } + dll_pll_veml_tracking_fpga::~dll_pll_veml_tracking_fpga() { + if (signal_type.compare("1C") == 0) + { + volk_gnsssdr_free(d_gps_l1ca_preambles_symbols); + } + if (d_dump_file.is_open()) { try @@ -520,26 +620,19 @@ dll_pll_veml_tracking_fpga::~dll_pll_veml_tracking_fpga() LOG(WARNING) << "Exception in destructor " << ex.what(); } } - if (trk_parameters.dump) + if (d_dump_mat) { - if (d_channel == 0) - { - std::cout << "Writing .mat files ..."; - } save_matfile(); - if (d_channel == 0) - { - std::cout << " done." << std::endl; - } } try { volk_gnsssdr_free(d_local_code_shift_chips); volk_gnsssdr_free(d_correlator_outs); - if (trk_parameters.track_pilot) - { - volk_gnsssdr_free(d_Prompt_Data); - } + volk_gnsssdr_free(d_Prompt_Data); + // if (trk_parameters.track_pilot) + // { + // volk_gnsssdr_free(d_Prompt_Data); + // } delete[] d_Prompt_buffer; multicorrelator_fpga->free(); } @@ -553,8 +646,8 @@ dll_pll_veml_tracking_fpga::~dll_pll_veml_tracking_fpga() bool dll_pll_veml_tracking_fpga::acquire_secondary() { // ******* preamble correlation ******** - int corr_value = 0; - for (unsigned int i = 0; i < d_secondary_code_length; i++) + int32_t corr_value = 0; + for (uint32_t i = 0; i < d_secondary_code_length; i++) { if (d_Prompt_buffer_deque.at(i).real() < 0.0) // symbols clipping { @@ -580,7 +673,8 @@ bool dll_pll_veml_tracking_fpga::acquire_secondary() } } - if (abs(corr_value) == static_cast(d_secondary_code_length)) + // if (abs(corr_value) == d_secondary_code_length) + if (abs(corr_value) == static_cast(d_secondary_code_length)) { return true; } @@ -593,6 +687,7 @@ bool dll_pll_veml_tracking_fpga::acquire_secondary() bool dll_pll_veml_tracking_fpga::cn0_and_tracking_lock_status(double coh_integration_time_s) { + //printf("kkkkkkkkkkkkk d_cn0_estimation_counter = %d\n", d_cn0_estimation_counter); // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### if (d_cn0_estimation_counter < trk_parameters.cn0_samples) { @@ -603,6 +698,7 @@ bool dll_pll_veml_tracking_fpga::cn0_and_tracking_lock_status(double coh_integra } else { + //printf("KKKKKKKKKKK checking count fail ...\n"); d_cn0_estimation_counter = 0; // Code lock indicator d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, trk_parameters.cn0_samples, coh_integration_time_s); @@ -674,7 +770,8 @@ void dll_pll_veml_tracking_fpga::run_dll_pll() void dll_pll_veml_tracking_fpga::clear_tracking_vars() { std::fill_n(d_correlator_outs, d_n_correlator_taps, gr_complex(0.0, 0.0)); - if (trk_parameters.track_pilot) *d_Prompt_Data = gr_complex(0.0, 0.0); + //if (trk_parameters.track_pilot) *d_Prompt_Data = gr_complex(0.0, 0.0); + if (trk_parameters.track_pilot) d_Prompt_Data[0] = gr_complex(0.0, 0.0); d_carr_error_hz = 0.0; d_carr_error_filt_hz = 0.0; d_code_error_chips = 0.0; @@ -696,7 +793,9 @@ void dll_pll_veml_tracking_fpga::update_tracking_vars() // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation T_prn_samples = T_prn_seconds * trk_parameters.fs_in; K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * trk_parameters.fs_in; - d_next_prn_length_samples = round(K_blk_samples); + //d_next_prn_length_samples = round(K_blk_samples); + d_next_prn_length_samples = static_cast(std::floor(K_blk_samples)); // round to a discrete number of samples + //################### PLL COMMANDS ################################################# // carrier phase step (NCO phase increment per sample) [rads/sample] d_carrier_phase_step_rad = PI_2 * d_carrier_doppler_hz / trk_parameters.fs_in; @@ -712,6 +811,10 @@ void dll_pll_veml_tracking_fpga::update_tracking_vars() // remnant code phase [chips] d_rem_code_phase_samples = K_blk_samples - static_cast(d_current_prn_length_samples); // rounding error < 1 sample d_rem_code_phase_chips = d_code_freq_chips * d_rem_code_phase_samples / trk_parameters.fs_in; + //printf("lll d_code_freq_chips = %f\n", d_code_freq_chips); + //printf("lll d_rem_code_phase_samples = %f\n", d_rem_code_phase_samples); + //printf("lll trk_parameters.fs_in = %f\n", trk_parameters.fs_in); + //printf("lll d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips); } @@ -768,7 +871,7 @@ void dll_pll_veml_tracking_fpga::save_correlation_results() void dll_pll_veml_tracking_fpga::log_data(bool integrating) { - if (trk_parameters.dump) + if (d_dump) { // Dump results to file float prompt_I; @@ -776,6 +879,7 @@ void dll_pll_veml_tracking_fpga::log_data(bool integrating) float tmp_VE, tmp_E, tmp_P, tmp_L, tmp_VL; float tmp_float; double tmp_double; + uint64_t tmp_long_int; if (trk_parameters.track_pilot) { if (interchange_iq) @@ -842,7 +946,8 @@ void dll_pll_veml_tracking_fpga::log_data(bool integrating) d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + tmp_long_int = d_sample_counter + static_cast(d_current_prn_length_samples); + d_dump_file.write(reinterpret_cast(&tmp_long_int), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_rad; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -872,8 +977,8 @@ void dll_pll_veml_tracking_fpga::log_data(bool integrating) tmp_double = static_cast(d_sample_counter + d_current_prn_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure &e) { @@ -883,19 +988,25 @@ void dll_pll_veml_tracking_fpga::log_data(bool integrating) } -int dll_pll_veml_tracking_fpga::save_matfile() +int32_t dll_pll_veml_tracking_fpga::save_matfile() { // READ DUMP FILE std::ifstream::pos_type size; - int number_of_double_vars = 1; - int number_of_float_vars = 17; - int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + - sizeof(float) * number_of_float_vars + sizeof(unsigned int); + int32_t number_of_double_vars = 1; + int32_t number_of_float_vars = 17; + int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; + std::string dump_filename_ = d_dump_filename; + // add channel number to the filename + dump_filename_.append(std::to_string(d_channel)); + // add extension + dump_filename_.append(".dat"); + std::cout << "Generating .mat file for " << dump_filename_ << std::endl; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { - dump_file.open(trk_parameters.dump_filename.c_str(), std::ios::binary | std::ios::ate); + dump_file.open(dump_filename_.c_str(), std::ios::binary | std::ios::ate); } catch (const std::ifstream::failure &e) { @@ -903,11 +1014,11 @@ int dll_pll_veml_tracking_fpga::save_matfile() return 1; } // count number of epochs and rewind - long int num_epoch = 0; + int64_t num_epoch = 0; if (dump_file.is_open()) { size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); dump_file.seekg(0, std::ios::beg); } else @@ -921,7 +1032,7 @@ int dll_pll_veml_tracking_fpga::save_matfile() float *abs_VL = new float[num_epoch]; float *Prompt_I = new float[num_epoch]; float *Prompt_Q = new float[num_epoch]; - unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch]; + uint64_t *PRN_start_sample_count = new uint64_t[num_epoch]; float *acc_carrier_phase_rad = new float[num_epoch]; float *carrier_doppler_hz = new float[num_epoch]; float *code_freq_chips = new float[num_epoch]; @@ -933,13 +1044,13 @@ int dll_pll_veml_tracking_fpga::save_matfile() float *carrier_lock_test = new float[num_epoch]; float *aux1 = new float[num_epoch]; double *aux2 = new double[num_epoch]; - unsigned int *PRN = new unsigned int[num_epoch]; + uint32_t *PRN = new uint32_t[num_epoch]; try { if (dump_file.is_open()) { - for (long int i = 0; i < num_epoch; i++) + for (int64_t i = 0; i < num_epoch; i++) { dump_file.read(reinterpret_cast(&abs_VE[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); @@ -948,7 +1059,7 @@ int dll_pll_veml_tracking_fpga::save_matfile() dump_file.read(reinterpret_cast(&abs_VL[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(uint64_t)); dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(float)); dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(float)); dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(float)); @@ -960,7 +1071,7 @@ int dll_pll_veml_tracking_fpga::save_matfile() dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(float)); dump_file.read(reinterpret_cast(&aux1[i]), sizeof(float)); dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(uint32_t)); } } dump_file.close(); @@ -994,11 +1105,11 @@ int dll_pll_veml_tracking_fpga::save_matfile() // WRITE MAT FILE mat_t *matfp; matvar_t *matvar; - std::string filename = trk_parameters.dump_filename; + std::string filename = dump_filename_; filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (reinterpret_cast(matfp) != NULL) + if (reinterpret_cast(matfp) != NULL) { size_t dims[2] = {1, static_cast(num_epoch)}; matvar = Mat_VarCreate("abs_VE", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_VE, 0); @@ -1105,23 +1216,28 @@ int dll_pll_veml_tracking_fpga::save_matfile() return 0; } -void dll_pll_veml_tracking_fpga::set_channel(unsigned int channel) + +void dll_pll_veml_tracking_fpga::set_channel(uint32_t channel) { d_channel = channel; multicorrelator_fpga->set_channel(d_channel); LOG(INFO) << "Tracking Channel set to " << d_channel; // ############# ENABLE DATA FILE LOG ################# - if (trk_parameters.dump) + if (d_dump) { + std::string dump_filename_ = d_dump_filename; + // add channel number to the filename + dump_filename_.append(std::to_string(d_channel)); + // add extension + dump_filename_.append(".dat"); + if (!d_dump_file.is_open()) { try { - trk_parameters.dump_filename.append(boost::lexical_cast(d_channel)); - trk_parameters.dump_filename.append(".dat"); d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); - d_dump_file.open(trk_parameters.dump_filename.c_str(), std::ios::out | std::ios::binary); - LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << trk_parameters.dump_filename.c_str(); + d_dump_file.open(dump_filename_.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << dump_filename_.c_str(); } catch (const std::ifstream::failure &e) { @@ -1137,16 +1253,16 @@ void dll_pll_veml_tracking_fpga::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) d_acquisition_gnss_synchro = p_gnss_synchro; } - -void dll_pll_veml_tracking_fpga::reset(void) +void dll_pll_veml_tracking_fpga::stop_tracking() { - multicorrelator_fpga->unlock_channel(); + gr::thread::scoped_lock l(d_setlock); + d_state = 0; } - int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), - gr_vector_const_void_star &input_items __attribute__((unused)), gr_vector_void_star &output_items) + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { + gr::thread::scoped_lock l(d_setlock); // Block input data and block output stream pointers Gnss_Synchro **out = reinterpret_cast(&output_items[0]); @@ -1160,12 +1276,12 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un { case 0: // Standby - Consume samples at full throttle, do nothing { - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; + current_synchro_data.Tracking_sample_counter = 0ULL; // in order to reduce computational workload do not read the sample counter until we start tracking d_sample_counter + d_current_prn_length_samples; current_synchro_data.System = {'G'}; current_synchro_data.correlation_length_ms = 1; break; @@ -1174,10 +1290,17 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un { d_pull_in = 0; multicorrelator_fpga->lock_channel(); - unsigned counter_value = multicorrelator_fpga->read_sample_counter(); - unsigned num_frames = ceil((counter_value - current_synchro_data.Acq_samplestamp_samples - current_synchro_data.Acq_delay_samples) / d_correlation_length_samples); - unsigned absolute_samples_offset = current_synchro_data.Acq_delay_samples + current_synchro_data.Acq_samplestamp_samples + num_frames * d_correlation_length_samples; + uint64_t counter_value = multicorrelator_fpga->read_sample_counter(); + //printf("333333 counter_value = %llu\n", counter_value); + //printf("333333 current_synchro_data.Acq_samplestamp_samples = %d\n", current_synchro_data.Acq_samplestamp_samples); + //printf("333333 current_synchro_data.Acq_delay_samples = %f\n", current_synchro_data.Acq_delay_samples); + //printf("333333 d_correlation_length_samples = %d\n", d_correlation_length_samples); + uint32_t num_frames = ceil((counter_value - current_synchro_data.Acq_samplestamp_samples - current_synchro_data.Acq_delay_samples) / d_correlation_length_samples); + //printf("333333 num_frames = %d\n", num_frames); + uint64_t absolute_samples_offset = static_cast(current_synchro_data.Acq_delay_samples + current_synchro_data.Acq_samplestamp_samples + num_frames * d_correlation_length_samples); + //printf("333333 absolute_samples_offset = %llu\n", absolute_samples_offset); multicorrelator_fpga->set_initial_sample(absolute_samples_offset); + d_absolute_samples_offset = absolute_samples_offset; d_sample_counter = absolute_samples_offset; current_synchro_data.Tracking_sample_counter = absolute_samples_offset; d_sample_counter_next = d_sample_counter; @@ -1189,13 +1312,13 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un case 2: { d_sample_counter = d_sample_counter_next; - d_sample_counter_next = d_sample_counter + d_current_prn_length_samples; + d_sample_counter_next = d_sample_counter + static_cast(d_current_prn_length_samples); // ################# CARRIER WIPEOFF AND CORRELATORS ############################## // perform carrier wipe-off and compute Early, Prompt and Late correlation multicorrelator_fpga->Carrier_wipeoff_multicorrelator_resampler( d_rem_carr_phase_rad, d_carrier_phase_step_rad, - d_rem_code_phase_chips, d_code_phase_step_chips, + d_rem_code_phase_chips * static_cast(d_code_samples_per_chip), d_code_phase_step_chips * static_cast(d_code_samples_per_chip), d_current_prn_length_samples); // Save single correlation step variables @@ -1240,33 +1363,70 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un } else if (d_symbols_per_bit > 1) //Signal does not have secondary code. Search a bit transition by sign change { - if (d_synchonizing) + // if (d_synchonizing) + // { + // if (d_Prompt->real() * d_last_prompt.real() > 0.0) + // { + // d_current_symbol++; + // } + // else if (d_current_symbol > d_symbols_per_bit) + // { + // d_synchonizing = false; + // d_current_symbol = 1; + // } + // else + // { + // d_current_symbol = 1; + // d_last_prompt = *d_Prompt; + // } + // } + // else if (d_last_prompt.real() != 0.0) + // { + // d_current_symbol++; + // if (d_current_symbol == d_symbols_per_bit) next_state = true; + // } + // else + // { + // d_last_prompt = *d_Prompt; + // d_synchonizing = true; + // d_current_symbol = 1; + // } + // } + //=========================================================================================================== + //float current_tracking_time_s = static_cast(d_sample_counter - d_acq_sample_stamp) / trk_parameters.fs_in; + float current_tracking_time_s = static_cast(d_sample_counter - d_absolute_samples_offset) / trk_parameters.fs_in; + if (current_tracking_time_s > 10) { - if (d_Prompt->real() * d_last_prompt.real() > 0.0) + d_symbol_history.push_back(d_Prompt->real()); + //******* preamble correlation ******** + int32_t corr_value = 0; + if ((d_symbol_history.size() == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)) // and (d_make_correlation or !d_flag_frame_sync)) { - d_current_symbol++; + for (uint32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++) + { + if (d_symbol_history.at(i) < 0) // symbols clipping + { + corr_value -= d_gps_l1ca_preambles_symbols[i]; + } + else + { + corr_value += d_gps_l1ca_preambles_symbols[i]; + } + } } - else if (d_current_symbol > d_symbols_per_bit) + if (corr_value == GPS_CA_PREAMBLE_LENGTH_SYMBOLS) { - d_synchonizing = false; - d_current_symbol = 1; + //std::cout << "Preamble detected at tracking!" << std::endl; + next_state = true; } else { - d_current_symbol = 1; - d_last_prompt = *d_Prompt; + next_state = false; } } - else if (d_last_prompt.real() != 0.0) - { - d_current_symbol++; - if (d_current_symbol == d_symbols_per_bit) next_state = true; - } else { - d_last_prompt = *d_Prompt; - d_synchonizing = true; - d_current_symbol = 1; + next_state = false; } } else @@ -1274,6 +1434,42 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un next_state = true; } + // ########### Output the tracking results to Telemetry block ########## + if (interchange_iq) + { + if (trk_parameters.track_pilot) + { + // Note that data and pilot components are in quadrature. I and Q are interchanged + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).imag()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).real()); + } + else + { + current_synchro_data.Prompt_I = static_cast((*d_Prompt).imag()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).real()); + } + } + else + { + if (trk_parameters.track_pilot) + { + // Note that data and pilot components are in quadrature. I and Q are interchanged + current_synchro_data.Prompt_I = static_cast((*d_Prompt_Data).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt_Data).imag()); + } + else + { + current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); + current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); + } + } + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + current_synchro_data.Flag_valid_symbol_output = true; + current_synchro_data.correlation_length_ms = d_correlation_length_ms; + if (next_state) { // reset extended correlator d_VE_accu = gr_complex(0.0, 0.0); @@ -1294,10 +1490,10 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un d_carrier_loop_filter.set_pdi(new_correlation_time); d_code_loop_filter.set_pdi(new_correlation_time); d_state = 3; // next state is the extended correlator integrator - LOG(INFO) << "Enabled " << trk_parameters.extend_correlation_symbols * static_cast(d_code_period * 1000.0) << " ms extended correlator in channel " + LOG(INFO) << "Enabled " << trk_parameters.extend_correlation_symbols * static_cast(d_code_period * 1000.0) << " ms extended correlator in channel " << d_channel << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN); - std::cout << "Enabled " << trk_parameters.extend_correlation_symbols * static_cast(d_code_period * 1000.0) << " ms extended correlator in channel " + std::cout << "Enabled " << trk_parameters.extend_correlation_symbols * static_cast(d_code_period * 1000.0) << " ms extended correlator in channel " << d_channel << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; // Set narrow taps delay values [chips] @@ -1329,14 +1525,14 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un case 3: { d_sample_counter = d_sample_counter_next; - d_sample_counter_next = d_sample_counter + d_current_prn_length_samples; + d_sample_counter_next = d_sample_counter + static_cast(d_current_prn_length_samples); // Fill the acquisition data current_synchro_data = *d_acquisition_gnss_synchro; // perform a correlation step multicorrelator_fpga->Carrier_wipeoff_multicorrelator_resampler( d_rem_carr_phase_rad, d_carrier_phase_step_rad, - d_rem_code_phase_chips, d_code_phase_step_chips, + d_rem_code_phase_chips * static_cast(d_code_samples_per_chip), d_code_phase_step_chips * static_cast(d_code_samples_per_chip), d_current_prn_length_samples); update_tracking_vars(); save_correlation_results(); @@ -1389,13 +1585,13 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un case 4: // narrow tracking { d_sample_counter = d_sample_counter_next; - d_sample_counter_next = d_sample_counter + d_current_prn_length_samples; + d_sample_counter_next = d_sample_counter + static_cast(d_current_prn_length_samples); // perform a correlation step //do_correlation_step(in); multicorrelator_fpga->Carrier_wipeoff_multicorrelator_resampler( d_rem_carr_phase_rad, d_carrier_phase_step_rad, - d_rem_code_phase_chips, d_code_phase_step_chips, + d_rem_code_phase_chips * static_cast(d_code_samples_per_chip), d_code_phase_step_chips * static_cast(d_code_samples_per_chip), d_current_prn_length_samples); save_correlation_results(); @@ -1464,10 +1660,16 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un } if (current_synchro_data.Flag_valid_symbol_output) { - current_synchro_data.fs = static_cast(trk_parameters.fs_in); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; + current_synchro_data.fs = static_cast(trk_parameters.fs_in); + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_current_prn_length_samples); *out[0] = current_synchro_data; return 1; } return 0; } + + +void dll_pll_veml_tracking_fpga::reset(void) +{ + multicorrelator_fpga->unlock_channel(); +} diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h index 09efbd9b7..91e34d400 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.h @@ -13,7 +13,7 @@ * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -31,7 +31,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ @@ -39,51 +39,25 @@ #ifndef GNSS_SDR_DLL_PLL_VEML_TRACKING_FPGA_H #define GNSS_SDR_DLL_PLL_VEML_TRACKING_FPGA_H -#include "fpga_multicorrelator.h" +#include "dll_pll_conf_fpga.h" #include "gnss_synchro.h" #include "tracking_2nd_DLL_filter.h" #include "tracking_2nd_PLL_filter.h" +#include "fpga_multicorrelator.h" #include #include #include #include - - -typedef struct -{ - /* DLL/PLL tracking configuration */ - double fs_in; - unsigned int vector_length; - bool dump; - std::string dump_filename; - float pll_bw_hz; - float dll_bw_hz; - float pll_bw_narrow_hz; - float dll_bw_narrow_hz; - float early_late_space_chips; - float very_early_late_space_chips; - float early_late_space_narrow_chips; - float very_early_late_space_narrow_chips; - int extend_correlation_symbols; - int cn0_samples; - int cn0_min; - int max_lock_fail; - double carrier_lock_th; - bool track_pilot; - char system; - char signal[3]; - std::string device_name; - unsigned int device_base; - unsigned int code_length; - int *ca_codes; -} dllpllconf_fpga_t; +#include +#include +#include "fpga_multicorrelator.h" class dll_pll_veml_tracking_fpga; typedef boost::shared_ptr dll_pll_veml_tracking_fpga_sptr; -dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(dllpllconf_fpga_t conf_); +dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_); /*! @@ -94,19 +68,20 @@ class dll_pll_veml_tracking_fpga : public gr::block public: ~dll_pll_veml_tracking_fpga(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro); void start_tracking(); - + void stop_tracking(); int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); void reset(void); private: - friend dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(dllpllconf_fpga_t conf_); + friend dll_pll_veml_tracking_fpga_sptr dll_pll_veml_make_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_); - dll_pll_veml_tracking_fpga(dllpllconf_fpga_t conf_); + dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga &conf_); + void msg_handler_preamble_index(pmt::pmt_t msg); bool cn0_and_tracking_lock_status(double coh_integration_time_s); bool acquire_secondary(); @@ -115,13 +90,14 @@ private: void clear_tracking_vars(); void save_correlation_results(); void log_data(bool integrating); - int save_matfile(); + int32_t save_matfile(); // tracking configuration vars - dllpllconf_fpga_t trk_parameters; + Dll_Pll_Conf_Fpga trk_parameters; + //dllpllconf_fpga_t trk_parameters; bool d_veml; bool d_cloop; - unsigned int d_channel; + uint32_t d_channel; Gnss_Synchro *d_acquisition_gnss_synchro; //Signal parameters @@ -130,21 +106,24 @@ private: double d_signal_carrier_freq; double d_code_period; double d_code_chip_rate; - unsigned int d_secondary_code_length; - unsigned int d_code_length_chips; - unsigned int d_code_samples_per_chip; // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled) - int d_symbols_per_bit; + uint32_t d_secondary_code_length; + uint32_t d_code_length_chips; + uint32_t d_code_samples_per_chip; // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled) + int32_t d_symbols_per_bit; std::string systemName; std::string signal_type; std::string *d_secondary_code_string; std::string signal_pretty_name; + int32_t *d_gps_l1ca_preambles_symbols; + boost::circular_buffer d_symbol_history; + //tracking state machine - int d_state; + int32_t d_state; bool d_synchonizing; //Integration period in samples - int d_correlation_length_ms; - int d_n_correlator_taps; + int32_t d_correlation_length_ms; + int32_t d_n_correlator_taps; float *d_local_code_shift_chips; float *d_prompt_data_shift; std::shared_ptr multicorrelator_fpga; @@ -157,8 +136,8 @@ private: gr_complex *d_Very_Late; bool d_enable_extended_integration; - int d_extend_correlation_symbols_count; - int d_current_symbol; + int32_t d_extend_correlation_symbols_count; + int32_t d_current_symbol; gr_complex d_VE_accu; gr_complex d_E_accu; @@ -199,14 +178,15 @@ private: double T_prn_samples; double K_blk_samples; // PRN period in samples - int d_current_prn_length_samples; + int32_t d_current_prn_length_samples; // processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; + uint64_t d_absolute_samples_offset; // CN0 estimation and lock detector - int d_cn0_estimation_counter; - int d_carrier_lock_fail_counter; + int32_t d_cn0_estimation_counter; + int32_t d_carrier_lock_fail_counter; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; @@ -215,12 +195,15 @@ private: // file dump std::ofstream d_dump_file; + std::string d_dump_filename; + bool d_dump; + bool d_dump_mat; // extra - int d_correlation_length_samples; - int d_next_prn_length_samples; - unsigned long int d_sample_counter_next; - unsigned int d_pull_in = 0; + int32_t d_correlation_length_samples; + int32_t d_next_prn_length_samples; + uint64_t d_sample_counter_next; + uint32_t d_pull_in = 0U; }; #endif //GNSS_SDR_DLL_PLL_VEML_TRACKING_FPGA_H diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc index acb0021c0..ee049869d 100644 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc @@ -60,8 +60,8 @@ using google::LogMessage; galileo_e1_tcp_connector_tracking_cc_sptr galileo_e1_tcp_connector_make_tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -80,14 +80,14 @@ void Galileo_E1_Tcp_Connector_Tracking_cc::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(d_vector_length) * 2; // set the required available samples in each call + ninput_items_required[0] = static_cast(d_vector_length) * 2; // set the required available samples in each call } } Galileo_E1_Tcp_Connector_Tracking_cc::Galileo_E1_Tcp_Connector_Tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz __attribute__((unused)), @@ -123,7 +123,7 @@ Galileo_E1_Tcp_Connector_Tracking_cc::Galileo_E1_Tcp_Connector_Tracking_cc( // correlator outputs (scalar) d_n_correlator_taps = 5; // Very-Early, Early, Prompt, Late, Very-Late d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -155,13 +155,13 @@ Galileo_E1_Tcp_Connector_Tracking_cc::Galileo_E1_Tcp_Connector_Tracking_cc( d_rem_carr_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; + d_sample_counter = 0ULL; d_acq_sample_stamp = 0; d_enable_tracking = false; d_pull_in = false; - d_current_prn_length_samples = static_cast(d_vector_length); + d_current_prn_length_samples = static_cast(d_vector_length); // CN0 estimation and lock detector buffers d_cn0_estimation_counter = 0; @@ -199,8 +199,8 @@ void Galileo_E1_Tcp_Connector_Tracking_cc::start_tracking() 2 * Galileo_E1_CODE_CHIP_RATE_HZ, 0); - multicorrelator_cpu.set_local_code_and_taps(static_cast(2 * Galileo_E1_B_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); - for (int n = 0; n < d_n_correlator_taps; n++) + multicorrelator_cpu.set_local_code_and_taps(static_cast(2 * Galileo_E1_B_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -258,7 +258,7 @@ Galileo_E1_Tcp_Connector_Tracking_cc::~Galileo_E1_Tcp_Connector_Tracking_cc() } -void Galileo_E1_Tcp_Connector_Tracking_cc::set_channel(unsigned int channel) +void Galileo_E1_Tcp_Connector_Tracking_cc::set_channel(uint32_t channel) { d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -319,16 +319,16 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri /* * Signal alignment (skip samples until the incoming signal is aligned with local replica) */ - int samples_offset; + int32_t samples_offset; float acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; + int32_t acq_to_trk_delay_samples; acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; acq_trk_shif_correction_samples = d_current_prn_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(samples_offset); current_synchro_data.fs = d_fs_in; *out[0] = current_synchro_data; - d_sample_counter = d_sample_counter + samples_offset; //count for the processed samples + d_sample_counter = d_sample_counter + static_cast(samples_offset); //count for the processed samples d_pull_in = false; consume_each(samples_offset); //shift input to perform alignment with local replica return 1; @@ -444,7 +444,7 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri current_synchro_data.Prompt_I = static_cast((*d_Prompt).real()); current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); // Tracking_timestamp_secs is aligned with the PRN start sample - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_current_prn_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample current_synchro_data.Carrier_phase_rads = static_cast(d_acc_carrier_phase_rad); @@ -458,7 +458,7 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri *d_Early = gr_complex(0, 0); *d_Prompt = gr_complex(0, 0); *d_Late = gr_complex(0, 0); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_current_prn_length_samples); //! When tracking is disabled an array of 1's is sent to maintain the TCP connection boost::array tx_variables_array = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}}; d_tcp_com.send_receive_tcp_packet_galileo_e1(tx_variables_array, &tcp_data); @@ -498,7 +498,7 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_rad; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -528,8 +528,8 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri double tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.h index 1e92e711a..724207ab3 100644 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.h @@ -55,7 +55,7 @@ typedef boost::shared_ptr galileo_e1_tcp_c galileo_e1_tcp_connector_tracking_cc_sptr galileo_e1_tcp_connector_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -73,7 +73,7 @@ class Galileo_E1_Tcp_Connector_Tracking_cc : public gr::block public: ~Galileo_E1_Tcp_Connector_Tracking_cc(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro); void start_tracking(); @@ -85,7 +85,7 @@ public: private: friend galileo_e1_tcp_connector_tracking_cc_sptr galileo_e1_tcp_connector_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -95,7 +95,7 @@ private: size_t port_ch0); Galileo_E1_Tcp_Connector_Tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -109,16 +109,16 @@ private: void update_local_carrier(); // tracking configuration vars - unsigned int d_vector_length; + uint32_t d_vector_length; bool d_dump; Gnss_Synchro *d_acquisition_gnss_synchro; - unsigned int d_channel; + uint32_t d_channel; - long d_fs_in; + int64_t d_fs_in; - int d_correlation_length_samples; - int d_n_correlator_taps; + int32_t d_correlation_length_samples; + int32_t d_n_correlator_taps; float d_early_late_spc_chips; float d_very_early_late_spc_chips; @@ -152,25 +152,25 @@ private: float d_code_phase_samples; size_t d_port_ch0; size_t d_port; - int d_listen_connection; + int32_t d_listen_connection; float d_control_id; tcp_communication d_tcp_com; //PRN period in samples - int d_current_prn_length_samples; - int d_next_prn_length_samples; + int32_t d_current_prn_length_samples; + int32_t d_next_prn_length_samples; //processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; + int32_t d_cn0_estimation_counter; gr_complex *d_Prompt_buffer; float d_carrier_lock_test; float d_CN0_SNV_dB_Hz; float d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + int32_t d_carrier_lock_fail_counter; // control vars bool d_enable_tracking; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc index 7e71810f9..2689e382f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -1,5 +1,5 @@ /*! - * \file glonass_l1_ca_dll_pll_c_aid_tracking_cc.h + * \file glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com @@ -62,15 +62,15 @@ using google::LogMessage; glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr glonass_l1_ca_dll_pll_c_aid_make_tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) { return glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr(new glonass_l1_ca_dll_pll_c_aid_tracking_cc( @@ -83,7 +83,7 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_cc::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call } } @@ -102,15 +102,15 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_cc::msg_handler_preamble_index(pmt::pm glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) : gr::block("glonass_l1_ca_dll_pll_c_aid_tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { @@ -126,7 +126,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc d_fs_in = fs_in; d_vector_length = vector_length; d_dump_filename = dump_filename; - d_correlation_length_samples = static_cast(d_vector_length); + d_correlation_length_samples = static_cast(d_vector_length); // Initialize tracking ========================================== d_pll_bw_hz = pll_bw_hz; @@ -142,12 +142,12 @@ glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc // Initialization of local code replica // Get space for a vector with the C/A code replica sampled 1x/chip - d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); // correlator outputs (scalar) d_n_correlator_taps = 3; // Early, Prompt, and Late d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -168,7 +168,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc d_rem_carrier_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; //(from trk to tlm) + d_sample_counter = 0ULL; //(from trk to tlm) d_acq_sample_stamp = 0; d_enable_tracking = false; d_pull_in = false; @@ -211,7 +211,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc d_glonass_freq_ch = 0; - //set_min_output_buffer((long int)300); + //set_min_output_buffer((int64_t)300); } @@ -224,9 +224,9 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking() d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; - long int acq_trk_diff_samples; + int64_t acq_trk_diff_samples; double acq_trk_diff_seconds; - acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); // Doppler effect @@ -274,8 +274,8 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking() // generate local reference ALWAYS starting at chip 1 (1 sample per chip) glonass_l1_ca_code_gen_complex(d_ca_code, 0); - multicorrelator_cpu.set_local_code_and_taps(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); - for (int n = 0; n < d_n_correlator_taps; n++) + multicorrelator_cpu.set_local_code_and_taps(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -348,14 +348,14 @@ glonass_l1_ca_dll_pll_c_aid_tracking_cc::~glonass_l1_ca_dll_pll_c_aid_tracking_c } -int glonass_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() +int32_t glonass_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() { // READ DUMP FILE std::ifstream::pos_type size; - int number_of_double_vars = 11; - int number_of_float_vars = 5; - int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + - sizeof(float) * number_of_float_vars + sizeof(unsigned int); + int32_t number_of_double_vars = 11; + int32_t number_of_float_vars = 5; + int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try @@ -368,11 +368,11 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() return 1; } // count number of epochs and rewind - long int num_epoch = 0; + int64_t num_epoch = 0; if (dump_file.is_open()) { size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); dump_file.seekg(0, std::ios::beg); } else @@ -384,7 +384,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() float *abs_L = new float[num_epoch]; float *Prompt_I = new float[num_epoch]; float *Prompt_Q = new float[num_epoch]; - unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch]; + uint64_t *PRN_start_sample_count = new uint64_t[num_epoch]; double *acc_carrier_phase_rad = new double[num_epoch]; double *carrier_doppler_hz = new double[num_epoch]; double *code_freq_chips = new double[num_epoch]; @@ -396,20 +396,20 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() double *carrier_lock_test = new double[num_epoch]; double *aux1 = new double[num_epoch]; double *aux2 = new double[num_epoch]; - unsigned int *PRN = new unsigned int[num_epoch]; + uint32_t *PRN = new uint32_t[num_epoch]; try { if (dump_file.is_open()) { - for (long int i = 0; i < num_epoch; i++) + for (int64_t i = 0; i < num_epoch; i++) { dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(uint64_t)); dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); @@ -421,7 +421,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(uint32_t)); } } dump_file.close(); @@ -457,7 +457,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (reinterpret_cast(matfp) != NULL) + if (reinterpret_cast(matfp) != NULL) { size_t dims[2] = {1, static_cast(num_epoch)}; matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); @@ -555,7 +555,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() } -void glonass_l1_ca_dll_pll_c_aid_tracking_cc::set_channel(unsigned int channel) +void glonass_l1_ca_dll_pll_c_aid_tracking_cc::set_channel(uint32_t channel) { d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -609,14 +609,14 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at // Receiver signal alignment if (d_pull_in == true) { - int samples_offset; + int32_t samples_offset; double acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; + int32_t acq_to_trk_delay_samples; acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; acq_trk_shif_correction_samples = d_correlation_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_correlation_length_samples)); samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; - d_sample_counter += samples_offset; // count for the processed samples + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(samples_offset); + d_sample_counter += static_cast(samples_offset); // count for the processed samples d_pull_in = false; d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * samples_offset / GLONASS_TWO_PI; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_cycles * GLONASS_TWO_PI; @@ -642,7 +642,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at d_P_history.push_back(d_correlator_outs[1]); // save prompt output d_L_history.push_back(d_correlator_outs[2]); // save late output - if (static_cast(d_P_history.size()) > d_extend_correlation_ms) + if (static_cast(d_P_history.size()) > d_extend_correlation_ms) { d_E_history.pop_front(); d_P_history.pop_front(); @@ -652,7 +652,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at bool enable_dll_pll; if (d_enable_extended_integration == true) { - long int symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); + int64_t symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); if (symbol_diff > 0 and symbol_diff % d_extend_correlation_ms == 0) { // compute coherent integration and enable tracking loop @@ -661,7 +661,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at d_correlator_outs[0] = gr_complex(0.0, 0.0); d_correlator_outs[1] = gr_complex(0.0, 0.0); d_correlator_outs[2] = gr_complex(0.0, 0.0); - for (int n = 0; n < d_extend_correlation_ms; n++) + for (int32_t n = 0; n < d_extend_correlation_ms; n++) { d_correlator_outs[0] += d_E_history.at(n); d_correlator_outs[1] += d_P_history.at(n); @@ -691,7 +691,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at double T_chip_seconds = 1.0 / d_code_freq_chips; double T_prn_seconds = T_chip_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS; double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); - int K_prn_samples = round(T_prn_samples); + int32_t K_prn_samples = round(T_prn_samples); double K_T_prn_error_samples = K_prn_samples - T_prn_samples; d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples; @@ -815,7 +815,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at // ########### Output the tracking data to navigation and PVT ########## current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; @@ -834,7 +834,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at { current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; // todo: project the carrier doppler @@ -843,13 +843,13 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at } else { - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } current_synchro_data.System = {'R'}; - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); } //assign the GNURadio block output data current_synchro_data.fs = d_fs_in; @@ -880,7 +880,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_cycles * GLONASS_TWO_PI; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -910,8 +910,8 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at double tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure *e) { diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h index 9c692d726..a5e4dfcf9 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h @@ -58,14 +58,14 @@ typedef boost::shared_ptr glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr glonass_l1_ca_dll_pll_c_aid_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); @@ -77,7 +77,7 @@ class glonass_l1_ca_dll_pll_c_aid_tracking_cc : public gr::block public: ~glonass_l1_ca_dll_pll_c_aid_tracking_cc(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); void start_tracking(); @@ -89,39 +89,39 @@ public: private: friend glonass_l1_ca_dll_pll_c_aid_tracking_cc_sptr glonass_l1_ca_dll_pll_c_aid_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); glonass_l1_ca_dll_pll_c_aid_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); // tracking configuration vars - unsigned int d_vector_length; + uint32_t d_vector_length; bool d_dump; Gnss_Synchro* d_acquisition_gnss_synchro; - unsigned int d_channel; + uint32_t d_channel; - long d_fs_in; + int64_t d_fs_in; double d_glonass_freq_ch; double d_early_late_spc_chips; - int d_n_correlator_taps; + int32_t d_n_correlator_taps; gr_complex* d_ca_code; float* d_local_code_shift_chips; @@ -132,7 +132,7 @@ private: double d_rem_code_phase_samples; double d_rem_code_phase_chips; double d_rem_carrier_phase_rad; - int d_rem_code_phase_integer_samples; + int32_t d_rem_code_phase_integer_samples; // PLL and DLL filter library //Tracking_2nd_DLL_filter d_code_loop_filter; @@ -167,25 +167,25 @@ private: std::deque d_P_history; std::deque d_L_history; double d_preamble_timestamp_s; - int d_extend_correlation_ms; + int32_t d_extend_correlation_ms; bool d_enable_extended_integration; bool d_preamble_synchronized; void msg_handler_preamble_index(pmt::pmt_t msg); //Integration period in samples - int d_correlation_length_samples; + int32_t d_correlation_length_samples; //processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; + int32_t d_cn0_estimation_counter; gr_complex* d_Prompt_buffer; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + int32_t d_carrier_lock_fail_counter; // control vars bool d_enable_tracking; @@ -198,7 +198,7 @@ private: std::map systemName; std::string sys; - int save_matfile(); + int32_t save_matfile(); }; #endif //GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_CC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc index c00de2486..1c0b45b9c 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -37,7 +37,6 @@ */ #include "glonass_l1_ca_dll_pll_c_aid_tracking_sc.h" -#include "gnss_synchro.h" #include "glonass_l1_signal_processing.h" #include "GLONASS_L1_L2_CA.h" #include "tracking_discriminators.h" @@ -61,15 +60,15 @@ using google::LogMessage; glonass_l1_ca_dll_pll_c_aid_tracking_sc_sptr glonass_l1_ca_dll_pll_c_aid_make_tracking_sc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) { return glonass_l1_ca_dll_pll_c_aid_tracking_sc_sptr(new glonass_l1_ca_dll_pll_c_aid_tracking_sc( @@ -82,7 +81,7 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_sc::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call } } @@ -100,15 +99,15 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_sc::msg_handler_preamble_index(pmt::pm } glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) : gr::block("glonass_l1_ca_dll_pll_c_aid_tracking_sc", gr::io_signature::make(1, 1, sizeof(lv_16sc_t)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { @@ -122,7 +121,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc d_fs_in = fs_in; d_vector_length = vector_length; d_dump_filename = dump_filename; - d_correlation_length_samples = static_cast(d_vector_length); + d_correlation_length_samples = static_cast(d_vector_length); // Initialize tracking ========================================== d_pll_bw_hz = pll_bw_hz; @@ -138,14 +137,14 @@ glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc // Initialization of local code replica // Get space for a vector with the C/A code replica sampled 1x/chip - d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - d_ca_code_16sc = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_ca_code_16sc = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); // correlator outputs (scalar) d_n_correlator_taps = 3; // Early, Prompt, and Late d_correlator_outs_16sc = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs_16sc[n] = lv_cmake(0, 0); } @@ -167,7 +166,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc d_rem_carrier_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; //(from trk to tlm) + d_sample_counter = 0ULL; //(from trk to tlm) d_acq_sample_stamp = 0; d_enable_tracking = false; d_pull_in = false; @@ -208,7 +207,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc d_carrier_doppler_old_hz = 0.0; d_glonass_freq_ch = 0; - //set_min_output_buffer((long int)300); + //set_min_output_buffer((int64_t)300); } @@ -221,9 +220,9 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_sc::start_tracking() d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; - long int acq_trk_diff_samples; + int64_t acq_trk_diff_samples; double acq_trk_diff_seconds; - acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); // Doppler effect @@ -268,10 +267,10 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_sc::start_tracking() // generate local reference ALWAYS starting at chip 1 (1 sample per chip) glonass_l1_ca_code_gen_complex(d_ca_code, 0); - volk_gnsssdr_32fc_convert_16ic(d_ca_code_16sc, d_ca_code, static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS)); + volk_gnsssdr_32fc_convert_16ic(d_ca_code_16sc, d_ca_code, static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS)); - multicorrelator_cpu_16sc.set_local_code_and_taps(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code_16sc, d_local_code_shift_chips); - for (int n = 0; n < d_n_correlator_taps; n++) + multicorrelator_cpu_16sc.set_local_code_and_taps(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code_16sc, d_local_code_shift_chips); + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs_16sc[n] = lv_16sc_t(0, 0); } @@ -303,14 +302,14 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_sc::start_tracking() } -int glonass_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() +int32_t glonass_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() { // READ DUMP FILE std::ifstream::pos_type size; - int number_of_double_vars = 11; - int number_of_float_vars = 5; - int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + - sizeof(float) * number_of_float_vars + sizeof(unsigned int); + int32_t number_of_double_vars = 11; + int32_t number_of_float_vars = 5; + int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try @@ -323,11 +322,11 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() return 1; } // count number of epochs and rewind - long int num_epoch = 0; + int64_t num_epoch = 0; if (dump_file.is_open()) { size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); dump_file.seekg(0, std::ios::beg); } else @@ -339,7 +338,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() float *abs_L = new float[num_epoch]; float *Prompt_I = new float[num_epoch]; float *Prompt_Q = new float[num_epoch]; - unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch]; + uint64_t *PRN_start_sample_count = new uint64_t[num_epoch]; double *acc_carrier_phase_rad = new double[num_epoch]; double *carrier_doppler_hz = new double[num_epoch]; double *code_freq_chips = new double[num_epoch]; @@ -351,20 +350,20 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() double *carrier_lock_test = new double[num_epoch]; double *aux1 = new double[num_epoch]; double *aux2 = new double[num_epoch]; - unsigned int *PRN = new unsigned int[num_epoch]; + uint32_t *PRN = new uint32_t[num_epoch]; try { if (dump_file.is_open()) { - for (long int i = 0; i < num_epoch; i++) + for (int64_t i = 0; i < num_epoch; i++) { dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(uint64_t)); dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); @@ -376,7 +375,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(uint32_t)); } } dump_file.close(); @@ -412,7 +411,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (reinterpret_cast(matfp) != NULL) + if (reinterpret_cast(matfp) != NULL) { size_t dims[2] = {1, static_cast(num_epoch)}; matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); @@ -547,7 +546,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_sc::~glonass_l1_ca_dll_pll_c_aid_tracking_s } -void glonass_l1_ca_dll_pll_c_aid_tracking_sc::set_channel(unsigned int channel) +void glonass_l1_ca_dll_pll_c_aid_tracking_sc::set_channel(uint32_t channel) { d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -601,14 +600,14 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at // Receiver signal alignment if (d_pull_in == true) { - int samples_offset; + int32_t samples_offset; double acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; + int32_t acq_to_trk_delay_samples; acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; acq_trk_shif_correction_samples = d_correlation_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_correlation_length_samples)); samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; - d_sample_counter += samples_offset; // count for the processed samples + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(samples_offset); + d_sample_counter += static_cast(samples_offset); // count for the processed samples d_pull_in = false; d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * samples_offset / GLONASS_TWO_PI; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_cycles * GLONASS_TWO_PI; @@ -634,7 +633,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at d_P_history.push_back(d_correlator_outs_16sc[1]); // save prompt output d_L_history.push_back(d_correlator_outs_16sc[2]); // save late output - if (static_cast(d_P_history.size()) > d_extend_correlation_ms) + if (static_cast(d_P_history.size()) > d_extend_correlation_ms) { d_E_history.pop_front(); d_P_history.pop_front(); @@ -644,7 +643,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at bool enable_dll_pll; if (d_enable_extended_integration == true) { - long int symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); + int64_t symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); if (symbol_diff > 0 and symbol_diff % d_extend_correlation_ms == 0) { // compute coherent integration and enable tracking loop @@ -653,7 +652,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at d_correlator_outs_16sc[0] = lv_cmake(0, 0); d_correlator_outs_16sc[1] = lv_cmake(0, 0); d_correlator_outs_16sc[2] = lv_cmake(0, 0); - for (int n = 0; n < d_extend_correlation_ms; n++) + for (int32_t n = 0; n < d_extend_correlation_ms; n++) { d_correlator_outs_16sc[0] += d_E_history.at(n); d_correlator_outs_16sc[1] += d_P_history.at(n); @@ -682,7 +681,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at double T_chip_seconds = 1.0 / d_code_freq_chips; double T_prn_seconds = T_chip_seconds * GLONASS_L1_CA_CODE_LENGTH_CHIPS; double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); - int K_prn_samples = round(T_prn_samples); + int32_t K_prn_samples = round(T_prn_samples); double K_T_prn_error_samples = K_prn_samples - T_prn_samples; d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples; @@ -806,7 +805,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at current_synchro_data.Prompt_I = static_cast((d_correlator_outs_16sc[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs_16sc[1]).imag()); // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!) - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; @@ -825,7 +824,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at { current_synchro_data.Prompt_I = static_cast((d_correlator_outs_16sc[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs_16sc[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; // todo: project the carrier doppler @@ -834,13 +833,13 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at } else { - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs_16sc[n] = lv_cmake(0, 0); } current_synchro_data.System = {'R'}; - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); } current_synchro_data.fs = d_fs_in; *out[0] = current_synchro_data; @@ -870,7 +869,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_cycles * GLONASS_TWO_PI; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -900,8 +899,8 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at double tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure *e) { diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h index d91066ab5..83fbe4007 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h @@ -59,14 +59,14 @@ typedef boost::shared_ptr glonass_l1_ca_dll_pll_c_aid_tracking_sc_sptr glonass_l1_ca_dll_pll_c_aid_make_tracking_sc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); @@ -78,7 +78,7 @@ class glonass_l1_ca_dll_pll_c_aid_tracking_sc : public gr::block public: ~glonass_l1_ca_dll_pll_c_aid_tracking_sc(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); void start_tracking(); @@ -90,39 +90,39 @@ public: private: friend glonass_l1_ca_dll_pll_c_aid_tracking_sc_sptr glonass_l1_ca_dll_pll_c_aid_make_tracking_sc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); glonass_l1_ca_dll_pll_c_aid_tracking_sc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); // tracking configuration vars - unsigned int d_vector_length; + uint32_t d_vector_length; bool d_dump; Gnss_Synchro* d_acquisition_gnss_synchro; - unsigned int d_channel; + uint32_t d_channel; - long d_fs_in; - long d_glonass_freq_ch; + int64_t d_fs_in; + int64_t d_glonass_freq_ch; double d_early_late_spc_chips; - int d_n_correlator_taps; + int32_t d_n_correlator_taps; gr_complex* d_ca_code; lv_16sc_t* d_ca_code_16sc; @@ -136,7 +136,7 @@ private: double d_rem_code_phase_samples; double d_rem_code_phase_chips; double d_rem_carrier_phase_rad; - int d_rem_code_phase_integer_samples; + int32_t d_rem_code_phase_integer_samples; // PLL and DLL filter library Tracking_2nd_DLL_filter d_code_loop_filter; @@ -163,7 +163,7 @@ private: double d_carr_phase_error_secs_Ti; double d_code_error_chips_Ti; double d_preamble_timestamp_s; - int d_extend_correlation_ms; + int32_t d_extend_correlation_ms; bool d_enable_extended_integration; bool d_preamble_synchronized; double d_code_error_filt_chips_s; @@ -176,19 +176,19 @@ private: std::deque d_L_history; //Integration period in samples - int d_correlation_length_samples; + int32_t d_correlation_length_samples; //processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; + int32_t d_cn0_estimation_counter; gr_complex* d_Prompt_buffer; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + int32_t d_carrier_lock_fail_counter; // control vars bool d_enable_tracking; @@ -201,7 +201,7 @@ private: std::map systemName; std::string sys; - int save_matfile(); + int32_t save_matfile(); }; #endif //GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_SC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc index 2d25c448e..2050d0f1f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc @@ -59,8 +59,8 @@ using google::LogMessage; glonass_l1_ca_dll_pll_tracking_cc_sptr glonass_l1_ca_dll_pll_make_tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -77,14 +77,14 @@ void Glonass_L1_Ca_Dll_Pll_Tracking_cc::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call } } Glonass_L1_Ca_Dll_Pll_Tracking_cc::Glonass_L1_Ca_Dll_Pll_Tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -100,7 +100,7 @@ Glonass_L1_Ca_Dll_Pll_Tracking_cc::Glonass_L1_Ca_Dll_Pll_Tracking_cc( d_vector_length = vector_length; d_dump_filename = dump_filename; - d_current_prn_length_samples = static_cast(d_vector_length); + d_current_prn_length_samples = static_cast(d_vector_length); // Initialize tracking ========================================== d_code_loop_filter.set_DLL_BW(dll_bw_hz); @@ -111,12 +111,12 @@ Glonass_L1_Ca_Dll_Pll_Tracking_cc::Glonass_L1_Ca_Dll_Pll_Tracking_cc( // Initialization of local code replica // Get space for a vector with the C/A code replica sampled 1x/chip - d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); // correlator outputs (scalar) d_n_correlator_taps = 3; // Early, Prompt, and Late d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -137,7 +137,7 @@ Glonass_L1_Ca_Dll_Pll_Tracking_cc::Glonass_L1_Ca_Dll_Pll_Tracking_cc( d_rem_carr_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; + d_sample_counter = 0ULL; //d_sample_counter_seconds = 0; d_acq_sample_stamp = 0; @@ -182,9 +182,9 @@ void Glonass_L1_Ca_Dll_Pll_Tracking_cc::start_tracking() d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; - long int acq_trk_diff_samples; + int64_t acq_trk_diff_samples; double acq_trk_diff_seconds; - acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); // Doppler effect @@ -229,8 +229,8 @@ void Glonass_L1_Ca_Dll_Pll_Tracking_cc::start_tracking() // generate local reference ALWAYS starting at chip 1 (1 sample per chip) glonass_l1_ca_code_gen_complex(d_ca_code, 0); - multicorrelator_cpu.set_local_code_and_taps(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); - for (int n = 0; n < d_n_correlator_taps; n++) + multicorrelator_cpu.set_local_code_and_taps(static_cast(GLONASS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -300,14 +300,14 @@ Glonass_L1_Ca_Dll_Pll_Tracking_cc::~Glonass_L1_Ca_Dll_Pll_Tracking_cc() } -int Glonass_L1_Ca_Dll_Pll_Tracking_cc::save_matfile() +int32_t Glonass_L1_Ca_Dll_Pll_Tracking_cc::save_matfile() { // READ DUMP FILE std::ifstream::pos_type size; - int number_of_double_vars = 11; - int number_of_float_vars = 5; - int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + - sizeof(float) * number_of_float_vars + sizeof(unsigned int); + int32_t number_of_double_vars = 11; + int32_t number_of_float_vars = 5; + int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try @@ -320,11 +320,11 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::save_matfile() return 1; } // count number of epochs and rewind - long int num_epoch = 0; + int64_t num_epoch = 0; if (dump_file.is_open()) { size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); dump_file.seekg(0, std::ios::beg); } else @@ -336,7 +336,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::save_matfile() float *abs_L = new float[num_epoch]; float *Prompt_I = new float[num_epoch]; float *Prompt_Q = new float[num_epoch]; - unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch]; + uint64_t *PRN_start_sample_count = new uint64_t[num_epoch]; double *acc_carrier_phase_rad = new double[num_epoch]; double *carrier_doppler_hz = new double[num_epoch]; double *code_freq_chips = new double[num_epoch]; @@ -348,20 +348,20 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::save_matfile() double *carrier_lock_test = new double[num_epoch]; double *aux1 = new double[num_epoch]; double *aux2 = new double[num_epoch]; - unsigned int *PRN = new unsigned int[num_epoch]; + uint32_t *PRN = new uint32_t[num_epoch]; try { if (dump_file.is_open()) { - for (long int i = 0; i < num_epoch; i++) + for (int64_t i = 0; i < num_epoch; i++) { dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(uint64_t)); dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); @@ -373,7 +373,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::save_matfile() dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(uint32_t)); } } dump_file.close(); @@ -409,7 +409,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::save_matfile() filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (reinterpret_cast(matfp) != NULL) + if (reinterpret_cast(matfp) != NULL) { size_t dims[2] = {1, static_cast(num_epoch)}; matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); @@ -507,7 +507,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::save_matfile() } -void Glonass_L1_Ca_Dll_Pll_Tracking_cc::set_channel(unsigned int channel) +void Glonass_L1_Ca_Dll_Pll_Tracking_cc::set_channel(uint32_t channel) { d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -562,14 +562,14 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut // Receiver signal alignment if (d_pull_in == true) { - int samples_offset; + int32_t samples_offset; double acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; + int32_t acq_to_trk_delay_samples; acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; acq_trk_shif_correction_samples = d_current_prn_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; - d_sample_counter = d_sample_counter + samples_offset; // count for the processed samples + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(samples_offset); + d_sample_counter = d_sample_counter + static_cast(samples_offset); // count for the processed samples d_pull_in = false; // take into account the carrier cycles accumulated in the pull in signal alignment d_acc_carrier_phase_rad -= d_carrier_doppler_phase_step_rad * samples_offset; @@ -673,7 +673,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut // ########### Output the tracking data to navigation and PVT ########## current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_current_prn_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; @@ -683,12 +683,12 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut } else { - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_current_prn_length_samples); current_synchro_data.System = {'R'}; current_synchro_data.correlation_length_ms = 1; } @@ -722,7 +722,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_rad; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -752,8 +752,8 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut double tmp_double = static_cast(d_sample_counter + d_current_prn_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h index 26adc852a..8f64c5d86 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h @@ -55,7 +55,7 @@ typedef boost::shared_ptr glonass_l1_ca_dll_pll_tracking_cc_sptr glonass_l1_ca_dll_pll_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -71,7 +71,7 @@ class Glonass_L1_Ca_Dll_Pll_Tracking_cc : public gr::block public: ~Glonass_L1_Ca_Dll_Pll_Tracking_cc(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); void start_tracking(); @@ -83,7 +83,7 @@ public: private: friend glonass_l1_ca_dll_pll_tracking_cc_sptr glonass_l1_ca_dll_pll_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -91,7 +91,7 @@ private: float early_late_space_chips); Glonass_L1_Ca_Dll_Pll_Tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -99,14 +99,14 @@ private: float early_late_space_chips); // tracking configuration vars - unsigned int d_vector_length; + uint32_t d_vector_length; bool d_dump; Gnss_Synchro* d_acquisition_gnss_synchro; - unsigned int d_channel; + uint32_t d_channel; - long d_fs_in; - long d_glonass_freq_ch; + int64_t d_fs_in; + int64_t d_glonass_freq_ch; double d_early_late_spc_chips; @@ -123,7 +123,7 @@ private: double d_acq_code_phase_samples; double d_acq_carrier_doppler_hz; // correlator - int d_n_correlator_taps; + int32_t d_n_correlator_taps; gr_complex* d_ca_code; float* d_local_code_shift_chips; gr_complex* d_correlator_outs; @@ -141,19 +141,19 @@ private: double d_code_phase_samples; //PRN period in samples - int d_current_prn_length_samples; + int32_t d_current_prn_length_samples; //processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; + int32_t d_cn0_estimation_counter; gr_complex* d_Prompt_buffer; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + int32_t d_carrier_lock_fail_counter; // control vars bool d_enable_tracking; @@ -166,7 +166,7 @@ private: std::map systemName; std::string sys; - int save_matfile(); + int32_t save_matfile(); }; #endif //GNSS_SDR_GLONASS_L1_CA_DLL_PLL_TRACKING_CC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc index 370366ed4..19c5cca3e 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc @@ -1,5 +1,5 @@ /*! - * \file glonass_l2_ca_dll_pll_c_aid_tracking_cc.h + * \file glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc * \brief Implementation of a code DLL + carrier PLL tracking block * \author Damian Miralles, 2018. dmiralles2009(at)gmail.com * @@ -59,15 +59,15 @@ using google::LogMessage; glonass_l2_ca_dll_pll_c_aid_tracking_cc_sptr glonass_l2_ca_dll_pll_c_aid_make_tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) { return glonass_l2_ca_dll_pll_c_aid_tracking_cc_sptr(new glonass_l2_ca_dll_pll_c_aid_tracking_cc( @@ -80,7 +80,7 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_cc::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call } } @@ -99,15 +99,15 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_cc::msg_handler_preamble_index(pmt::pm glonass_l2_ca_dll_pll_c_aid_tracking_cc::glonass_l2_ca_dll_pll_c_aid_tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) : gr::block("glonass_l2_ca_dll_pll_c_aid_tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { @@ -123,7 +123,7 @@ glonass_l2_ca_dll_pll_c_aid_tracking_cc::glonass_l2_ca_dll_pll_c_aid_tracking_cc d_fs_in = fs_in; d_vector_length = vector_length; d_dump_filename = dump_filename; - d_correlation_length_samples = static_cast(d_vector_length); + d_correlation_length_samples = static_cast(d_vector_length); // Initialize tracking ========================================== d_pll_bw_hz = pll_bw_hz; @@ -139,12 +139,12 @@ glonass_l2_ca_dll_pll_c_aid_tracking_cc::glonass_l2_ca_dll_pll_c_aid_tracking_cc // Initialization of local code replica // Get space for a vector with the C/A code replica sampled 1x/chip - d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); // correlator outputs (scalar) d_n_correlator_taps = 3; // Early, Prompt, and Late d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -165,7 +165,7 @@ glonass_l2_ca_dll_pll_c_aid_tracking_cc::glonass_l2_ca_dll_pll_c_aid_tracking_cc d_rem_carrier_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; //(from trk to tlm) + d_sample_counter = 0ULL; //(from trk to tlm) d_acq_sample_stamp = 0; d_enable_tracking = false; d_pull_in = false; @@ -208,7 +208,7 @@ glonass_l2_ca_dll_pll_c_aid_tracking_cc::glonass_l2_ca_dll_pll_c_aid_tracking_cc d_glonass_freq_ch = 0; - //set_min_output_buffer((long int)300); + //set_min_output_buffer((int64_t)300); } @@ -221,9 +221,9 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_cc::start_tracking() d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; - long int acq_trk_diff_samples; + int64_t acq_trk_diff_samples; double acq_trk_diff_seconds; - acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); // Doppler effect @@ -271,8 +271,8 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_cc::start_tracking() // generate local reference ALWAYS starting at chip 1 (1 sample per chip) glonass_l2_ca_code_gen_complex(d_ca_code, 0); - multicorrelator_cpu.set_local_code_and_taps(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); - for (int n = 0; n < d_n_correlator_taps; n++) + multicorrelator_cpu.set_local_code_and_taps(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -345,14 +345,14 @@ glonass_l2_ca_dll_pll_c_aid_tracking_cc::~glonass_l2_ca_dll_pll_c_aid_tracking_c } -int glonass_l2_ca_dll_pll_c_aid_tracking_cc::save_matfile() +int32_t glonass_l2_ca_dll_pll_c_aid_tracking_cc::save_matfile() { // READ DUMP FILE std::ifstream::pos_type size; - int number_of_double_vars = 11; - int number_of_float_vars = 5; - int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + - sizeof(float) * number_of_float_vars + sizeof(unsigned int); + int32_t number_of_double_vars = 11; + int32_t number_of_float_vars = 5; + int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try @@ -365,11 +365,11 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::save_matfile() return 1; } // count number of epochs and rewind - long int num_epoch = 0; + int64_t num_epoch = 0; if (dump_file.is_open()) { size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); dump_file.seekg(0, std::ios::beg); } else @@ -381,7 +381,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::save_matfile() float *abs_L = new float[num_epoch]; float *Prompt_I = new float[num_epoch]; float *Prompt_Q = new float[num_epoch]; - unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch]; + uint64_t *PRN_start_sample_count = new uint64_t[num_epoch]; double *acc_carrier_phase_rad = new double[num_epoch]; double *carrier_doppler_hz = new double[num_epoch]; double *code_freq_chips = new double[num_epoch]; @@ -393,20 +393,20 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::save_matfile() double *carrier_lock_test = new double[num_epoch]; double *aux1 = new double[num_epoch]; double *aux2 = new double[num_epoch]; - unsigned int *PRN = new unsigned int[num_epoch]; + uint32_t *PRN = new uint32_t[num_epoch]; try { if (dump_file.is_open()) { - for (long int i = 0; i < num_epoch; i++) + for (int64_t i = 0; i < num_epoch; i++) { dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(uint64_t)); dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); @@ -418,7 +418,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::save_matfile() dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(uint32_t)); } } dump_file.close(); @@ -454,7 +454,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::save_matfile() filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (reinterpret_cast(matfp) != NULL) + if (reinterpret_cast(matfp) != NULL) { size_t dims[2] = {1, static_cast(num_epoch)}; matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); @@ -552,7 +552,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::save_matfile() } -void glonass_l2_ca_dll_pll_c_aid_tracking_cc::set_channel(unsigned int channel) +void glonass_l2_ca_dll_pll_c_aid_tracking_cc::set_channel(uint32_t channel) { d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -606,14 +606,14 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at // Receiver signal alignment if (d_pull_in == true) { - int samples_offset; + int32_t samples_offset; double acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; + int32_t acq_to_trk_delay_samples; acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; acq_trk_shif_correction_samples = d_correlation_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_correlation_length_samples)); samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; - d_sample_counter += samples_offset; // count for the processed samples + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(samples_offset); + d_sample_counter += static_cast(samples_offset); // count for the processed samples d_pull_in = false; d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * samples_offset / GLONASS_TWO_PI; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_cycles * GLONASS_TWO_PI; @@ -639,7 +639,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at d_P_history.push_back(d_correlator_outs[1]); // save prompt output d_L_history.push_back(d_correlator_outs[2]); // save late output - if (static_cast(d_P_history.size()) > d_extend_correlation_ms) + if (static_cast(d_P_history.size()) > d_extend_correlation_ms) { d_E_history.pop_front(); d_P_history.pop_front(); @@ -649,7 +649,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at bool enable_dll_pll; if (d_enable_extended_integration == true) { - long int symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); + int64_t symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); if (symbol_diff > 0 and symbol_diff % d_extend_correlation_ms == 0) { // compute coherent integration and enable tracking loop @@ -658,7 +658,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at d_correlator_outs[0] = gr_complex(0.0, 0.0); d_correlator_outs[1] = gr_complex(0.0, 0.0); d_correlator_outs[2] = gr_complex(0.0, 0.0); - for (int n = 0; n < d_extend_correlation_ms; n++) + for (int32_t n = 0; n < d_extend_correlation_ms; n++) { d_correlator_outs[0] += d_E_history.at(n); d_correlator_outs[1] += d_P_history.at(n); @@ -688,7 +688,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at double T_chip_seconds = 1.0 / d_code_freq_chips; double T_prn_seconds = T_chip_seconds * GLONASS_L2_CA_CODE_LENGTH_CHIPS; double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); - int K_prn_samples = round(T_prn_samples); + int32_t K_prn_samples = round(T_prn_samples); double K_T_prn_error_samples = K_prn_samples - T_prn_samples; d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples; @@ -812,7 +812,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at // ########### Output the tracking data to navigation and PVT ########## current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; @@ -831,7 +831,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at { current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; // todo: project the carrier doppler @@ -840,13 +840,13 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at } else { - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } current_synchro_data.System = {'R'}; - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); } //assign the GNURadio block output data current_synchro_data.fs = d_fs_in; @@ -877,7 +877,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_cycles * GLONASS_TWO_PI; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -907,8 +907,8 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at double tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure *e) { diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.h index c5cf8403f..34462476c 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.h @@ -56,14 +56,14 @@ typedef boost::shared_ptr glonass_l2_ca_dll_pll_c_aid_tracking_cc_sptr glonass_l2_ca_dll_pll_c_aid_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); @@ -75,7 +75,7 @@ class glonass_l2_ca_dll_pll_c_aid_tracking_cc : public gr::block public: ~glonass_l2_ca_dll_pll_c_aid_tracking_cc(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); void start_tracking(); @@ -87,39 +87,39 @@ public: private: friend glonass_l2_ca_dll_pll_c_aid_tracking_cc_sptr glonass_l2_ca_dll_pll_c_aid_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); glonass_l2_ca_dll_pll_c_aid_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); // tracking configuration vars - unsigned int d_vector_length; + uint32_t d_vector_length; bool d_dump; Gnss_Synchro* d_acquisition_gnss_synchro; - unsigned int d_channel; + uint32_t d_channel; - long d_fs_in; + int64_t d_fs_in; double d_glonass_freq_ch; double d_early_late_spc_chips; - int d_n_correlator_taps; + int32_t d_n_correlator_taps; gr_complex* d_ca_code; float* d_local_code_shift_chips; @@ -130,7 +130,7 @@ private: double d_rem_code_phase_samples; double d_rem_code_phase_chips; double d_rem_carrier_phase_rad; - int d_rem_code_phase_integer_samples; + int32_t d_rem_code_phase_integer_samples; // PLL and DLL filter library //Tracking_2nd_DLL_filter d_code_loop_filter; @@ -165,25 +165,25 @@ private: std::deque d_P_history; std::deque d_L_history; double d_preamble_timestamp_s; - int d_extend_correlation_ms; + int32_t d_extend_correlation_ms; bool d_enable_extended_integration; bool d_preamble_synchronized; void msg_handler_preamble_index(pmt::pmt_t msg); //Integration period in samples - int d_correlation_length_samples; + int32_t d_correlation_length_samples; //processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; + int32_t d_cn0_estimation_counter; gr_complex* d_Prompt_buffer; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + int32_t d_carrier_lock_fail_counter; // control vars bool d_enable_tracking; @@ -196,7 +196,7 @@ private: std::map systemName; std::string sys; - int save_matfile(); + int32_t save_matfile(); }; #endif //GNSS_SDR_GLONASS_L1_CA_DLL_PLL_C_AID_TRACKING_CC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc index dd3032eac..a02b9f358 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc @@ -35,7 +35,6 @@ */ #include "glonass_l2_ca_dll_pll_c_aid_tracking_sc.h" -#include "gnss_synchro.h" #include "glonass_l2_signal_processing.h" #include "tracking_discriminators.h" #include "lock_detectors.h" @@ -59,15 +58,15 @@ using google::LogMessage; glonass_l2_ca_dll_pll_c_aid_tracking_sc_sptr glonass_l2_ca_dll_pll_c_aid_make_tracking_sc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) { return glonass_l2_ca_dll_pll_c_aid_tracking_sc_sptr(new glonass_l2_ca_dll_pll_c_aid_tracking_sc( @@ -80,7 +79,7 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_sc::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call } } @@ -97,16 +96,17 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_sc::msg_handler_preamble_index(pmt::pm } } + glonass_l2_ca_dll_pll_c_aid_tracking_sc::glonass_l2_ca_dll_pll_c_aid_tracking_sc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) : gr::block("glonass_l1_ca_dll_pll_c_aid_tracking_sc", gr::io_signature::make(1, 1, sizeof(lv_16sc_t)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { @@ -120,7 +120,7 @@ glonass_l2_ca_dll_pll_c_aid_tracking_sc::glonass_l2_ca_dll_pll_c_aid_tracking_sc d_fs_in = fs_in; d_vector_length = vector_length; d_dump_filename = dump_filename; - d_correlation_length_samples = static_cast(d_vector_length); + d_correlation_length_samples = static_cast(d_vector_length); // Initialize tracking ========================================== d_pll_bw_hz = pll_bw_hz; @@ -136,14 +136,14 @@ glonass_l2_ca_dll_pll_c_aid_tracking_sc::glonass_l2_ca_dll_pll_c_aid_tracking_sc // Initialization of local code replica // Get space for a vector with the C/A code replica sampled 1x/chip - d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - d_ca_code_16sc = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_ca_code_16sc = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); // correlator outputs (scalar) d_n_correlator_taps = 3; // Early, Prompt, and Late d_correlator_outs_16sc = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs_16sc[n] = lv_cmake(0, 0); } @@ -165,7 +165,7 @@ glonass_l2_ca_dll_pll_c_aid_tracking_sc::glonass_l2_ca_dll_pll_c_aid_tracking_sc d_rem_carrier_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; //(from trk to tlm) + d_sample_counter = 0ULL; //(from trk to tlm) d_acq_sample_stamp = 0; d_enable_tracking = false; d_pull_in = false; @@ -206,7 +206,7 @@ glonass_l2_ca_dll_pll_c_aid_tracking_sc::glonass_l2_ca_dll_pll_c_aid_tracking_sc d_carrier_doppler_old_hz = 0.0; d_glonass_freq_ch = 0; - //set_min_output_buffer((long int)300); + //set_min_output_buffer((int64_t)300); } @@ -219,9 +219,9 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_sc::start_tracking() d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; - long int acq_trk_diff_samples; + int64_t acq_trk_diff_samples; double acq_trk_diff_seconds; - acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); // Doppler effect @@ -266,10 +266,10 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_sc::start_tracking() // generate local reference ALWAYS starting at chip 1 (1 sample per chip) glonass_l2_ca_code_gen_complex(d_ca_code, 0); - volk_gnsssdr_32fc_convert_16ic(d_ca_code_16sc, d_ca_code, static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS)); + volk_gnsssdr_32fc_convert_16ic(d_ca_code_16sc, d_ca_code, static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS)); - multicorrelator_cpu_16sc.set_local_code_and_taps(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS), d_ca_code_16sc, d_local_code_shift_chips); - for (int n = 0; n < d_n_correlator_taps; n++) + multicorrelator_cpu_16sc.set_local_code_and_taps(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS), d_ca_code_16sc, d_local_code_shift_chips); + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs_16sc[n] = lv_16sc_t(0, 0); } @@ -301,14 +301,14 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_sc::start_tracking() } -int glonass_l2_ca_dll_pll_c_aid_tracking_sc::save_matfile() +int32_t glonass_l2_ca_dll_pll_c_aid_tracking_sc::save_matfile() { // READ DUMP FILE std::ifstream::pos_type size; - int number_of_double_vars = 11; - int number_of_float_vars = 5; - int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + - sizeof(float) * number_of_float_vars + sizeof(unsigned int); + int32_t number_of_double_vars = 11; + int32_t number_of_float_vars = 5; + int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try @@ -321,11 +321,11 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::save_matfile() return 1; } // count number of epochs and rewind - long int num_epoch = 0; + int64_t num_epoch = 0; if (dump_file.is_open()) { size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); dump_file.seekg(0, std::ios::beg); } else @@ -337,7 +337,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::save_matfile() float *abs_L = new float[num_epoch]; float *Prompt_I = new float[num_epoch]; float *Prompt_Q = new float[num_epoch]; - unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch]; + uint64_t *PRN_start_sample_count = new uint64_t[num_epoch]; double *acc_carrier_phase_rad = new double[num_epoch]; double *carrier_doppler_hz = new double[num_epoch]; double *code_freq_chips = new double[num_epoch]; @@ -349,20 +349,20 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::save_matfile() double *carrier_lock_test = new double[num_epoch]; double *aux1 = new double[num_epoch]; double *aux2 = new double[num_epoch]; - unsigned int *PRN = new unsigned int[num_epoch]; + uint32_t *PRN = new uint32_t[num_epoch]; try { if (dump_file.is_open()) { - for (long int i = 0; i < num_epoch; i++) + for (int64_t i = 0; i < num_epoch; i++) { dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(uint64_t)); dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); @@ -374,7 +374,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::save_matfile() dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(uint32_t)); } } dump_file.close(); @@ -410,7 +410,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::save_matfile() filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (reinterpret_cast(matfp) != NULL) + if (reinterpret_cast(matfp) != NULL) { size_t dims[2] = {1, static_cast(num_epoch)}; matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); @@ -545,7 +545,7 @@ glonass_l2_ca_dll_pll_c_aid_tracking_sc::~glonass_l2_ca_dll_pll_c_aid_tracking_s } -void glonass_l2_ca_dll_pll_c_aid_tracking_sc::set_channel(unsigned int channel) +void glonass_l2_ca_dll_pll_c_aid_tracking_sc::set_channel(uint32_t channel) { d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -599,14 +599,14 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at // Receiver signal alignment if (d_pull_in == true) { - int samples_offset; + int32_t samples_offset; double acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; + int32_t acq_to_trk_delay_samples; acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; acq_trk_shif_correction_samples = d_correlation_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_correlation_length_samples)); samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; - d_sample_counter += samples_offset; // count for the processed samples + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(samples_offset); + d_sample_counter += static_cast(samples_offset); // count for the processed samples d_pull_in = false; d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * samples_offset / GLONASS_TWO_PI; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_cycles * GLONASS_TWO_PI; @@ -632,7 +632,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at d_P_history.push_back(d_correlator_outs_16sc[1]); // save prompt output d_L_history.push_back(d_correlator_outs_16sc[2]); // save late output - if (static_cast(d_P_history.size()) > d_extend_correlation_ms) + if (static_cast(d_P_history.size()) > d_extend_correlation_ms) { d_E_history.pop_front(); d_P_history.pop_front(); @@ -642,7 +642,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at bool enable_dll_pll; if (d_enable_extended_integration == true) { - long int symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); + int64_t symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); if (symbol_diff > 0 and symbol_diff % d_extend_correlation_ms == 0) { // compute coherent integration and enable tracking loop @@ -651,7 +651,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at d_correlator_outs_16sc[0] = lv_cmake(0, 0); d_correlator_outs_16sc[1] = lv_cmake(0, 0); d_correlator_outs_16sc[2] = lv_cmake(0, 0); - for (int n = 0; n < d_extend_correlation_ms; n++) + for (int32_t n = 0; n < d_extend_correlation_ms; n++) { d_correlator_outs_16sc[0] += d_E_history.at(n); d_correlator_outs_16sc[1] += d_P_history.at(n); @@ -680,7 +680,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at double T_chip_seconds = 1.0 / d_code_freq_chips; double T_prn_seconds = T_chip_seconds * GLONASS_L2_CA_CODE_LENGTH_CHIPS; double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); - int K_prn_samples = round(T_prn_samples); + int32_t K_prn_samples = round(T_prn_samples); double K_T_prn_error_samples = K_prn_samples - T_prn_samples; d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples; @@ -804,7 +804,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at current_synchro_data.Prompt_I = static_cast((d_correlator_outs_16sc[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs_16sc[1]).imag()); // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!) - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; @@ -823,7 +823,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at { current_synchro_data.Prompt_I = static_cast((d_correlator_outs_16sc[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs_16sc[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GLONASS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; // todo: project the carrier doppler @@ -832,13 +832,13 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at } else { - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs_16sc[n] = lv_cmake(0, 0); } current_synchro_data.System = {'R'}; - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); } current_synchro_data.fs = d_fs_in; *out[0] = current_synchro_data; @@ -868,7 +868,7 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_cycles * GLONASS_TWO_PI; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -898,8 +898,8 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at double tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure *e) { diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.h index f986ccd4c..746df0595 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.h @@ -57,14 +57,14 @@ typedef boost::shared_ptr glonass_l2_ca_dll_pll_c_aid_tracking_sc_sptr glonass_l2_ca_dll_pll_c_aid_make_tracking_sc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); @@ -76,7 +76,7 @@ class glonass_l2_ca_dll_pll_c_aid_tracking_sc : public gr::block public: ~glonass_l2_ca_dll_pll_c_aid_tracking_sc(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); void start_tracking(); @@ -88,39 +88,39 @@ public: private: friend glonass_l2_ca_dll_pll_c_aid_tracking_sc_sptr glonass_l2_ca_dll_pll_c_aid_make_tracking_sc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); glonass_l2_ca_dll_pll_c_aid_tracking_sc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); // tracking configuration vars - unsigned int d_vector_length; + uint32_t d_vector_length; bool d_dump; Gnss_Synchro* d_acquisition_gnss_synchro; - unsigned int d_channel; + uint32_t d_channel; - long d_fs_in; - long d_glonass_freq_ch; + int64_t d_fs_in; + int64_t d_glonass_freq_ch; double d_early_late_spc_chips; - int d_n_correlator_taps; + int32_t d_n_correlator_taps; gr_complex* d_ca_code; lv_16sc_t* d_ca_code_16sc; @@ -134,7 +134,7 @@ private: double d_rem_code_phase_samples; double d_rem_code_phase_chips; double d_rem_carrier_phase_rad; - int d_rem_code_phase_integer_samples; + int32_t d_rem_code_phase_integer_samples; // PLL and DLL filter library Tracking_2nd_DLL_filter d_code_loop_filter; @@ -161,7 +161,7 @@ private: double d_carr_phase_error_secs_Ti; double d_code_error_chips_Ti; double d_preamble_timestamp_s; - int d_extend_correlation_ms; + int32_t d_extend_correlation_ms; bool d_enable_extended_integration; bool d_preamble_synchronized; double d_code_error_filt_chips_s; @@ -174,19 +174,19 @@ private: std::deque d_L_history; //Integration period in samples - int d_correlation_length_samples; + int32_t d_correlation_length_samples; //processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; + int32_t d_cn0_estimation_counter; gr_complex* d_Prompt_buffer; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + int32_t d_carrier_lock_fail_counter; // control vars bool d_enable_tracking; @@ -199,7 +199,7 @@ private: std::map systemName; std::string sys; - int save_matfile(); + int32_t save_matfile(); }; #endif //GNSS_SDR_GLONASS_L2_CA_DLL_PLL_C_AID_TRACKING_SC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc index bb6adb024..e90341eac 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc @@ -59,8 +59,8 @@ using google::LogMessage; glonass_l2_ca_dll_pll_tracking_cc_sptr glonass_l2_ca_dll_pll_make_tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -77,14 +77,14 @@ void Glonass_L2_Ca_Dll_Pll_Tracking_cc::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call } } Glonass_L2_Ca_Dll_Pll_Tracking_cc::Glonass_L2_Ca_Dll_Pll_Tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -100,7 +100,7 @@ Glonass_L2_Ca_Dll_Pll_Tracking_cc::Glonass_L2_Ca_Dll_Pll_Tracking_cc( d_vector_length = vector_length; d_dump_filename = dump_filename; - d_current_prn_length_samples = static_cast(d_vector_length); + d_current_prn_length_samples = static_cast(d_vector_length); // Initialize tracking ========================================== d_code_loop_filter.set_DLL_BW(dll_bw_hz); @@ -111,12 +111,12 @@ Glonass_L2_Ca_Dll_Pll_Tracking_cc::Glonass_L2_Ca_Dll_Pll_Tracking_cc( // Initialization of local code replica // Get space for a vector with the C/A code replica sampled 1x/chip - d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); // correlator outputs (scalar) d_n_correlator_taps = 3; // Early, Prompt, and Late d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -137,7 +137,7 @@ Glonass_L2_Ca_Dll_Pll_Tracking_cc::Glonass_L2_Ca_Dll_Pll_Tracking_cc( d_rem_carr_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; + d_sample_counter = 0ULL; //d_sample_counter_seconds = 0; d_acq_sample_stamp = 0; @@ -182,9 +182,9 @@ void Glonass_L2_Ca_Dll_Pll_Tracking_cc::start_tracking() d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; - long int acq_trk_diff_samples; + int64_t acq_trk_diff_samples; double acq_trk_diff_seconds; - acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); // Doppler effect @@ -229,8 +229,8 @@ void Glonass_L2_Ca_Dll_Pll_Tracking_cc::start_tracking() // generate local reference ALWAYS starting at chip 1 (1 sample per chip) glonass_l2_ca_code_gen_complex(d_ca_code, 0); - multicorrelator_cpu.set_local_code_and_taps(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); - for (int n = 0; n < d_n_correlator_taps; n++) + multicorrelator_cpu.set_local_code_and_taps(static_cast(GLONASS_L2_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -300,14 +300,14 @@ Glonass_L2_Ca_Dll_Pll_Tracking_cc::~Glonass_L2_Ca_Dll_Pll_Tracking_cc() } -int Glonass_L2_Ca_Dll_Pll_Tracking_cc::save_matfile() +int32_t Glonass_L2_Ca_Dll_Pll_Tracking_cc::save_matfile() { // READ DUMP FILE std::ifstream::pos_type size; - int number_of_double_vars = 11; - int number_of_float_vars = 5; - int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + - sizeof(float) * number_of_float_vars + sizeof(unsigned int); + int32_t number_of_double_vars = 11; + int32_t number_of_float_vars = 5; + int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try @@ -320,11 +320,11 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::save_matfile() return 1; } // count number of epochs and rewind - long int num_epoch = 0; + int64_t num_epoch = 0; if (dump_file.is_open()) { size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); dump_file.seekg(0, std::ios::beg); } else @@ -336,7 +336,7 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::save_matfile() float *abs_L = new float[num_epoch]; float *Prompt_I = new float[num_epoch]; float *Prompt_Q = new float[num_epoch]; - unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch]; + uint64_t *PRN_start_sample_count = new uint64_t[num_epoch]; double *acc_carrier_phase_rad = new double[num_epoch]; double *carrier_doppler_hz = new double[num_epoch]; double *code_freq_chips = new double[num_epoch]; @@ -348,20 +348,20 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::save_matfile() double *carrier_lock_test = new double[num_epoch]; double *aux1 = new double[num_epoch]; double *aux2 = new double[num_epoch]; - unsigned int *PRN = new unsigned int[num_epoch]; + uint32_t *PRN = new uint32_t[num_epoch]; try { if (dump_file.is_open()) { - for (long int i = 0; i < num_epoch; i++) + for (int64_t i = 0; i < num_epoch; i++) { dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(uint64_t)); dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); @@ -373,7 +373,7 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::save_matfile() dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(uint32_t)); } } dump_file.close(); @@ -409,7 +409,7 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::save_matfile() filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (reinterpret_cast(matfp) != NULL) + if (reinterpret_cast(matfp) != NULL) { size_t dims[2] = {1, static_cast(num_epoch)}; matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); @@ -507,7 +507,7 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::save_matfile() } -void Glonass_L2_Ca_Dll_Pll_Tracking_cc::set_channel(unsigned int channel) +void Glonass_L2_Ca_Dll_Pll_Tracking_cc::set_channel(uint32_t channel) { d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -562,14 +562,14 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut // Receiver signal alignment if (d_pull_in == true) { - int samples_offset; + int32_t samples_offset; double acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; + int32_t acq_to_trk_delay_samples; acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; acq_trk_shif_correction_samples = d_current_prn_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; - d_sample_counter = d_sample_counter + samples_offset; // count for the processed samples + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(samples_offset); + d_sample_counter = d_sample_counter + static_cast(samples_offset); // count for the processed samples d_pull_in = false; // take into account the carrier cycles accumulated in the pull in signal alignment d_acc_carrier_phase_rad -= d_carrier_doppler_phase_step_rad * samples_offset; @@ -673,7 +673,7 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut // ########### Output the tracking data to navigation and PVT ########## current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_current_prn_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; @@ -683,12 +683,12 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut } else { - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_current_prn_length_samples); current_synchro_data.System = {'R'}; current_synchro_data.correlation_length_ms = 1; } @@ -722,7 +722,7 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_rad; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -752,8 +752,8 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut double tmp_double = static_cast(d_sample_counter + d_current_prn_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.h index 63598dfd0..1839ea51b 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.h @@ -53,7 +53,7 @@ typedef boost::shared_ptr glonass_l2_ca_dll_pll_tracking_cc_sptr glonass_l2_ca_dll_pll_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -69,7 +69,7 @@ class Glonass_L2_Ca_Dll_Pll_Tracking_cc : public gr::block public: ~Glonass_L2_Ca_Dll_Pll_Tracking_cc(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); void start_tracking(); @@ -81,7 +81,7 @@ public: private: friend glonass_l2_ca_dll_pll_tracking_cc_sptr glonass_l2_ca_dll_pll_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -89,7 +89,7 @@ private: float early_late_space_chips); Glonass_L2_Ca_Dll_Pll_Tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -97,14 +97,14 @@ private: float early_late_space_chips); // tracking configuration vars - unsigned int d_vector_length; + uint32_t d_vector_length; bool d_dump; Gnss_Synchro* d_acquisition_gnss_synchro; - unsigned int d_channel; + uint32_t d_channel; - long d_fs_in; - long d_glonass_freq_ch; + int64_t d_fs_in; + int64_t d_glonass_freq_ch; double d_early_late_spc_chips; @@ -121,7 +121,7 @@ private: double d_acq_code_phase_samples; double d_acq_carrier_doppler_hz; // correlator - int d_n_correlator_taps; + int32_t d_n_correlator_taps; gr_complex* d_ca_code; float* d_local_code_shift_chips; gr_complex* d_correlator_outs; @@ -139,19 +139,19 @@ private: double d_code_phase_samples; //PRN period in samples - int d_current_prn_length_samples; + int32_t d_current_prn_length_samples; //processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; + int32_t d_cn0_estimation_counter; gr_complex* d_Prompt_buffer; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + int32_t d_carrier_lock_fail_counter; // control vars bool d_enable_tracking; @@ -164,7 +164,7 @@ private: std::map systemName; std::string sys; - int save_matfile(); + int32_t save_matfile(); }; #endif //GNSS_SDR_GLONASS_L2_CA_DLL_PLL_TRACKING_CC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc index 7407c792e..33879066e 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -51,15 +51,15 @@ using google::LogMessage; gps_l1_ca_dll_pll_c_aid_tracking_cc_sptr gps_l1_ca_dll_pll_c_aid_make_tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) { return gps_l1_ca_dll_pll_c_aid_tracking_cc_sptr(new gps_l1_ca_dll_pll_c_aid_tracking_cc( @@ -72,7 +72,7 @@ void gps_l1_ca_dll_pll_c_aid_tracking_cc::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call } } @@ -91,15 +91,15 @@ void gps_l1_ca_dll_pll_c_aid_tracking_cc::msg_handler_preamble_index(pmt::pmt_t gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) : gr::block("gps_l1_ca_dll_pll_c_aid_tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { @@ -115,7 +115,7 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc( d_fs_in = fs_in; d_vector_length = vector_length; d_dump_filename = dump_filename; - d_correlation_length_samples = static_cast(d_vector_length); + d_correlation_length_samples = static_cast(d_vector_length); // Initialize tracking ========================================== d_pll_bw_hz = pll_bw_hz; @@ -131,12 +131,12 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc( // Initialization of local code replica // Get space for a vector with the C/A code replica sampled 1x/chip - d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); // correlator outputs (scalar) d_n_correlator_taps = 3; // Early, Prompt, and Late d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -157,7 +157,7 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc( d_rem_carrier_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; //(from trk to tlm) + d_sample_counter = 0ULL; //(from trk to tlm) d_acq_sample_stamp = 0; d_enable_tracking = false; d_pull_in = false; @@ -195,7 +195,7 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::gps_l1_ca_dll_pll_c_aid_tracking_cc( d_code_error_filt_chips_s = 0.0; d_carr_phase_error_secs_Ti = 0.0; d_preamble_timestamp_s = 0.0; - //set_min_output_buffer((long int)300); + //set_min_output_buffer((int64_t)300); } @@ -208,9 +208,9 @@ void gps_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking() d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; - long int acq_trk_diff_samples; + int64_t acq_trk_diff_samples; double acq_trk_diff_seconds; - acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); // Doppler effect @@ -253,8 +253,8 @@ void gps_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking() // generate local reference ALWAYS starting at chip 1 (1 sample per chip) gps_l1_ca_code_gen_complex(d_ca_code, d_acquisition_gnss_synchro->PRN, 0); - multicorrelator_cpu.set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); - for (int n = 0; n < d_n_correlator_taps; n++) + multicorrelator_cpu.set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -327,14 +327,14 @@ gps_l1_ca_dll_pll_c_aid_tracking_cc::~gps_l1_ca_dll_pll_c_aid_tracking_cc() } -int gps_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() +int32_t gps_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() { // READ DUMP FILE std::ifstream::pos_type size; - int number_of_double_vars = 11; - int number_of_float_vars = 5; - int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + - sizeof(float) * number_of_float_vars + sizeof(unsigned int); + int32_t number_of_double_vars = 11; + int32_t number_of_float_vars = 5; + int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try @@ -347,11 +347,11 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() return 1; } // count number of epochs and rewind - long int num_epoch = 0; + int64_t num_epoch = 0; if (dump_file.is_open()) { size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); dump_file.seekg(0, std::ios::beg); } else @@ -363,7 +363,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() float *abs_L = new float[num_epoch]; float *Prompt_I = new float[num_epoch]; float *Prompt_Q = new float[num_epoch]; - unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch]; + uint64_t *PRN_start_sample_count = new uint64_t[num_epoch]; double *acc_carrier_phase_rad = new double[num_epoch]; double *carrier_doppler_hz = new double[num_epoch]; double *code_freq_chips = new double[num_epoch]; @@ -375,20 +375,20 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() double *carrier_lock_test = new double[num_epoch]; double *aux1 = new double[num_epoch]; double *aux2 = new double[num_epoch]; - unsigned int *PRN = new unsigned int[num_epoch]; + uint32_t *PRN = new uint32_t[num_epoch]; try { if (dump_file.is_open()) { - for (long int i = 0; i < num_epoch; i++) + for (int64_t i = 0; i < num_epoch; i++) { dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(uint64_t)); dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); @@ -400,7 +400,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(uint32_t)); } } dump_file.close(); @@ -436,7 +436,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (reinterpret_cast(matfp) != NULL) + if (reinterpret_cast(matfp) != NULL) { size_t dims[2] = {1, static_cast(num_epoch)}; matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); @@ -534,7 +534,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::save_matfile() } -void gps_l1_ca_dll_pll_c_aid_tracking_cc::set_channel(unsigned int channel) +void gps_l1_ca_dll_pll_c_aid_tracking_cc::set_channel(uint32_t channel) { d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -588,14 +588,14 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib // Receiver signal alignment if (d_pull_in == true) { - int samples_offset; + int32_t samples_offset; double acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; + int32_t acq_to_trk_delay_samples; acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; acq_trk_shif_correction_samples = d_correlation_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_correlation_length_samples)); samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; - d_sample_counter += samples_offset; // count for the processed samples + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(samples_offset); + d_sample_counter += static_cast(samples_offset); // count for the processed samples d_pull_in = false; d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * samples_offset / GPS_TWO_PI; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_cycles * GPS_TWO_PI; @@ -621,7 +621,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib d_P_history.push_back(d_correlator_outs[1]); // save prompt output d_L_history.push_back(d_correlator_outs[2]); // save late output - if (static_cast(d_P_history.size()) > d_extend_correlation_ms) + if (static_cast(d_P_history.size()) > d_extend_correlation_ms) { d_E_history.pop_front(); d_P_history.pop_front(); @@ -631,7 +631,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib bool enable_dll_pll; if (d_enable_extended_integration == true) { - long int symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); + int64_t symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); if (symbol_diff > 0 and symbol_diff % d_extend_correlation_ms == 0) { // compute coherent integration and enable tracking loop @@ -640,7 +640,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib d_correlator_outs[0] = gr_complex(0.0, 0.0); d_correlator_outs[1] = gr_complex(0.0, 0.0); d_correlator_outs[2] = gr_complex(0.0, 0.0); - for (int n = 0; n < d_extend_correlation_ms; n++) + for (int32_t n = 0; n < d_extend_correlation_ms; n++) { d_correlator_outs[0] += d_E_history.at(n); d_correlator_outs[1] += d_P_history.at(n); @@ -670,7 +670,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib double T_chip_seconds = 1.0 / d_code_freq_chips; double T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); - int K_prn_samples = round(T_prn_samples); + int32_t K_prn_samples = round(T_prn_samples); double K_T_prn_error_samples = K_prn_samples - T_prn_samples; d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples; @@ -793,7 +793,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib // ########### Output the tracking data to navigation and PVT ########## current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GPS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; @@ -812,7 +812,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib { current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GPS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; // todo: project the carrier doppler @@ -821,13 +821,13 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib } else { - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } current_synchro_data.System = {'G'}; - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); } //assign the GNURadio block output data current_synchro_data.fs = d_fs_in; @@ -858,7 +858,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_cycles * GPS_TWO_PI; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -888,8 +888,8 @@ int gps_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __attrib double tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure *e) { diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h index 1b6d9e12e..42f5a4902 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_cc.h @@ -56,14 +56,14 @@ typedef boost::shared_ptr gps_l1_ca_dll_pll_c_aid_tracking_cc_sptr gps_l1_ca_dll_pll_c_aid_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); @@ -75,7 +75,7 @@ class gps_l1_ca_dll_pll_c_aid_tracking_cc : public gr::block public: ~gps_l1_ca_dll_pll_c_aid_tracking_cc(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); void start_tracking(); @@ -87,37 +87,37 @@ public: private: friend gps_l1_ca_dll_pll_c_aid_tracking_cc_sptr gps_l1_ca_dll_pll_c_aid_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); gps_l1_ca_dll_pll_c_aid_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); // tracking configuration vars - unsigned int d_vector_length; + uint32_t d_vector_length; bool d_dump; Gnss_Synchro* d_acquisition_gnss_synchro; - unsigned int d_channel; - long d_fs_in; + uint32_t d_channel; + int64_t d_fs_in; double d_early_late_spc_chips; - int d_n_correlator_taps; + int32_t d_n_correlator_taps; gr_complex* d_ca_code; float* d_local_code_shift_chips; @@ -128,7 +128,7 @@ private: double d_rem_code_phase_samples; double d_rem_code_phase_chips; double d_rem_carrier_phase_rad; - int d_rem_code_phase_integer_samples; + int32_t d_rem_code_phase_integer_samples; // PLL and DLL filter library //Tracking_2nd_DLL_filter d_code_loop_filter; @@ -161,25 +161,25 @@ private: std::deque d_P_history; std::deque d_L_history; double d_preamble_timestamp_s; - int d_extend_correlation_ms; + int32_t d_extend_correlation_ms; bool d_enable_extended_integration; bool d_preamble_synchronized; void msg_handler_preamble_index(pmt::pmt_t msg); //Integration period in samples - int d_correlation_length_samples; + int32_t d_correlation_length_samples; //processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; + int32_t d_cn0_estimation_counter; gr_complex* d_Prompt_buffer; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + int32_t d_carrier_lock_fail_counter; // control vars bool d_enable_tracking; @@ -192,7 +192,7 @@ private: std::map systemName; std::string sys; - int save_matfile(); + int32_t save_matfile(); }; #endif //GNSS_SDR_GPS_L1_CA_DLL_PLL_C_AID_TRACKING_CC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc index 644616b28..b1defca22 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -29,7 +29,6 @@ */ #include "gps_l1_ca_dll_pll_c_aid_tracking_sc.h" -#include "gnss_synchro.h" #include "gps_sdr_signal_processing.h" #include "tracking_discriminators.h" #include "lock_detectors.h" @@ -52,15 +51,15 @@ using google::LogMessage; gps_l1_ca_dll_pll_c_aid_tracking_sc_sptr gps_l1_ca_dll_pll_c_aid_make_tracking_sc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) { return gps_l1_ca_dll_pll_c_aid_tracking_sc_sptr(new gps_l1_ca_dll_pll_c_aid_tracking_sc( @@ -73,7 +72,7 @@ void gps_l1_ca_dll_pll_c_aid_tracking_sc::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call } } @@ -91,15 +90,15 @@ void gps_l1_ca_dll_pll_c_aid_tracking_sc::msg_handler_preamble_index(pmt::pmt_t } gps_l1_ca_dll_pll_c_aid_tracking_sc::gps_l1_ca_dll_pll_c_aid_tracking_sc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips) : gr::block("gps_l1_ca_dll_pll_c_aid_tracking_sc", gr::io_signature::make(1, 1, sizeof(lv_16sc_t)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { @@ -113,7 +112,7 @@ gps_l1_ca_dll_pll_c_aid_tracking_sc::gps_l1_ca_dll_pll_c_aid_tracking_sc( d_fs_in = fs_in; d_vector_length = vector_length; d_dump_filename = dump_filename; - d_correlation_length_samples = static_cast(d_vector_length); + d_correlation_length_samples = static_cast(d_vector_length); // Initialize tracking ========================================== d_pll_bw_hz = pll_bw_hz; @@ -129,14 +128,14 @@ gps_l1_ca_dll_pll_c_aid_tracking_sc::gps_l1_ca_dll_pll_c_aid_tracking_sc( // Initialization of local code replica // Get space for a vector with the C/A code replica sampled 1x/chip - d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - d_ca_code_16sc = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + d_ca_code_16sc = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); // correlator outputs (scalar) d_n_correlator_taps = 3; // Early, Prompt, and Late d_correlator_outs_16sc = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs_16sc[n] = lv_cmake(0, 0); } @@ -158,7 +157,7 @@ gps_l1_ca_dll_pll_c_aid_tracking_sc::gps_l1_ca_dll_pll_c_aid_tracking_sc( d_rem_carrier_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; //(from trk to tlm) + d_sample_counter = 0ULL; //(from trk to tlm) d_acq_sample_stamp = 0; d_enable_tracking = false; d_pull_in = false; @@ -195,7 +194,7 @@ gps_l1_ca_dll_pll_c_aid_tracking_sc::gps_l1_ca_dll_pll_c_aid_tracking_sc( d_code_error_filt_chips_Ti = 0.0; d_preamble_timestamp_s = 0.0; d_carr_phase_error_secs_Ti = 0.0; - //set_min_output_buffer((long int)300); + //set_min_output_buffer((int64_t)300); } @@ -208,9 +207,9 @@ void gps_l1_ca_dll_pll_c_aid_tracking_sc::start_tracking() d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; - long int acq_trk_diff_samples; + int64_t acq_trk_diff_samples; double acq_trk_diff_seconds; - acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); // Doppler effect @@ -252,10 +251,10 @@ void gps_l1_ca_dll_pll_c_aid_tracking_sc::start_tracking() // generate local reference ALWAYS starting at chip 1 (1 sample per chip) gps_l1_ca_code_gen_complex(d_ca_code, d_acquisition_gnss_synchro->PRN, 0); - volk_gnsssdr_32fc_convert_16ic(d_ca_code_16sc, d_ca_code, static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS)); + volk_gnsssdr_32fc_convert_16ic(d_ca_code_16sc, d_ca_code, static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS)); - multicorrelator_cpu_16sc.set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code_16sc, d_local_code_shift_chips); - for (int n = 0; n < d_n_correlator_taps; n++) + multicorrelator_cpu_16sc.set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code_16sc, d_local_code_shift_chips); + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs_16sc[n] = lv_16sc_t(0, 0); } @@ -330,14 +329,14 @@ gps_l1_ca_dll_pll_c_aid_tracking_sc::~gps_l1_ca_dll_pll_c_aid_tracking_sc() } -int gps_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() +int32_t gps_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() { // READ DUMP FILE std::ifstream::pos_type size; - int number_of_double_vars = 11; - int number_of_float_vars = 5; - int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + - sizeof(float) * number_of_float_vars + sizeof(unsigned int); + int32_t number_of_double_vars = 11; + int32_t number_of_float_vars = 5; + int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(uint32_t); std::ifstream dump_file; dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); try @@ -350,11 +349,11 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() return 1; } // count number of epochs and rewind - long int num_epoch = 0; + int64_t num_epoch = 0; if (dump_file.is_open()) { size = dump_file.tellg(); - num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); dump_file.seekg(0, std::ios::beg); } else @@ -366,7 +365,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() float *abs_L = new float[num_epoch]; float *Prompt_I = new float[num_epoch]; float *Prompt_Q = new float[num_epoch]; - unsigned long int *PRN_start_sample_count = new unsigned long int[num_epoch]; + uint64_t *PRN_start_sample_count = new uint64_t[num_epoch]; double *acc_carrier_phase_rad = new double[num_epoch]; double *carrier_doppler_hz = new double[num_epoch]; double *code_freq_chips = new double[num_epoch]; @@ -378,20 +377,20 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() double *carrier_lock_test = new double[num_epoch]; double *aux1 = new double[num_epoch]; double *aux2 = new double[num_epoch]; - unsigned int *PRN = new unsigned int[num_epoch]; + uint32_t *PRN = new uint32_t[num_epoch]; try { if (dump_file.is_open()) { - for (long int i = 0; i < num_epoch; i++) + for (int64_t i = 0; i < num_epoch; i++) { dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); - dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(unsigned long int)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(uint64_t)); dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(double)); dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(double)); dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(double)); @@ -403,7 +402,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux1[i]), sizeof(double)); dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); - dump_file.read(reinterpret_cast(&PRN[i]), sizeof(unsigned int)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(uint32_t)); } } dump_file.close(); @@ -439,7 +438,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() filename.erase(filename.length() - 4, 4); filename.append(".mat"); matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); - if (reinterpret_cast(matfp) != NULL) + if (reinterpret_cast(matfp) != NULL) { size_t dims[2] = {1, static_cast(num_epoch)}; matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); @@ -537,7 +536,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::save_matfile() } -void gps_l1_ca_dll_pll_c_aid_tracking_sc::set_channel(unsigned int channel) +void gps_l1_ca_dll_pll_c_aid_tracking_sc::set_channel(uint32_t channel) { d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -591,14 +590,14 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib // Receiver signal alignment if (d_pull_in == true) { - int samples_offset; + int32_t samples_offset; double acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; + int32_t acq_to_trk_delay_samples; acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; acq_trk_shif_correction_samples = d_correlation_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_correlation_length_samples)); samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; - d_sample_counter += samples_offset; // count for the processed samples + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(samples_offset); + d_sample_counter += static_cast(samples_offset); // count for the processed samples d_pull_in = false; d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * samples_offset / GPS_TWO_PI; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_cycles * GPS_TWO_PI; @@ -624,7 +623,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib d_P_history.push_back(d_correlator_outs_16sc[1]); // save prompt output d_L_history.push_back(d_correlator_outs_16sc[2]); // save late output - if (static_cast(d_P_history.size()) > d_extend_correlation_ms) + if (static_cast(d_P_history.size()) > d_extend_correlation_ms) { d_E_history.pop_front(); d_P_history.pop_front(); @@ -634,7 +633,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib bool enable_dll_pll; if (d_enable_extended_integration == true) { - long int symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); + int64_t symbol_diff = round(1000.0 * ((static_cast(d_sample_counter) + d_rem_code_phase_samples) / static_cast(d_fs_in) - d_preamble_timestamp_s)); if (symbol_diff > 0 and symbol_diff % d_extend_correlation_ms == 0) { // compute coherent integration and enable tracking loop @@ -643,7 +642,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib d_correlator_outs_16sc[0] = lv_cmake(0, 0); d_correlator_outs_16sc[1] = lv_cmake(0, 0); d_correlator_outs_16sc[2] = lv_cmake(0, 0); - for (int n = 0; n < d_extend_correlation_ms; n++) + for (int32_t n = 0; n < d_extend_correlation_ms; n++) { d_correlator_outs_16sc[0] += d_E_history.at(n); d_correlator_outs_16sc[1] += d_P_history.at(n); @@ -672,7 +671,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib double T_chip_seconds = 1.0 / d_code_freq_chips; double T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); - int K_prn_samples = round(T_prn_samples); + int32_t K_prn_samples = round(T_prn_samples); double K_T_prn_error_samples = K_prn_samples - T_prn_samples; d_rem_code_phase_samples = d_rem_code_phase_samples - K_T_prn_error_samples; @@ -796,7 +795,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib current_synchro_data.Prompt_I = static_cast((d_correlator_outs_16sc[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs_16sc[1]).imag()); // Tracking_timestamp_secs is aligned with the CURRENT PRN start sample (Hybridization OK!) - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GPS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; @@ -815,7 +814,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib { current_synchro_data.Prompt_I = static_cast((d_correlator_outs_16sc[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs_16sc[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GPS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; // todo: project the carrier doppler @@ -824,13 +823,13 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib } else { - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs_16sc[n] = lv_cmake(0, 0); } current_synchro_data.System = {'G'}; - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); } current_synchro_data.fs = d_fs_in; *out[0] = current_synchro_data; @@ -860,7 +859,7 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_cycles * GPS_TWO_PI; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -890,8 +889,8 @@ int gps_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __attrib double tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure *e) { diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.h index 5da13feb4..7bd75d974 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.h +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_c_aid_tracking_sc.h @@ -57,14 +57,14 @@ typedef boost::shared_ptr gps_l1_ca_dll_pll_c_aid_tracking_sc_sptr gps_l1_ca_dll_pll_c_aid_make_tracking_sc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); @@ -76,7 +76,7 @@ class gps_l1_ca_dll_pll_c_aid_tracking_sc : public gr::block public: ~gps_l1_ca_dll_pll_c_aid_tracking_sc(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); void start_tracking(); @@ -88,38 +88,38 @@ public: private: friend gps_l1_ca_dll_pll_c_aid_tracking_sc_sptr gps_l1_ca_dll_pll_c_aid_make_tracking_sc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); gps_l1_ca_dll_pll_c_aid_tracking_sc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, float dll_bw_hz, float pll_bw_narrow_hz, float dll_bw_narrow_hz, - int extend_correlation_ms, + int32_t extend_correlation_ms, float early_late_space_chips); // tracking configuration vars - unsigned int d_vector_length; + uint32_t d_vector_length; bool d_dump; Gnss_Synchro* d_acquisition_gnss_synchro; - unsigned int d_channel; + uint32_t d_channel; - long d_fs_in; + int64_t d_fs_in; double d_early_late_spc_chips; - int d_n_correlator_taps; + int32_t d_n_correlator_taps; gr_complex* d_ca_code; lv_16sc_t* d_ca_code_16sc; @@ -133,7 +133,7 @@ private: double d_rem_code_phase_samples; double d_rem_code_phase_chips; double d_rem_carrier_phase_rad; - int d_rem_code_phase_integer_samples; + int32_t d_rem_code_phase_integer_samples; // PLL and DLL filter library Tracking_2nd_DLL_filter d_code_loop_filter; @@ -158,7 +158,7 @@ private: double d_carr_phase_error_secs_Ti; double d_code_error_chips_Ti; double d_preamble_timestamp_s; - int d_extend_correlation_ms; + int32_t d_extend_correlation_ms; bool d_enable_extended_integration; bool d_preamble_synchronized; double d_code_error_filt_chips_s; @@ -171,19 +171,19 @@ private: std::deque d_L_history; //Integration period in samples - int d_correlation_length_samples; + int32_t d_correlation_length_samples; //processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; + int32_t d_cn0_estimation_counter; gr_complex* d_Prompt_buffer; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + int32_t d_carrier_lock_fail_counter; // control vars bool d_enable_tracking; @@ -196,7 +196,7 @@ private: std::map systemName; std::string sys; - int save_matfile(); + int32_t save_matfile(); }; #endif //GNSS_SDR_GPS_L1_CA_DLL_PLL_C_AID_TRACKING_SC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc index 77ac57a0e..713d43164 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc @@ -49,8 +49,8 @@ using google::LogMessage; gps_l1_ca_dll_pll_tracking_gpu_cc_sptr gps_l1_ca_dll_pll_make_tracking_gpu_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -67,14 +67,14 @@ void Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call } } Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -90,7 +90,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc( d_fs_in = fs_in; d_vector_length = vector_length; d_dump_filename = dump_filename; - d_correlation_length_samples = static_cast(d_vector_length); + d_correlation_length_samples = static_cast(d_vector_length); // Initialize tracking ========================================== d_code_loop_filter.set_DLL_BW(dll_bw_hz); @@ -105,7 +105,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc( //pinned memory mode - use special function to get OS-pinned memory d_n_correlator_taps = 3; // Early, Prompt, and Late // Get space for a vector with the C/A code replica sampled 1x/chip - cudaHostAlloc((void **)&d_ca_code, (static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex)), cudaHostAllocMapped || cudaHostAllocWriteCombined); + cudaHostAlloc((void **)&d_ca_code, (static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex)), cudaHostAllocMapped || cudaHostAllocWriteCombined); // Get space for the resampled early / prompt / late local replicas cudaHostAlloc((void **)&d_local_code_shift_chips, d_n_correlator_taps * sizeof(float), cudaHostAllocMapped || cudaHostAllocWriteCombined); cudaHostAlloc((void **)&in_gpu, 2 * d_vector_length * sizeof(gr_complex), cudaHostAllocMapped || cudaHostAllocWriteCombined); @@ -131,7 +131,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc( d_rem_carrier_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; + d_sample_counter = 0ULL; //d_sample_counter_seconds = 0; d_acq_sample_stamp = 0; @@ -163,7 +163,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc( d_rem_code_phase_chips = 0.0; d_code_phase_step_chips = 0.0; d_carrier_phase_step_rad = 0.0; - //set_min_output_buffer((long int)300); + //set_min_output_buffer((int64_t)300); } @@ -176,9 +176,9 @@ void Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::start_tracking() d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; - long int acq_trk_diff_samples; + int64_t acq_trk_diff_samples; double acq_trk_diff_seconds; - acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; DLOG(INFO) << "Number of samples between Acquisition and Tracking =" << acq_trk_diff_samples; acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); //doppler effect @@ -221,9 +221,9 @@ void Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::start_tracking() // generate local reference ALWAYS starting at chip 1 (1 sample per chip) gps_l1_ca_code_gen_complex(d_ca_code, d_acquisition_gnss_synchro->PRN, 0); - multicorrelator_gpu->set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips, d_n_correlator_taps); + multicorrelator_gpu->set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips, d_n_correlator_taps); - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -283,7 +283,7 @@ Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::~Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc() } -void Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::set_channel(unsigned int channel) +void Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::set_channel(uint32_t channel) { d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -341,17 +341,17 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut // Receiver signal alignment if (d_pull_in == true) { - int samples_offset; + int32_t samples_offset; double acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; + int32_t acq_to_trk_delay_samples; acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; acq_trk_shif_correction_samples = d_correlation_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_correlation_length_samples)); samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(samples_offset); current_synchro_data.fs = d_fs_in; current_synchro_data.correlation_length_ms = 1; *out[0] = current_synchro_data; - d_sample_counter += samples_offset; //count for the processed samples + d_sample_counter += static_cast(samples_offset); //count for the processed samples d_pull_in = false; consume_each(samples_offset); //shift input to perform alignment with local replica return 1; @@ -466,7 +466,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut // ########### Output the tracking data to navigation and PVT ########## current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = GPS_TWO_PI * d_acc_carrier_phase_cycles; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; @@ -476,14 +476,14 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut } else { - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } current_synchro_data.System = {'G'}; current_synchro_data.correlation_length_ms = 1; - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); } //assign the GNURadio block output data @@ -516,7 +516,7 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_cycles * GPS_TWO_PI; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -546,8 +546,8 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut double tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure *e) { diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.h index 85c07a1b4..987af5686 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.h @@ -53,8 +53,8 @@ typedef boost::shared_ptr gps_l1_ca_dll_pll_tracking_gpu_cc_sptr gps_l1_ca_dll_pll_make_tracking_gpu_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -70,7 +70,7 @@ class Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc : public gr::block public: ~Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro); void start_tracking(); @@ -82,8 +82,8 @@ public: private: friend gps_l1_ca_dll_pll_tracking_gpu_cc_sptr gps_l1_ca_dll_pll_make_tracking_gpu_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -91,8 +91,8 @@ private: float early_late_space_chips); Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float pll_bw_hz, @@ -102,18 +102,17 @@ private: void update_local_carrier(); // tracking configuration vars - unsigned int d_vector_length; + uint32_t d_vector_length; bool d_dump; Gnss_Synchro *d_acquisition_gnss_synchro; - unsigned int d_channel; + uint32_t d_channel; - long d_if_freq; - long d_fs_in; + int64_t d_if_freq; + int64_t d_fs_in; double d_early_late_spc_chips; - int d_n_correlator_taps; - + int32_t d_n_correlator_taps; //GPU HOST PINNED MEMORY IN/OUT VECTORS gr_complex *in_gpu; @@ -150,19 +149,19 @@ private: double d_pll_to_dll_assist_secs_Ti; //Integration period in samples - int d_correlation_length_samples; + int32_t d_correlation_length_samples; //processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; + int32_t d_cn0_estimation_counter; gr_complex *d_Prompt_buffer; double d_carrier_lock_test; double d_CN0_SNV_dB_Hz; double d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + int32_t d_carrier_lock_fail_counter; // control vars bool d_enable_tracking; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.cc new file mode 100644 index 000000000..f277bf216 --- /dev/null +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.cc @@ -0,0 +1,958 @@ +/*! + * \file gps_l1_ca_kf_tracking_cc.cc + * \brief Implementation of a processing block of a DLL + Kalman carrier + * tracking loop for GPS L1 C/A signals + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * \author Jordi Vila-Valls 2018. jvila(at)cttc.es + * \author Carles Fernandez-Prades 2018. cfernandez(at)cttc.es + * + * Reference: + * J. Vila-Valls, P. Closas, M. Navarro and C. Fernandez-Prades, + * "Are PLLs Dead? A Tutorial on Kalman Filter-based Techniques for Digital + * Carrier Synchronization", IEEE Aerospace and Electronic Systems Magazine, + * Vol. 32, No. 7, pp. 28–45, July 2017. DOI: 10.1109/MAES.2017.150260 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "gps_l1_ca_kf_tracking_cc.h" +#include "gps_sdr_signal_processing.h" +#include "tracking_discriminators.h" +#include "lock_detectors.h" +#include "gnss_sdr_flags.h" +#include "GPS_L1_CA.h" +#include "control_message_factory.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using google::LogMessage; + +gps_l1_ca_kf_tracking_cc_sptr +gps_l1_ca_kf_make_tracking_cc( + uint32_t order, + int64_t if_freq, + int64_t fs_in, + uint32_t vector_length, + bool dump, + std::string dump_filename, + float dll_bw_hz, + float early_late_space_chips, + bool bce_run, + uint32_t bce_ptrans, + uint32_t bce_strans, + int32_t bce_nu, + int32_t bce_kappa) +{ + return gps_l1_ca_kf_tracking_cc_sptr(new Gps_L1_Ca_Kf_Tracking_cc(order, if_freq, + fs_in, vector_length, dump, dump_filename, dll_bw_hz, early_late_space_chips, + bce_run, bce_ptrans, bce_strans, bce_nu, bce_kappa)); +} + + +void Gps_L1_Ca_Kf_Tracking_cc::forecast(int noutput_items, + gr_vector_int &ninput_items_required) +{ + if (noutput_items != 0) + { + ninput_items_required[0] = static_cast(d_vector_length) * 2; // set the required available samples in each call + } +} + + +Gps_L1_Ca_Kf_Tracking_cc::Gps_L1_Ca_Kf_Tracking_cc( + uint32_t order, + int64_t if_freq, + int64_t fs_in, + uint32_t vector_length, + bool dump, + std::string dump_filename, + float dll_bw_hz, + float early_late_space_chips, + bool bce_run, + uint32_t bce_ptrans, + uint32_t bce_strans, + int32_t bce_nu, + int32_t bce_kappa) : gr::block("Gps_L1_Ca_Kf_Tracking_cc", gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) +{ + // Telemetry bit synchronization message port input + this->message_port_register_in(pmt::mp("preamble_timestamp_s")); + this->message_port_register_out(pmt::mp("events")); + + // initialize internal vars + d_order = order; + d_dump = dump; + d_if_freq = if_freq; + d_fs_in = fs_in; + d_vector_length = vector_length; + d_dump_filename = dump_filename; + + d_current_prn_length_samples = static_cast(d_vector_length); + + // Initialize tracking ========================================== + d_code_loop_filter.set_DLL_BW(dll_bw_hz); + + // --- DLL variables -------------------------------------------------------- + d_early_late_spc_chips = early_late_space_chips; // Define early-late offset (in chips) + + // Initialization of local code replica + // Get space for a vector with the C/A code replica sampled 1x/chip + d_ca_code = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(float), volk_gnsssdr_get_alignment())); + + // correlator outputs (scalar) + d_n_correlator_taps = 3; // Early, Prompt, and Late + d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); + for (int32_t n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs[n] = gr_complex(0, 0); + } + d_local_code_shift_chips = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(float), volk_gnsssdr_get_alignment())); + // Set TAPs delay values [chips] + d_local_code_shift_chips[0] = -d_early_late_spc_chips; + d_local_code_shift_chips[1] = 0.0; + d_local_code_shift_chips[2] = d_early_late_spc_chips; + + multicorrelator_cpu.init(2 * d_current_prn_length_samples, d_n_correlator_taps); + + // --- Perform initializations ------------------------------ + // define initial code frequency basis of NCO + d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ; + // define residual code phase (in chips) + d_rem_code_phase_samples = 0.0; + // define residual carrier phase + d_rem_carr_phase_rad = 0.0; + // define residual carrier phase covariance + d_carr_phase_sigma2 = 0.0; + + // sample synchronization + d_sample_counter = 0; + d_acq_sample_stamp = 0; + + d_enable_tracking = false; + d_pull_in = false; + + // CN0 estimation and lock detector buffers + d_cn0_estimation_counter = 0; + d_Prompt_buffer = new gr_complex[FLAGS_cn0_samples]; + d_carrier_lock_test = 1; + d_CN0_SNV_dB_Hz = 0; + d_carrier_lock_fail_counter = 0; + d_carrier_lock_threshold = FLAGS_carrier_lock_th; + + systemName["G"] = std::string("GPS"); + systemName["S"] = std::string("SBAS"); + + d_acquisition_gnss_synchro = 0; + d_channel = 0; + d_acq_code_phase_samples = 0.0; + d_acq_carrier_doppler_hz = 0.0; + d_carrier_doppler_hz = 0.0; + d_carrier_dopplerrate_hz2 = 0.0; + d_acc_carrier_phase_rad = 0.0; + d_code_phase_samples = 0.0; + d_rem_code_phase_chips = 0.0; + d_code_phase_step_chips = 0.0; + d_code_phase_rate_step_chips = 0.0; + d_carrier_phase_step_rad = 0.0; + code_error_chips = 0.0; + code_error_filt_chips = 0.0; + + set_relative_rate(1.0 / static_cast(d_vector_length)); + + // Kalman filter initialization (receiver initialization) + + double CN_dB_Hz = 30; + double CN_lin = pow(10, CN_dB_Hz / 10.0); + + double sigma2_phase_detector_cycles2; + sigma2_phase_detector_cycles2 = (1.0 / (2.0 * CN_lin * GPS_L1_CA_CODE_PERIOD)) * (1.0 + 1.0 / (2.0 * CN_lin * GPS_L1_CA_CODE_PERIOD)); + + // covariances (static) + double sigma2_carrier_phase = GPS_TWO_PI / 4; + double sigma2_doppler = 450; + double sigma2_doppler_rate = pow(4.0 * GPS_TWO_PI, 2) / 12.0; + + kf_P_x_ini = arma::zeros(2, 2); + kf_P_x_ini(0, 0) = sigma2_carrier_phase; + kf_P_x_ini(1, 1) = sigma2_doppler; + + kf_R = arma::zeros(1, 1); + kf_R(0, 0) = sigma2_phase_detector_cycles2; + + kf_Q = arma::zeros(2, 2); + kf_Q(0, 0) = pow(GPS_L1_CA_CODE_PERIOD, 4); + kf_Q(1, 1) = GPS_L1_CA_CODE_PERIOD; + + kf_F = arma::zeros(2, 2); + kf_F(0, 0) = 1.0; + kf_F(0, 1) = GPS_TWO_PI * GPS_L1_CA_CODE_PERIOD; + kf_F(1, 0) = 0.0; + kf_F(1, 1) = 1.0; + + kf_H = arma::zeros(1, 2); + kf_H(0, 0) = 1.0; + + kf_x = arma::zeros(2, 1); + kf_y = arma::zeros(1, 1); + kf_P_y = arma::zeros(1, 1); + + // order three + if (d_order == 3) + { + kf_P_x_ini = arma::resize(kf_P_x_ini, 3, 3); + kf_P_x_ini(2, 2) = sigma2_doppler_rate; + + kf_Q = arma::zeros(3, 3); + kf_Q(0, 0) = pow(GPS_L1_CA_CODE_PERIOD, 4); + kf_Q(1, 1) = GPS_L1_CA_CODE_PERIOD; + kf_Q(2, 2) = GPS_L1_CA_CODE_PERIOD; + + kf_F = arma::resize(kf_F, 3, 3); + kf_F(0, 2) = 0.5 * GPS_TWO_PI * pow(GPS_L1_CA_CODE_PERIOD, 2); + kf_F(1, 2) = GPS_L1_CA_CODE_PERIOD; + kf_F(2, 0) = 0.0; + kf_F(2, 1) = 0.0; + kf_F(2, 2) = 1.0; + + kf_H = arma::resize(kf_H, 1, 3); + kf_H(0, 2) = 0.0; + + kf_x = arma::resize(kf_x, 3, 1); + kf_x(2, 0) = 0.0; + } + + // Bayesian covariance estimator initialization + kf_iter = 0; + bayes_run = bce_run; + bayes_ptrans = bce_ptrans; + bayes_strans = bce_strans; + + bayes_kappa = bce_kappa; + bayes_nu = bce_nu; + kf_R_est = kf_R; + + bayes_estimator.init(arma::zeros(1, 1), bayes_kappa, bayes_nu, (kf_H * kf_P_x_ini * kf_H.t() + kf_R) * (bayes_nu + 2)); +} + +void Gps_L1_Ca_Kf_Tracking_cc::start_tracking() +{ + /* + * correct the code phase according to the delay between acq and trk + */ + d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples; + d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; + d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; + d_acq_carrier_doppler_step_hz = static_cast(d_acquisition_gnss_synchro->Acq_doppler_step); + + // Correct Kalman filter covariance according to acq doppler step size (3 sigma) + if (d_acquisition_gnss_synchro->Acq_doppler_step > 0) + { + kf_P_x_ini(1, 1) = pow(d_acq_carrier_doppler_step_hz / 3.0, 2); + bayes_estimator.init(arma::zeros(1, 1), bayes_kappa, bayes_nu, (kf_H * kf_P_x_ini * kf_H.t() + kf_R) * (bayes_nu + 2)); + } + + int64_t acq_trk_diff_samples; + double acq_trk_diff_seconds; + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); //-d_vector_length; + DLOG(INFO) << "Number of samples between Acquisition and Tracking = " << acq_trk_diff_samples; + acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); + // Doppler effect Fd = (C / (C + Vr)) * F + double radial_velocity = (GPS_L1_FREQ_HZ + d_acq_carrier_doppler_hz) / GPS_L1_FREQ_HZ; + // new chip and prn sequence periods based on acq Doppler + double T_chip_mod_seconds; + double T_prn_mod_seconds; + double T_prn_mod_samples; + d_code_freq_chips = radial_velocity * GPS_L1_CA_CODE_RATE_HZ; + d_code_phase_step_chips = static_cast(d_code_freq_chips) / static_cast(d_fs_in); + T_chip_mod_seconds = 1 / d_code_freq_chips; + T_prn_mod_seconds = T_chip_mod_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; + T_prn_mod_samples = T_prn_mod_seconds * static_cast(d_fs_in); + + d_current_prn_length_samples = round(T_prn_mod_samples); + + double T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ; + double T_prn_true_samples = T_prn_true_seconds * static_cast(d_fs_in); + double T_prn_diff_seconds = T_prn_true_seconds - T_prn_mod_seconds; + double N_prn_diff = acq_trk_diff_seconds / T_prn_true_seconds; + double corrected_acq_phase_samples, delay_correction_samples; + corrected_acq_phase_samples = fmod((d_acq_code_phase_samples + T_prn_diff_seconds * N_prn_diff * static_cast(d_fs_in)), T_prn_true_samples); + if (corrected_acq_phase_samples < 0) + { + corrected_acq_phase_samples = T_prn_mod_samples + corrected_acq_phase_samples; + } + delay_correction_samples = d_acq_code_phase_samples - corrected_acq_phase_samples; + + d_acq_code_phase_samples = corrected_acq_phase_samples; + + d_carrier_doppler_hz = d_acq_carrier_doppler_hz; + d_carrier_dopplerrate_hz2 = 0; + d_carrier_phase_step_rad = GPS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + + // DLL filter initialization + d_code_loop_filter.initialize(); // initialize the code filter + + // generate local reference ALWAYS starting at chip 1 (1 sample per chip) + gps_l1_ca_code_gen_float(d_ca_code, d_acquisition_gnss_synchro->PRN, 0); + + multicorrelator_cpu.set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); + for (int32_t n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs[n] = gr_complex(0, 0); + } + + d_carrier_lock_fail_counter = 0; + d_rem_code_phase_samples = 0; + d_rem_carr_phase_rad = 0.0; + d_rem_code_phase_chips = 0.0; + d_acc_carrier_phase_rad = 0.0; + d_carr_phase_sigma2 = 0.0; + + d_code_phase_samples = d_acq_code_phase_samples; + + std::string sys_ = &d_acquisition_gnss_synchro->System; + sys = sys_.substr(0, 1); + + // DEBUG OUTPUT + std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << std::endl; + LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; + + // enable tracking + d_pull_in = true; + d_enable_tracking = true; + + LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz + << " Code Phase correction [samples]=" << delay_correction_samples + << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; +} + + +Gps_L1_Ca_Kf_Tracking_cc::~Gps_L1_Ca_Kf_Tracking_cc() +{ + if (d_dump_file.is_open()) + { + try + { + d_dump_file.close(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Exception in destructor " << ex.what(); + } + } + if (d_dump) + { + if (d_channel == 0) + { + std::cout << "Writing .mat files ..."; + } + Gps_L1_Ca_Kf_Tracking_cc::save_matfile(); + if (d_channel == 0) + { + std::cout << " done." << std::endl; + } + } + try + { + volk_gnsssdr_free(d_local_code_shift_chips); + volk_gnsssdr_free(d_correlator_outs); + volk_gnsssdr_free(d_ca_code); + delete[] d_Prompt_buffer; + multicorrelator_cpu.free(); + } + catch (const std::exception &ex) + { + LOG(WARNING) << "Exception in destructor " << ex.what(); + } +} + + +int32_t Gps_L1_Ca_Kf_Tracking_cc::save_matfile() +{ + // READ DUMP FILE + std::ifstream::pos_type size; + int32_t number_of_double_vars = 1; + int32_t number_of_float_vars = 19; + int32_t epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + + sizeof(float) * number_of_float_vars + sizeof(uint32_t); + std::ifstream dump_file; + dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + dump_file.open(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem opening dump file:" << e.what() << std::endl; + return 1; + } + // count number of epochs and rewind + int64_t num_epoch = 0; + if (dump_file.is_open()) + { + size = dump_file.tellg(); + num_epoch = static_cast(size) / static_cast(epoch_size_bytes); + dump_file.seekg(0, std::ios::beg); + } + else + { + return 1; + } + float *abs_VE = new float[num_epoch]; + float *abs_E = new float[num_epoch]; + float *abs_P = new float[num_epoch]; + float *abs_L = new float[num_epoch]; + float *abs_VL = new float[num_epoch]; + float *Prompt_I = new float[num_epoch]; + float *Prompt_Q = new float[num_epoch]; + uint64_t *PRN_start_sample_count = new uint64_t[num_epoch]; + float *acc_carrier_phase_rad = new float[num_epoch]; + float *carrier_doppler_hz = new float[num_epoch]; + float *carrier_dopplerrate_hz2 = new float[num_epoch]; + float *code_freq_chips = new float[num_epoch]; + float *carr_error_hz = new float[num_epoch]; + float *carr_noise_sigma2 = new float[num_epoch]; + float *carr_error_filt_hz = new float[num_epoch]; + float *code_error_chips = new float[num_epoch]; + float *code_error_filt_chips = new float[num_epoch]; + float *CN0_SNV_dB_Hz = new float[num_epoch]; + float *carrier_lock_test = new float[num_epoch]; + float *aux1 = new float[num_epoch]; + double *aux2 = new double[num_epoch]; + uint32_t *PRN = new uint32_t[num_epoch]; + + try + { + if (dump_file.is_open()) + { + for (int64_t i = 0; i < num_epoch; i++) + { + dump_file.read(reinterpret_cast(&abs_VE[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_E[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_P[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_L[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&abs_VL[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_I[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&Prompt_Q[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&PRN_start_sample_count[i]), sizeof(uint64_t)); + dump_file.read(reinterpret_cast(&acc_carrier_phase_rad[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carrier_doppler_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carrier_dopplerrate_hz2[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_freq_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carr_error_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carr_noise_sigma2[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carr_error_filt_hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_error_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&code_error_filt_chips[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&CN0_SNV_dB_Hz[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&carrier_lock_test[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&aux1[i]), sizeof(float)); + dump_file.read(reinterpret_cast(&aux2[i]), sizeof(double)); + dump_file.read(reinterpret_cast(&PRN[i]), sizeof(uint32_t)); + } + } + dump_file.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Problem reading dump file:" << e.what() << std::endl; + delete[] abs_VE; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] abs_VL; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] carrier_dopplerrate_hz2; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_noise_sigma2; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 1; + } + + // WRITE MAT FILE + mat_t *matfp; + matvar_t *matvar; + std::string filename = d_dump_filename; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, static_cast(num_epoch)}; + matvar = Mat_VarCreate("abs_VE", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_VE, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_E", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_E, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_P", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_P, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_L", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_L, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("abs_VL", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, abs_VL, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_I", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_I, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("Prompt_Q", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, Prompt_Q, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN_start_sample_count", MAT_C_UINT64, MAT_T_UINT64, 2, dims, PRN_start_sample_count, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("acc_carrier_phase_rad", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, acc_carrier_phase_rad, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_doppler_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_doppler_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_dopplerrate_hz2", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_dopplerrate_hz2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_freq_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_freq_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_noise_sigma2", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_noise_sigma2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carr_error_filt_hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carr_error_filt_hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("code_error_filt_chips", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, code_error_filt_chips, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("CN0_SNV_dB_Hz", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, CN0_SNV_dB_Hz, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("carrier_lock_test", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, carrier_lock_test, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux1", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, aux1, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("aux2", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aux2, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("PRN", MAT_C_UINT32, MAT_T_UINT32, 2, dims, PRN, 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + delete[] abs_VE; + delete[] abs_E; + delete[] abs_P; + delete[] abs_L; + delete[] abs_VL; + delete[] Prompt_I; + delete[] Prompt_Q; + delete[] PRN_start_sample_count; + delete[] acc_carrier_phase_rad; + delete[] carrier_doppler_hz; + delete[] carrier_dopplerrate_hz2; + delete[] code_freq_chips; + delete[] carr_error_hz; + delete[] carr_noise_sigma2; + delete[] carr_error_filt_hz; + delete[] code_error_chips; + delete[] code_error_filt_chips; + delete[] CN0_SNV_dB_Hz; + delete[] carrier_lock_test; + delete[] aux1; + delete[] aux2; + delete[] PRN; + return 0; +} + + +void Gps_L1_Ca_Kf_Tracking_cc::set_channel(uint32_t channel) +{ + gr::thread::scoped_lock l(d_setlock); + d_channel = channel; + LOG(INFO) << "Tracking Channel set to " << d_channel; + // ############# ENABLE DATA FILE LOG ################# + if (d_dump) + { + if (!d_dump_file.is_open()) + { + try + { + d_dump_filename.append(boost::lexical_cast(d_channel)); + d_dump_filename.append(".dat"); + d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); + LOG(INFO) << "Tracking dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); + } + } + } +} + + +void Gps_L1_Ca_Kf_Tracking_cc::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) +{ + d_acquisition_gnss_synchro = p_gnss_synchro; +} + + +int Gps_L1_Ca_Kf_Tracking_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) +{ + // process vars + d_carr_phase_error_rad = 0.0; + double code_error_chips = 0.0; + double code_error_filt_chips = 0.0; + + // Block input data and block output stream pointers + const gr_complex *in = reinterpret_cast(input_items[0]); + Gnss_Synchro **out = reinterpret_cast(&output_items[0]); + + // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder + Gnss_Synchro current_synchro_data = Gnss_Synchro(); + + if (d_enable_tracking == true) + { + // Fill the acquisition data + current_synchro_data = *d_acquisition_gnss_synchro; + // Receiver signal alignment + if (d_pull_in == true) + { + // Signal alignment (skip samples until the incoming signal is aligned with local replica) + uint64_t acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; + double acq_trk_shif_correction_samples = static_cast(d_current_prn_length_samples) - std::fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_current_prn_length_samples)); + int32_t samples_offset = std::round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); + if (samples_offset < 0) + { + samples_offset = 0; + } + d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * d_acq_code_phase_samples; + + d_sample_counter += samples_offset; // count for the processed samples + d_pull_in = false; + + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.fs = d_fs_in; + current_synchro_data.correlation_length_ms = 1; + *out[0] = current_synchro_data; + // Kalman filter initialization reset + kf_P_x = kf_P_x_ini; + // Update Kalman states based on acquisition information + kf_x(0) = d_carrier_phase_step_rad * samples_offset; + kf_x(1) = d_carrier_doppler_hz; + if (kf_x.n_elem > 2) + { + kf_x(2) = d_carrier_dopplerrate_hz2; + } + + // Covariance estimation initialization reset + kf_iter = 0; + bayes_estimator.init(arma::zeros(1, 1), bayes_kappa, bayes_nu, (kf_H * kf_P_x_ini * kf_H.t() + kf_R) * (bayes_nu + 2)); + + consume_each(samples_offset); // shift input to perform alignment with local replica + return 1; + } + + // ################# CARRIER WIPEOFF AND CORRELATORS ############################## + // Perform carrier wipe-off and compute Early, Prompt and Late correlation + multicorrelator_cpu.set_input_output_vectors(d_correlator_outs, in); + multicorrelator_cpu.Carrier_wipeoff_multicorrelator_resampler(d_rem_carr_phase_rad, + d_carrier_phase_step_rad, + d_rem_code_phase_chips, + d_code_phase_step_chips, + d_code_phase_rate_step_chips, + d_current_prn_length_samples); + + // ################## Kalman Carrier Tracking ###################################### + + // Kalman state prediction (time update) + kf_x_pre = kf_F * kf_x; //state prediction + kf_P_x_pre = kf_F * kf_P_x * kf_F.t() + kf_Q; //state error covariance prediction + + // Update discriminator [rads/Ti] + d_carr_phase_error_rad = pll_cloop_two_quadrant_atan(d_correlator_outs[1]); // prompt output + + // Kalman estimation (measurement update) + double sigma2_phase_detector_cycles2; + double CN_lin = pow(10, d_CN0_SNV_dB_Hz / 10.0); + sigma2_phase_detector_cycles2 = (1.0 / (2.0 * CN_lin * GPS_L1_CA_CODE_PERIOD)) * (1.0 + 1.0 / (2.0 * CN_lin * GPS_L1_CA_CODE_PERIOD)); + + kf_y(0) = d_carr_phase_error_rad; // measurement vector + kf_R(0, 0) = sigma2_phase_detector_cycles2; + + if (bayes_run && (kf_iter >= bayes_ptrans)) + { + bayes_estimator.update_sequential(kf_y); + } + if (bayes_run && (kf_iter >= (bayes_ptrans + bayes_strans))) + { + // TODO: Resolve segmentation fault + kf_P_y = bayes_estimator.get_Psi_est(); + kf_R_est = kf_P_y - kf_H * kf_P_x_pre * kf_H.t(); + } + else + { + kf_P_y = kf_H * kf_P_x_pre * kf_H.t() + kf_R; // innovation covariance matrix + kf_R_est = kf_R; + } + + // Kalman filter update step + kf_K = (kf_P_x_pre * kf_H.t()) * arma::inv(kf_P_y); // Kalman gain + kf_x = kf_x_pre + kf_K * kf_y; // updated state estimation + kf_P_x = (arma::eye(size(kf_P_x_pre)) - kf_K * kf_H) * kf_P_x_pre; // update state estimation error covariance matrix + + // Store Kalman filter results + d_rem_carr_phase_rad = kf_x(0); // set a new carrier Phase estimation to the NCO + d_carrier_doppler_hz = kf_x(1); // set a new carrier Doppler estimation to the NCO + if (kf_x.n_elem > 2) + { + d_carrier_dopplerrate_hz2 = kf_x(2); + } + else + { + d_carrier_dopplerrate_hz2 = 0; + } + d_carr_phase_sigma2 = kf_R_est(0, 0); + + // ################## DLL ########################################################## + // New code Doppler frequency estimation based on carrier frequency estimation + d_code_freq_chips = GPS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GPS_L1_CA_CODE_RATE_HZ) / GPS_L1_FREQ_HZ); + // DLL discriminator + code_error_chips = dll_nc_e_minus_l_normalized(d_correlator_outs[0], d_correlator_outs[2]); // [chips/Ti] early and late + // Code discriminator filter + code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); // [chips/second] + double T_chip_seconds = 1.0 / static_cast(d_code_freq_chips); + double T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS; + double code_error_filt_secs = (T_prn_seconds * code_error_filt_chips * T_chip_seconds); // [seconds] + + // ################## CARRIER AND CODE NCO BUFFER ALIGNMENT ####################### + // keep alignment parameters for the next input buffer + // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation + double T_prn_samples = T_prn_seconds * static_cast(d_fs_in); + double K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in); + d_current_prn_length_samples = static_cast(round(K_blk_samples)); // round to a discrete number of samples + + //################### NCO COMMANDS ################################################# + // carrier phase step (NCO phase increment per sample) [rads/sample] + d_carrier_phase_step_rad = PI_2 * d_carrier_doppler_hz / static_cast(d_fs_in); + // carrier phase accumulator + d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * static_cast(d_current_prn_length_samples); + + //################### DLL COMMANDS ################################################# + // code phase step (Code resampler phase increment per sample) [chips/sample] + d_code_phase_step_chips = d_code_freq_chips / static_cast(d_fs_in); + // remnant code phase [chips] + d_rem_code_phase_samples = K_blk_samples - static_cast(d_current_prn_length_samples); // rounding error < 1 sample + d_rem_code_phase_chips = d_code_freq_chips * (d_rem_code_phase_samples / static_cast(d_fs_in)); + + // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### + if (d_cn0_estimation_counter < FLAGS_cn0_samples) + { + // fill buffer with prompt correlator output values + d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; //prompt + d_cn0_estimation_counter++; + } + else + { + d_cn0_estimation_counter = 0; + // Code lock indicator + d_CN0_SNV_dB_Hz = cn0_svn_estimator(d_Prompt_buffer, FLAGS_cn0_samples, GPS_L1_CA_CODE_PERIOD); + // Carrier lock indicator + d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, FLAGS_cn0_samples); + // Loss of lock detection + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) + { + //if (d_channel == 1) + //std::cout << "Carrier Lock Test Fail in channel " << d_channel << ": " << d_carrier_lock_test << " < " << d_carrier_lock_threshold << "," << nfail++ << std::endl; + d_carrier_lock_fail_counter++; + //nfail++; + } + else + { + if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; + } + if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) + { + std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl; + LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; + this->message_port_pub(pmt::mp("events"), pmt::from_long(3)); // 3 -> loss of lock + d_carrier_lock_fail_counter = 0; + d_enable_tracking = false; + } + } + // ########### Output the tracking data to navigation and PVT ########## + current_synchro_data.Prompt_I = static_cast((d_correlator_outs[1]).real()); + current_synchro_data.Prompt_Q = static_cast((d_correlator_outs[1]).imag()); + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_current_prn_length_samples); + current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; + current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; + current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; + current_synchro_data.Flag_valid_symbol_output = true; + current_synchro_data.correlation_length_ms = 1; + + kf_iter++; + } + else + { + for (int32_t n = 0; n < d_n_correlator_taps; n++) + { + d_correlator_outs[n] = gr_complex(0, 0); + } + + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_current_prn_length_samples); + current_synchro_data.System = {'G'}; + current_synchro_data.correlation_length_ms = 1; + } + + // assign the GNU Radio block output data + current_synchro_data.fs = d_fs_in; + *out[0] = current_synchro_data; + + if (d_dump) + { + // MULTIPLEXED FILE RECORDING - Record results to file + float prompt_I; + float prompt_Q; + float tmp_E, tmp_P, tmp_L; + float tmp_VE = 0.0; + float tmp_VL = 0.0; + float tmp_float; + double tmp_double; + prompt_I = d_correlator_outs[1].real(); + prompt_Q = d_correlator_outs[1].imag(); + tmp_E = std::abs(d_correlator_outs[0]); + tmp_P = std::abs(d_correlator_outs[1]); + tmp_L = std::abs(d_correlator_outs[2]); + try + { + // EPR + d_dump_file.write(reinterpret_cast(&tmp_VE), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_E), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_P), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_L), sizeof(float)); + d_dump_file.write(reinterpret_cast(&tmp_VL), sizeof(float)); + // PROMPT I and Q (to analyze navigation symbols) + d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); + d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); + // PRN start sample stamp + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); + // accumulated carrier phase + tmp_float = d_acc_carrier_phase_rad; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // carrier and code frequency + tmp_float = d_carrier_doppler_hz; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = d_carrier_dopplerrate_hz2; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = d_code_freq_chips; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // Kalman commands + tmp_float = static_cast(d_carr_phase_error_rad * GPS_TWO_PI); + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = static_cast(d_carr_phase_sigma2); + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = static_cast(d_rem_carr_phase_rad * GPS_TWO_PI); + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // DLL commands + tmp_float = code_error_chips; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = code_error_filt_chips; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // CN0 and carrier lock test + tmp_float = d_CN0_SNV_dB_Hz; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_float = d_carrier_lock_test; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + // AUX vars (for debug purposes) + tmp_float = d_rem_code_phase_samples; + d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); + tmp_double = static_cast(d_sample_counter + static_cast(d_current_prn_length_samples)); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + // PRN + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); + } + catch (const std::ifstream::failure &e) + { + LOG(WARNING) << "Exception writing trk dump file " << e.what(); + } + } + + consume_each(d_current_prn_length_samples); // this is necessary in gr::block derivates + d_sample_counter += d_current_prn_length_samples; // count for the processed samples + return 1; // output tracking result ALWAYS even in the case of d_enable_tracking==false +} diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.h new file mode 100644 index 000000000..7f714500e --- /dev/null +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.h @@ -0,0 +1,222 @@ +/*! + * \file gps_l1_ca_kf_tracking_cc.h + * \brief Interface of a processing block of a DLL + Kalman carrier + * tracking loop for GPS L1 C/A signals + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * \author Jordi Vila-Valls 2018. jvila(at)cttc.es + * \author Carles Fernandez-Prades 2018. cfernandez(at)cttc.es + * + * Reference: + * J. Vila-Valls, P. Closas, M. Navarro and C. Fernandez-Prades, + * "Are PLLs Dead? A Tutorial on Kalman Filter-based Techniques for Digital + * Carrier Synchronization", IEEE Aerospace and Electronic Systems Magazine, + * Vol. 32, No. 7, pp. 28–45, July 2017. DOI: 10.1109/MAES.2017.150260 + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GPS_L1_CA_KF_TRACKING_CC_H +#define GNSS_SDR_GPS_L1_CA_KF_TRACKING_CC_H + +#include "gnss_synchro.h" +#include "tracking_2nd_DLL_filter.h" +#include "tracking_2nd_PLL_filter.h" +#include "cpu_multicorrelator_real_codes.h" +#include "bayesian_estimation.h" +#include +#include +#include +#include +#include + +class Gps_L1_Ca_Kf_Tracking_cc; + +typedef boost::shared_ptr + gps_l1_ca_kf_tracking_cc_sptr; + +gps_l1_ca_kf_tracking_cc_sptr +gps_l1_ca_kf_make_tracking_cc(uint32_t order, + int64_t if_freq, + int64_t fs_in, uint32_t vector_length, + bool dump, + std::string dump_filename, + float pll_bw_hz, + float early_late_space_chips, + bool bce_run, + uint32_t bce_ptrans, + uint32_t bce_strans, + int32_t bce_nu, + int32_t bce_kappa); + + +/*! + * \brief This class implements a DLL + PLL tracking loop block + */ +class Gps_L1_Ca_Kf_Tracking_cc : public gr::block +{ +public: + ~Gps_L1_Ca_Kf_Tracking_cc(); + + void set_channel(uint32_t channel); + void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro); + void start_tracking(); + + int general_work(int noutput_items, gr_vector_int& ninput_items, + gr_vector_const_void_star& input_items, gr_vector_void_star& output_items); + + void forecast(int noutput_items, gr_vector_int& ninput_items_required); + +private: + friend gps_l1_ca_kf_tracking_cc_sptr + gps_l1_ca_kf_make_tracking_cc(uint32_t order, + int64_t if_freq, + int64_t fs_in, uint32_t vector_length, + bool dump, + std::string dump_filename, + float dll_bw_hz, + float early_late_space_chips, + bool bce_run, + uint32_t bce_ptrans, + uint32_t bce_strans, + int32_t bce_nu, + int32_t bce_kappa); + + Gps_L1_Ca_Kf_Tracking_cc(uint32_t order, + int64_t if_freq, + int64_t fs_in, uint32_t vector_length, + bool dump, + std::string dump_filename, + float dll_bw_hz, + float early_late_space_chips, + bool bce_run, + uint32_t bce_ptrans, + uint32_t bce_strans, + int32_t bce_nu, + int32_t bce_kappa); + + // tracking configuration vars + uint32_t d_order; + uint32_t d_vector_length; + bool d_dump; + + Gnss_Synchro* d_acquisition_gnss_synchro; + uint32_t d_channel; + + int64_t d_if_freq; + int64_t d_fs_in; + + double d_early_late_spc_chips; + + // remaining code phase and carrier phase between tracking loops + double d_rem_code_phase_samples; + double d_rem_code_phase_chips; + double d_rem_carr_phase_rad; + + // Kalman filter variables + arma::mat kf_P_x_ini; // initial state error covariance matrix + arma::mat kf_P_x; // state error covariance matrix + arma::mat kf_P_x_pre; // Predicted state error covariance matrix + arma::mat kf_P_y; // innovation covariance matrix + + arma::mat kf_F; // state transition matrix + arma::mat kf_H; // system matrix + arma::mat kf_R; // measurement error covariance matrix + arma::mat kf_Q; // system error covariance matrix + + arma::colvec kf_x; // state vector + arma::colvec kf_x_pre; // predicted state vector + arma::colvec kf_y; // measurement vector + arma::mat kf_K; // Kalman gain matrix + + // Bayesian estimator + Bayesian_estimator bayes_estimator; + arma::mat kf_R_est; // measurement error covariance + uint32_t bayes_ptrans; + uint32_t bayes_strans; + int32_t bayes_nu; + int32_t bayes_kappa; + + bool bayes_run; + uint32_t kf_iter; + + // PLL and DLL filter library + Tracking_2nd_DLL_filter d_code_loop_filter; + // Tracking_2nd_PLL_filter d_carrier_loop_filter; + + // acquisition + double d_acq_carrier_doppler_step_hz; + double d_acq_code_phase_samples; + double d_acq_carrier_doppler_hz; + // correlator + int32_t d_n_correlator_taps; + float* d_ca_code; + float* d_local_code_shift_chips; + gr_complex* d_correlator_outs; + cpu_multicorrelator_real_codes multicorrelator_cpu; + + // tracking vars + double d_code_freq_chips; + double d_code_phase_step_chips; + double d_code_phase_rate_step_chips; + double d_carrier_doppler_hz; + double d_carrier_dopplerrate_hz2; + double d_carrier_phase_step_rad; + double d_acc_carrier_phase_rad; + double d_carr_phase_error_rad; + double d_carr_phase_sigma2; + double d_code_phase_samples; + double code_error_chips; + double code_error_filt_chips; + + // PRN period in samples + int32_t d_current_prn_length_samples; + + // processing samples counters + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; + + // CN0 estimation and lock detector + int32_t d_cn0_estimation_counter; + gr_complex* d_Prompt_buffer; + double d_carrier_lock_test; + double d_CN0_SNV_dB_Hz; + double d_carrier_lock_threshold; + int32_t d_carrier_lock_fail_counter; + + // control vars + bool d_enable_tracking; + bool d_pull_in; + + // file dump + std::string d_dump_filename; + std::ofstream d_dump_file; + + std::map systemName; + std::string sys; + + int32_t save_matfile(); +}; + +#endif // GNSS_SDR_GPS_L1_CA_KF_TRACKING_CC_H diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc index c99990cfc..232fc7aa8 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc @@ -58,8 +58,8 @@ using google::LogMessage; gps_l1_ca_tcp_connector_tracking_cc_sptr gps_l1_ca_tcp_connector_make_tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float early_late_space_chips, @@ -75,14 +75,14 @@ void Gps_L1_Ca_Tcp_Connector_Tracking_cc::forecast(int noutput_items, { if (noutput_items != 0) { - ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call + ninput_items_required[0] = static_cast(d_vector_length) * 2; //set the required available samples in each call } } Gps_L1_Ca_Tcp_Connector_Tracking_cc::Gps_L1_Ca_Tcp_Connector_Tracking_cc( - long fs_in, - unsigned int vector_length, + int64_t fs_in, + uint32_t vector_length, bool dump, std::string dump_filename, float early_late_space_chips, @@ -112,7 +112,7 @@ Gps_L1_Ca_Tcp_Connector_Tracking_cc::Gps_L1_Ca_Tcp_Connector_Tracking_cc( // correlator outputs (scalar) d_n_correlator_taps = 3; // Very-Early, Early, Prompt, Late, Very-Late d_correlator_outs = static_cast(volk_gnsssdr_malloc(d_n_correlator_taps * sizeof(gr_complex), volk_gnsssdr_get_alignment())); - for (int n = 0; n < d_n_correlator_taps; n++) + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -140,14 +140,14 @@ Gps_L1_Ca_Tcp_Connector_Tracking_cc::Gps_L1_Ca_Tcp_Connector_Tracking_cc( d_rem_carr_phase_rad = 0.0; // sample synchronization - d_sample_counter = 0; + d_sample_counter = 0ULL; d_sample_counter_seconds = 0; - d_acq_sample_stamp = 0; + d_acq_sample_stamp = 0ULL; d_enable_tracking = false; d_pull_in = false; - d_current_prn_length_samples = static_cast(d_vector_length); + d_current_prn_length_samples = static_cast(d_vector_length); // CN0 estimation and lock detector buffers d_cn0_estimation_counter = 0; @@ -186,9 +186,9 @@ void Gps_L1_Ca_Tcp_Connector_Tracking_cc::start_tracking() d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples; - long int acq_trk_diff_samples; + int64_t acq_trk_diff_samples; float acq_trk_diff_seconds; - acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); + acq_trk_diff_samples = static_cast(d_sample_counter) - static_cast(d_acq_sample_stamp); std::cout << "acq_trk_diff_samples=" << acq_trk_diff_samples << std::endl; acq_trk_diff_seconds = static_cast(acq_trk_diff_samples) / static_cast(d_fs_in); //doppler effect @@ -227,8 +227,8 @@ void Gps_L1_Ca_Tcp_Connector_Tracking_cc::start_tracking() // generate local reference ALWAYS starting at chip 1 (1 sample per chip) gps_l1_ca_code_gen_complex(d_ca_code, d_acquisition_gnss_synchro->PRN, 0); - multicorrelator_cpu.set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); - for (int n = 0; n < d_n_correlator_taps; n++) + multicorrelator_cpu.set_local_code_and_taps(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS), d_ca_code, d_local_code_shift_chips); + for (int32_t n = 0; n < d_n_correlator_taps; n++) { d_correlator_outs[n] = gr_complex(0, 0); } @@ -288,7 +288,7 @@ Gps_L1_Ca_Tcp_Connector_Tracking_cc::~Gps_L1_Ca_Tcp_Connector_Tracking_cc() } -void Gps_L1_Ca_Tcp_Connector_Tracking_cc::set_channel(unsigned int channel) +void Gps_L1_Ca_Tcp_Connector_Tracking_cc::set_channel(uint32_t channel) { d_channel = channel; LOG(INFO) << "Tracking Channel set to " << d_channel; @@ -352,19 +352,19 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attrib */ if (d_pull_in == true) { - int samples_offset; + int32_t samples_offset; // 28/11/2011 ACQ to TRK transition BUG CORRECTION float acq_trk_shif_correction_samples; - int acq_to_trk_delay_samples; + int32_t acq_to_trk_delay_samples; acq_to_trk_delay_samples = d_sample_counter - d_acq_sample_stamp; acq_trk_shif_correction_samples = d_next_prn_length_samples - fmod(static_cast(acq_to_trk_delay_samples), static_cast(d_next_prn_length_samples)); samples_offset = round(d_acq_code_phase_samples + acq_trk_shif_correction_samples); - current_synchro_data.Tracking_sample_counter = d_sample_counter + samples_offset; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(samples_offset); current_synchro_data.fs = d_fs_in; *out[0] = current_synchro_data; d_sample_counter_seconds = d_sample_counter_seconds + (static_cast(samples_offset) / static_cast(d_fs_in)); - d_sample_counter = d_sample_counter + samples_offset; //count for the processed samples + d_sample_counter = d_sample_counter + static_cast(samples_offset); //count for the processed samples d_pull_in = false; consume_each(samples_offset); //shift input to perform alignment with local replica return 1; @@ -480,7 +480,7 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attrib current_synchro_data.Prompt_Q = static_cast((*d_Prompt).imag()); //compute remnant code phase samples AFTER the Tracking timestamp d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_current_prn_length_samples); current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = static_cast(d_acc_carrier_phase_rad); current_synchro_data.Carrier_Doppler_hz = static_cast(d_carrier_doppler_hz); @@ -494,7 +494,7 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attrib *d_Prompt = gr_complex(0, 0); *d_Late = gr_complex(0, 0); // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder - current_synchro_data.Tracking_sample_counter = d_sample_counter + d_correlation_length_samples; + current_synchro_data.Tracking_sample_counter = d_sample_counter + static_cast(d_correlation_length_samples); //! When tracking is disabled an array of 1's is sent to maintain the TCP connection boost::array tx_variables_array = {{1, 1, 1, 1, 1, 1, 1, 1, 0}}; d_tcp_com.send_receive_tcp_packet_gps_l1_ca(tx_variables_array, &tcp_data); @@ -535,7 +535,7 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attrib d_dump_file.write(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.write(reinterpret_cast(&prompt_Q), sizeof(float)); // PRN start sample stamp - d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(unsigned long int)); + d_dump_file.write(reinterpret_cast(&d_sample_counter), sizeof(uint64_t)); // accumulated carrier phase tmp_float = d_acc_carrier_phase_rad; d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); @@ -565,8 +565,8 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attrib double tmp_double = static_cast(d_sample_counter + d_correlation_length_samples); d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); // PRN - unsigned int prn_ = d_acquisition_gnss_synchro->PRN; - d_dump_file.write(reinterpret_cast(&prn_), sizeof(unsigned int)); + uint32_t prn_ = d_acquisition_gnss_synchro->PRN; + d_dump_file.write(reinterpret_cast(&prn_), sizeof(uint32_t)); } catch (const std::ifstream::failure &e) { diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.h index 089df2be2..f946ed0c8 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.h @@ -52,7 +52,7 @@ typedef boost::shared_ptr gps_l1_ca_tcp_con gps_l1_ca_tcp_connector_tracking_cc_sptr gps_l1_ca_tcp_connector_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float early_late_space_chips, @@ -67,7 +67,7 @@ class Gps_L1_Ca_Tcp_Connector_Tracking_cc : public gr::block public: ~Gps_L1_Ca_Tcp_Connector_Tracking_cc(); - void set_channel(unsigned int channel); + void set_channel(uint32_t channel); void set_gnss_synchro(Gnss_Synchro *p_gnss_synchro); void start_tracking(); @@ -84,29 +84,29 @@ public: private: friend gps_l1_ca_tcp_connector_tracking_cc_sptr gps_l1_ca_tcp_connector_make_tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float early_late_space_chips, size_t port_ch0); Gps_L1_Ca_Tcp_Connector_Tracking_cc( - long fs_in, unsigned int vector_length, + int64_t fs_in, uint32_t vector_length, bool dump, std::string dump_filename, float early_late_space_chips, size_t port_ch0); // tracking configuration vars - unsigned int d_vector_length; + uint32_t d_vector_length; bool d_dump; Gnss_Synchro *d_acquisition_gnss_synchro; - unsigned int d_channel; + uint32_t d_channel; - long d_fs_in; - int d_correlation_length_samples; - int d_n_correlator_taps; + int64_t d_fs_in; + int32_t d_correlation_length_samples; + int32_t d_n_correlator_taps; double d_early_late_spc_chips; double d_code_phase_step_chips; @@ -137,26 +137,26 @@ private: double d_code_phase_samples; size_t d_port_ch0; size_t d_port; - int d_listen_connection; + int32_t d_listen_connection; float d_control_id; tcp_communication d_tcp_com; //PRN period in samples - int d_current_prn_length_samples; - int d_next_prn_length_samples; + int32_t d_current_prn_length_samples; + int32_t d_next_prn_length_samples; double d_sample_counter_seconds; //processing samples counters - unsigned long int d_sample_counter; - unsigned long int d_acq_sample_stamp; + uint64_t d_sample_counter; + uint64_t d_acq_sample_stamp; // CN0 estimation and lock detector - int d_cn0_estimation_counter; + int32_t d_cn0_estimation_counter; gr_complex *d_Prompt_buffer; float d_carrier_lock_test; float d_CN0_SNV_dB_Hz; float d_carrier_lock_threshold; - int d_carrier_lock_fail_counter; + int32_t d_carrier_lock_fail_counter; // control vars bool d_enable_tracking; diff --git a/src/algorithms/tracking/libs/CMakeLists.txt b/src/algorithms/tracking/libs/CMakeLists.txt index fdb35a4e9..6991fbd55 100644 --- a/src/algorithms/tracking/libs/CMakeLists.txt +++ b/src/algorithms/tracking/libs/CMakeLists.txt @@ -22,64 +22,89 @@ if(ENABLE_CUDA) # set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} --gpu-architecture sm_30) list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_30,code=sm_30; -std=c++11;-O3; -use_fast_math -default-stream per-thread") set(CUDA_PROPAGATE_HOST_FLAGS OFF) - CUDA_INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}) + cuda_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) set(LIB_TYPE STATIC) #set the lib type - CUDA_ADD_LIBRARY(CUDA_CORRELATOR_LIB ${LIB_TYPE} cuda_multicorrelator.h cuda_multicorrelator.cu) + cuda_add_library(CUDA_CORRELATOR_LIB ${LIB_TYPE} cuda_multicorrelator.h cuda_multicorrelator.cu) set(OPT_TRACKING_LIBRARIES ${OPT_TRACKING_LIBRARIES} CUDA_CORRELATOR_LIB) - set(OPT_TRACKING_INCLUDES ${OPT_TRACKING_INCLUDES} ${CUDA_INCLUDE_DIRS} ) -endif(ENABLE_CUDA) - - + set(OPT_TRACKING_INCLUDES ${OPT_TRACKING_INCLUDES} ${CUDA_INCLUDE_DIRS}) +endif() set(TRACKING_LIB_SOURCES - cpu_multicorrelator.cc - cpu_multicorrelator_real_codes.cc - cpu_multicorrelator_16sc.cc - lock_detectors.cc - tcp_communication.cc - tcp_packet_data.cc - tracking_2nd_DLL_filter.cc - tracking_2nd_PLL_filter.cc - tracking_discriminators.cc - tracking_FLL_PLL_filter.cc - tracking_loop_filter.cc - dll_pll_conf.cc + cpu_multicorrelator.cc + cpu_multicorrelator_real_codes.cc + cpu_multicorrelator_16sc.cc + lock_detectors.cc + tcp_communication.cc + tcp_packet_data.cc + tracking_2nd_DLL_filter.cc + tracking_2nd_PLL_filter.cc + tracking_discriminators.cc + tracking_FLL_PLL_filter.cc + tracking_loop_filter.cc + dll_pll_conf.cc + bayesian_estimation.cc +) + +set(TRACKING_LIB_HEADERS + cpu_multicorrelator.h + cpu_multicorrelator_real_codes.h + cpu_multicorrelator_16sc.h + lock_detectors.h + tcp_communication.h + tcp_packet_data.h + tracking_2nd_DLL_filter.h + tracking_2nd_PLL_filter.h + tracking_discriminators.h + tracking_FLL_PLL_filter.h + tracking_loop_filter.h + dll_pll_conf.h + bayesian_estimation.h ) if(ENABLE_FPGA) - SET(TRACKING_LIB_SOURCES ${TRACKING_LIB_SOURCES} fpga_multicorrelator.cc) -endif(ENABLE_FPGA) + set(TRACKING_LIB_SOURCES ${TRACKING_LIB_SOURCES} fpga_multicorrelator.cc dll_pll_conf_fpga.cc) + set(TRACKING_LIB_HEADERS ${TRACKING_LIB_HEADERS} fpga_multicorrelator.h dll_pll_conf_fpga.h) +endif() include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${VOLK_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${OPT_TRACKING_INCLUDES} - ${VOLK_GNSSSDR_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${ARMADILLO_INCLUDE_DIRS} + ${VOLK_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${OPT_TRACKING_INCLUDES} + ${VOLK_GNSSSDR_INCLUDE_DIRS} ) if(ENABLE_GENERIC_ARCH) - add_definitions( -DGENERIC_ARCH=1 ) -endif(ENABLE_GENERIC_ARCH) + add_definitions(-DGENERIC_ARCH=1) +endif() -if (SSE3_AVAILABLE) - add_definitions( -DHAVE_SSE3=1 ) -endif(SSE3_AVAILABLE) +if(SSE3_AVAILABLE) + add_definitions(-DHAVE_SSE3=1) +endif() - -file(GLOB TRACKING_LIB_HEADERS "*.h") list(SORT TRACKING_LIB_HEADERS) -add_library(tracking_lib ${TRACKING_LIB_SOURCES} ${TRACKING_LIB_HEADERS}) -source_group(Headers FILES ${TRACKING_LIB_HEADERS}) -target_link_libraries(tracking_lib ${OPT_TRACKING_LIBRARIES} ${VOLK_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES}) +list(SORT TRACKING_LIB_SOURCES) -if(VOLK_GNSSSDR_FOUND) +add_library(tracking_lib ${TRACKING_LIB_SOURCES} ${TRACKING_LIB_HEADERS}) + +source_group(Headers FILES ${TRACKING_LIB_HEADERS}) + +target_link_libraries(tracking_lib + ${OPT_TRACKING_LIBRARIES} + ${VOLK_LIBRARIES} + ${VOLK_GNSSSDR_LIBRARIES} + ${Boost_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} +) + +if(VOLKGNSSSDR_FOUND) add_dependencies(tracking_lib glog-${glog_RELEASE}) -else(VOLK_GNSSSDR_FOUND) +else() add_dependencies(tracking_lib glog-${glog_RELEASE} volk_gnsssdr_module) endif() diff --git a/src/algorithms/tracking/libs/bayesian_estimation.cc b/src/algorithms/tracking/libs/bayesian_estimation.cc new file mode 100644 index 000000000..30e7d45ec --- /dev/null +++ b/src/algorithms/tracking/libs/bayesian_estimation.cc @@ -0,0 +1,187 @@ +/*! + * \file bayesian_estimation.cc + * \brief Interface of a library with Bayesian noise statistic estimation + * + * Bayesian_estimator is a Bayesian estimator which attempts to estimate + * the properties of a stochastic process based on a sequence of + * discrete samples of the sequence. + * + * [1] TODO: Refs + * + * \authors
        + *
      • Gerald LaMountain, 2018. gerald(at)ece.neu.edu + *
      • Jordi Vila-Valls 2018. jvila(at)cttc.es + *
      + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "bayesian_estimation.h" + + +Bayesian_estimator::Bayesian_estimator() +{ + int ny = 1; + mu_prior = arma::zeros(ny, 1); + kappa_prior = 0; + nu_prior = 0; + Psi_prior = arma::eye(ny, ny) * (nu_prior + ny + 1); + + mu_est = mu_prior; + Psi_est = Psi_prior; +} + +Bayesian_estimator::Bayesian_estimator(int ny) +{ + mu_prior = arma::zeros(ny, 1); + kappa_prior = 0; + nu_prior = 0; + Psi_prior = arma::eye(ny, ny) * (nu_prior + ny + 1); + + mu_est = mu_prior; + Psi_est = Psi_prior; +} + +Bayesian_estimator::Bayesian_estimator(const arma::vec& mu_prior_0, int kappa_prior_0, int nu_prior_0, const arma::mat& Psi_prior_0) +{ + mu_prior = mu_prior_0; + kappa_prior = kappa_prior_0; + nu_prior = nu_prior_0; + Psi_prior = Psi_prior_0; + + mu_est = mu_prior; + Psi_est = Psi_prior; +} + +Bayesian_estimator::~Bayesian_estimator() +{ +} + +void Bayesian_estimator::init(const arma::mat& mu_prior_0, int kappa_prior_0, int nu_prior_0, const arma::mat& Psi_prior_0) +{ + mu_prior = mu_prior_0; + kappa_prior = kappa_prior_0; + nu_prior = nu_prior_0; + Psi_prior = Psi_prior_0; + + mu_est = mu_prior; + Psi_est = Psi_prior; +} + +/* + * Perform Bayesian noise estimation using the normal-inverse-Wishart priors stored in + * the class structure, and update the priors according to the computed posteriors + */ +void Bayesian_estimator::update_sequential(const arma::vec& data) +{ + int K = data.n_cols; + int ny = data.n_rows; + + if (mu_prior.is_empty()) + { + mu_prior = arma::zeros(ny, 1); + } + + if (Psi_prior.is_empty()) + { + Psi_prior = arma::zeros(ny, ny); + } + + arma::vec y_mean = arma::mean(data, 1); + arma::mat Psi_N = arma::zeros(ny, ny); + + for (int kk = 0; kk < K; kk++) + { + Psi_N = Psi_N + (data.col(kk) - y_mean) * ((data.col(kk) - y_mean).t()); + } + + arma::vec mu_posterior = (kappa_prior * mu_prior + K * y_mean) / (kappa_prior + K); + int kappa_posterior = kappa_prior + K; + int nu_posterior = nu_prior + K; + arma::mat Psi_posterior = Psi_prior + Psi_N + (kappa_prior * K) / (kappa_prior + K) * (y_mean - mu_prior) * ((y_mean - mu_prior).t()); + + mu_est = mu_posterior; + if ((nu_posterior - ny - 1) > 0) + { + Psi_est = Psi_posterior / (nu_posterior - ny - 1); + } + else + { + Psi_est = Psi_posterior / (nu_posterior + ny + 1); + } + + mu_prior = mu_posterior; + kappa_prior = kappa_posterior; + nu_prior = nu_posterior; + Psi_prior = Psi_posterior; +} + + +/* + * Perform Bayesian noise estimation using a new set of normal-inverse-Wishart priors + * and update the priors according to the computed posteriors + */ +void Bayesian_estimator::update_sequential(const arma::vec& data, const arma::vec& mu_prior_0, int kappa_prior_0, int nu_prior_0, const arma::mat& Psi_prior_0) +{ + int K = data.n_cols; + int ny = data.n_rows; + + arma::vec y_mean = arma::mean(data, 1); + arma::mat Psi_N = arma::zeros(ny, ny); + + for (int kk = 0; kk < K; kk++) + { + Psi_N = Psi_N + (data.col(kk) - y_mean) * ((data.col(kk) - y_mean).t()); + } + + arma::vec mu_posterior = (kappa_prior_0 * mu_prior_0 + K * y_mean) / (kappa_prior_0 + K); + int kappa_posterior = kappa_prior_0 + K; + int nu_posterior = nu_prior_0 + K; + arma::mat Psi_posterior = Psi_prior_0 + Psi_N + (kappa_prior_0 * K) / (kappa_prior_0 + K) * (y_mean - mu_prior_0) * ((y_mean - mu_prior_0).t()); + + mu_est = mu_posterior; + if ((nu_posterior - ny - 1) > 0) + { + Psi_est = Psi_posterior / (nu_posterior - ny - 1); + } + else + { + Psi_est = Psi_posterior / (nu_posterior + ny + 1); + } + + mu_prior = mu_posterior; + kappa_prior = kappa_posterior; + nu_prior = nu_posterior; + Psi_prior = Psi_posterior; +} + +arma::mat Bayesian_estimator::get_mu_est() const +{ + return mu_est; +} + +arma::mat Bayesian_estimator::get_Psi_est() const +{ + return Psi_est; +} diff --git a/src/algorithms/tracking/libs/bayesian_estimation.h b/src/algorithms/tracking/libs/bayesian_estimation.h new file mode 100644 index 000000000..002e7a75c --- /dev/null +++ b/src/algorithms/tracking/libs/bayesian_estimation.h @@ -0,0 +1,85 @@ +/*! + * \file bayesian_estimation.h + * \brief Interface of a library with Bayesian noise statistic estimation + * + * Bayesian_estimator is a Bayesian estimator which attempts to estimate + * the properties of a stochastic process based on a sequence of + * discrete samples of the sequence. + * + * [1] TODO: Refs + * + * \authors
        + *
      • Gerald LaMountain, 2018. gerald(at)ece.neu.edu + *
      • Jordi Vila-Valls 2018. jvila(at)cttc.es + *
      + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_BAYESIAN_ESTIMATION_H_ +#define GNSS_SDR_BAYESIAN_ESTIMATION_H_ + +#include +#include + +/*! \brief Bayesian_estimator is an estimator of noise characteristics (i.e. mean, covariance) + * + * Bayesian_estimator is an estimator which performs estimation of noise characteristics from + * a sequence of identically and independently distributed (IID) samples of a stationary + * stochastic process by way of Bayesian inference using conjugate priors. The posterior + * distribution is assumed to be Gaussian with mean \mathbf{\mu} and covariance \hat{\mathbf{C}}, + * which has a conjugate prior given by a normal-inverse-Wishart distribution with paramemters + * \mathbf{\mu}_{0}, \kappa_{0}, \nu_{0}, and \mathbf{\Psi}. + * + * [1] TODO: Ref1 + * + */ + +class Bayesian_estimator +{ +public: + Bayesian_estimator(); + Bayesian_estimator(int ny); + Bayesian_estimator(const arma::vec& mu_prior_0, int kappa_prior_0, int nu_prior_0, const arma::mat& Psi_prior_0); + ~Bayesian_estimator(); + + void init(const arma::mat& mu_prior_0, int kappa_prior_0, int nu_prior_0, const arma::mat& Psi_prior_0); + + void update_sequential(const arma::vec& data); + void update_sequential(const arma::vec& data, const arma::vec& mu_prior_0, int kappa_prior_0, int nu_prior_0, const arma::mat& Psi_prior_0); + + arma::mat get_mu_est() const; + arma::mat get_Psi_est() const; + +private: + arma::vec mu_est; + arma::mat Psi_est; + + arma::vec mu_prior; + int kappa_prior; + int nu_prior; + arma::mat Psi_prior; +}; + +#endif diff --git a/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc b/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc index dc65db462..f23537fad 100644 --- a/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc +++ b/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.cc @@ -1,6 +1,6 @@ /*! * \file cpu_multicorrelator_real_codes.cc - * \brief High optimized CPU vector multiTAP correlator class with real-valued local codes + * \brief Highly optimized CPU vector multiTAP correlator class with real-valued local codes * \authors
        *
      • Javier Arribas, 2015. jarribas(at)cttc.es *
      • Cillian O'Driscoll, 2017. cillian.odriscoll(at)gmail.com @@ -37,7 +37,6 @@ #include #include - cpu_multicorrelator_real_codes::cpu_multicorrelator_real_codes() { d_sig_in = nullptr; @@ -47,6 +46,7 @@ cpu_multicorrelator_real_codes::cpu_multicorrelator_real_codes() d_local_codes_resampled = nullptr; d_code_length_chips = 0; d_n_correlators = 0; + d_use_high_dynamics_resampler = true; } @@ -84,6 +84,7 @@ bool cpu_multicorrelator_real_codes::set_local_code_and_taps( d_local_code_in = local_code_in; d_shifts_chips = shifts_chips; d_code_length_chips = code_length_chips; + return true; } @@ -97,27 +98,68 @@ bool cpu_multicorrelator_real_codes::set_input_output_vectors(std::complex(d_local_codes_resampled), d_n_correlators, signal_length_samples); + } + else + { + volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn(d_corr_out, d_sig_in, std::exp(lv_32fc_t(0.0, -phase_step_rad)), phase_offset_as_complex, const_cast(d_local_codes_resampled), d_n_correlators, signal_length_samples); + } + return true; +} +// Overload Carrier_wipeoff_multicorrelator_resampler to ensure back compatibility bool cpu_multicorrelator_real_codes::Carrier_wipeoff_multicorrelator_resampler( float rem_carrier_phase_in_rad, float phase_step_rad, float rem_code_phase_chips, float code_phase_step_chips, + float code_phase_rate_step_chips, int signal_length_samples) { - update_local_code(signal_length_samples, rem_code_phase_chips, code_phase_step_chips); + update_local_code(signal_length_samples, rem_code_phase_chips, code_phase_step_chips, code_phase_rate_step_chips); // Regenerate phase at each call in order to avoid numerical issues lv_32fc_t phase_offset_as_complex[1]; phase_offset_as_complex[0] = lv_cmake(std::cos(rem_carrier_phase_in_rad), -std::sin(rem_carrier_phase_in_rad)); @@ -141,3 +183,10 @@ bool cpu_multicorrelator_real_codes::free() } return true; } + + +void cpu_multicorrelator_real_codes::set_high_dynamics_resampler( + bool use_high_dynamics_resampler) +{ + d_use_high_dynamics_resampler = use_high_dynamics_resampler; +} diff --git a/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.h b/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.h index 50b5085f7..a4dfdd5f0 100644 --- a/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.h +++ b/src/algorithms/tracking/libs/cpu_multicorrelator_real_codes.h @@ -1,6 +1,6 @@ /*! * \file cpu_multicorrelator_real_codes.h - * \brief High optimized CPU vector multiTAP correlator class using real-valued local codes + * \brief Highly optimized CPU vector multiTAP correlator class using real-valued local codes * \authors
          *
        • Javier Arribas, 2015. jarribas(at)cttc.es *
        • Cillian O'Driscoll, 2017, cillian.odriscoll(at)gmail.com @@ -46,12 +46,15 @@ class cpu_multicorrelator_real_codes { public: cpu_multicorrelator_real_codes(); + void set_high_dynamics_resampler(bool use_high_dynamics_resampler); ~cpu_multicorrelator_real_codes(); bool init(int max_signal_length_samples, int n_correlators); bool set_local_code_and_taps(int code_length_chips, const float *local_code_in, float *shifts_chips); bool set_input_output_vectors(std::complex *corr_out, const std::complex *sig_in); - void update_local_code(int correlator_length_samples, float rem_code_phase_chips, float code_phase_step_chips); - bool Carrier_wipeoff_multicorrelator_resampler(float rem_carrier_phase_in_rad, float phase_step_rad, float rem_code_phase_chips, float code_phase_step_chips, int signal_length_samples); + void update_local_code(int correlator_length_samples, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips = 0.0); + // Overload Carrier_wipeoff_multicorrelator_resampler to ensure back compatibility + bool Carrier_wipeoff_multicorrelator_resampler(float rem_carrier_phase_in_rad, float phase_step_rad, float phase_rate_step_rad, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, int signal_length_samples); + bool Carrier_wipeoff_multicorrelator_resampler(float rem_carrier_phase_in_rad, float phase_step_rad, float rem_code_phase_chips, float code_phase_step_chips, float code_phase_rate_step_chips, int signal_length_samples); bool free(); private: @@ -61,6 +64,7 @@ private: const float *d_local_code_in; std::complex *d_corr_out; float *d_shifts_chips; + bool d_use_high_dynamics_resampler; int d_code_length_chips; int d_n_correlators; }; diff --git a/src/algorithms/tracking/libs/dll_pll_conf.cc b/src/algorithms/tracking/libs/dll_pll_conf.cc index 89c6a1256..77c0b48a3 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf.cc @@ -36,11 +36,16 @@ Dll_Pll_Conf::Dll_Pll_Conf() { /* DLL/PLL tracking configuration */ + high_dyn = false; + smoother_length = 10; fs_in = 0.0; - vector_length = 0; + vector_length = 0U; dump = false; - dump_filename = "./dll_pll_dump.dat"; - pll_bw_hz = 40.0; + dump_mat = true; + dump_filename = std::string("./dll_pll_dump.dat"); + pll_pull_in_bw_hz = 50.0; + dll_pull_in_bw_hz = 3.0; + pll_bw_hz = 35.0; dll_bw_hz = 2.0; pll_bw_narrow_hz = 5.0; dll_bw_narrow_hz = 0.75; diff --git a/src/algorithms/tracking/libs/dll_pll_conf.h b/src/algorithms/tracking/libs/dll_pll_conf.h index 2cee8c405..0fbf07cc3 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.h +++ b/src/algorithms/tracking/libs/dll_pll_conf.h @@ -33,17 +33,20 @@ #ifndef GNSS_SDR_DLL_PLL_CONF_H_ #define GNSS_SDR_DLL_PLL_CONF_H_ +#include #include class Dll_Pll_Conf { -private: public: /* DLL/PLL tracking configuration */ double fs_in; - unsigned int vector_length; + uint32_t vector_length; bool dump; + bool dump_mat; std::string dump_filename; + float pll_pull_in_bw_hz; + float dll_pull_in_bw_hz; float pll_bw_hz; float dll_bw_hz; float pll_bw_narrow_hz; @@ -52,11 +55,13 @@ public: float very_early_late_space_chips; float early_late_space_narrow_chips; float very_early_late_space_narrow_chips; - int extend_correlation_symbols; - int cn0_samples; - int carrier_lock_det_mav_samples; - int cn0_min; - int max_lock_fail; + int32_t extend_correlation_symbols; + bool high_dyn; + int32_t cn0_samples; + int32_t carrier_lock_det_mav_samples; + int32_t cn0_min; + int32_t max_lock_fail; + uint32_t smoother_length; double carrier_lock_th; bool track_pilot; char system; diff --git a/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc new file mode 100644 index 000000000..87b66a911 --- /dev/null +++ b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc @@ -0,0 +1,68 @@ +/*! + * \file dll_pll_conf.cc + * \brief Class that contains all the configuration parameters for generic + * tracking block based on a DLL and a PLL. + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "dll_pll_conf_fpga.h" +#include + +Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga() +{ + /* DLL/PLL tracking configuration */ + fs_in = 0.0; + vector_length = 0U; + dump = false; + dump_mat = true; + dump_filename = std::string("./dll_pll_dump.dat"); + pll_bw_hz = 40.0; + dll_bw_hz = 2.0; + pll_bw_narrow_hz = 5.0; + dll_bw_narrow_hz = 0.75; + early_late_space_chips = 0.5; + very_early_late_space_chips = 0.5; + early_late_space_narrow_chips = 0.1; + very_early_late_space_narrow_chips = 0.1; + extend_correlation_symbols = 5; + cn0_samples = 20; + cn0_min = 25; + max_lock_fail = 50; + carrier_lock_th = 0.85; + track_pilot = false; + system = 'G'; + char sig_[3] = "1C"; + std::memcpy(signal, sig_, 3); + device_name = "/dev/uio"; + device_base = 1U; + multicorr_type = 0U; + code_length_chips = 0U; + code_samples_per_chip = 0U; + ca_codes = nullptr; + data_codes = nullptr; +} diff --git a/src/algorithms/tracking/libs/dll_pll_conf_fpga.h b/src/algorithms/tracking/libs/dll_pll_conf_fpga.h new file mode 100644 index 000000000..8fd81fb36 --- /dev/null +++ b/src/algorithms/tracking/libs/dll_pll_conf_fpga.h @@ -0,0 +1,75 @@ +/*! + * \file dll_pll_conf.h + * \brief Class that contains all the configuration parameters for generic tracking block based on a DLL and a PLL. + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * Class that contains all the configuration parameters for generic tracking block based on a DLL and a PLL. + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_DLL_PLL_CONF_FPGA_H_ +#define GNSS_SDR_DLL_PLL_CONF_FPGA_H_ + +#include +#include + +class Dll_Pll_Conf_Fpga +{ +public: + /* DLL/PLL tracking configuration */ + double fs_in; + uint32_t vector_length; + bool dump; + bool dump_mat; + std::string dump_filename; + float pll_bw_hz; + float dll_bw_hz; + float pll_bw_narrow_hz; + float dll_bw_narrow_hz; + float early_late_space_chips; + float very_early_late_space_chips; + float early_late_space_narrow_chips; + float very_early_late_space_narrow_chips; + int32_t extend_correlation_symbols; + int32_t cn0_samples; + int32_t cn0_min; + int32_t max_lock_fail; + double carrier_lock_th; + bool track_pilot; + char system; + char signal[3]; + std::string device_name; + uint32_t device_base; + uint32_t multicorr_type; + uint32_t code_length_chips; + uint32_t code_samples_per_chip; + int32_t* ca_codes; + int32_t* data_codes; + + Dll_Pll_Conf_Fpga(); +}; + +#endif diff --git a/src/algorithms/tracking/libs/fpga_multicorrelator.cc b/src/algorithms/tracking/libs/fpga_multicorrelator.cc index 9a546caca..80123157d 100644 --- a/src/algorithms/tracking/libs/fpga_multicorrelator.cc +++ b/src/algorithms/tracking/libs/fpga_multicorrelator.cc @@ -75,7 +75,7 @@ #define CODE_RESAMPLER_NUM_BITS_PRECISION 20 #define CODE_PHASE_STEP_CHIPS_NUM_NBITS CODE_RESAMPLER_NUM_BITS_PRECISION #define pwrtwo(x) (1 << (x)) -#define MAX_CODE_RESAMPLER_COUNTER pwrtwo(CODE_PHASE_STEP_CHIPS_NUM_NBITS) // 2^CODE_PHASE_STEP_CHIPS_NUM_NBITS +#define MAX_CODE_RESAMPLER_COUNTER pwrtwo(CODE_PHASE_STEP_CHIPS_NUM_NBITS) // 2^CODE_PHASE_STEP_CHIPS_NUM_NBITS #define PHASE_CARR_NBITS 32 #define PHASE_CARR_NBITS_INT 1 #define PHASE_CARR_NBITS_FRAC PHASE_CARR_NBITS - PHASE_CARR_NBITS_INT @@ -84,57 +84,69 @@ #define LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY 0x0C000000 #define TEST_REGISTER_TRACK_WRITEVAL 0x55AA -int fpga_multicorrelator_8sc::read_sample_counter() +uint64_t fpga_multicorrelator_8sc::read_sample_counter() { - return d_map_base[7]; + uint64_t sample_counter_tmp, sample_counter_msw_tmp; + sample_counter_tmp = d_map_base[d_SAMPLE_COUNTER_REG_ADDR_LSW]; + sample_counter_msw_tmp = d_map_base[d_SAMPLE_COUNTER_REG_ADDR_MSW]; + sample_counter_msw_tmp = sample_counter_msw_tmp << 32; + sample_counter_tmp = sample_counter_tmp + sample_counter_msw_tmp; // 2^32 + //return d_map_base[d_SAMPLE_COUNTER_REG_ADDR]; + return sample_counter_tmp; } -void fpga_multicorrelator_8sc::set_initial_sample(int samples_offset) +void fpga_multicorrelator_8sc::set_initial_sample(uint64_t samples_offset) { d_initial_sample_counter = samples_offset; - d_map_base[13] = d_initial_sample_counter; + //printf("www writing d map base %d = d_initial_sample_counter = %d\n", d_INITIAL_COUNTER_VALUE_REG_ADDR, d_initial_sample_counter); + d_map_base[d_INITIAL_COUNTER_VALUE_REG_ADDR_LSW] = (d_initial_sample_counter & 0xFFFFFFFF); + d_map_base[d_INITIAL_COUNTER_VALUE_REG_ADDR_MSW] = (d_initial_sample_counter >> 32) & 0xFFFFFFFF; } - -void fpga_multicorrelator_8sc::set_local_code_and_taps(int code_length_chips, - float *shifts_chips, int PRN) -{ +//void fpga_multicorrelator_8sc::set_local_code_and_taps(int32_t code_length_chips, +// float *shifts_chips, int32_t PRN) + +void fpga_multicorrelator_8sc::set_local_code_and_taps(float *shifts_chips, float *prompt_data_shift, int32_t PRN) +{ d_shifts_chips = shifts_chips; - d_code_length_chips = code_length_chips; + d_prompt_data_shift = prompt_data_shift; + //d_code_length_chips = code_length_chips; fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(PRN); } -void fpga_multicorrelator_8sc::set_output_vectors(gr_complex* corr_out) +void fpga_multicorrelator_8sc::set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data) { d_corr_out = corr_out; + d_Prompt_Data = Prompt_Data; } void fpga_multicorrelator_8sc::update_local_code(float rem_code_phase_chips) { d_rem_code_phase_chips = rem_code_phase_chips; + //printf("uuuuu d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips); fpga_multicorrelator_8sc::fpga_compute_code_shift_parameters(); fpga_multicorrelator_8sc::fpga_configure_code_parameters_in_fpga(); } void fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler( - float rem_carrier_phase_in_rad, float phase_step_rad, - float rem_code_phase_chips, float code_phase_step_chips, - int signal_length_samples) + float rem_carrier_phase_in_rad, float phase_step_rad, + float rem_code_phase_chips, float code_phase_step_chips, + int32_t signal_length_samples) { - - update_local_code(rem_code_phase_chips); d_rem_carrier_phase_in_rad = rem_carrier_phase_in_rad; d_code_phase_step_chips = code_phase_step_chips; d_phase_step_rad = phase_step_rad; d_correlator_length_samples = signal_length_samples; - fpga_multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(); - fpga_multicorrelator_8sc::fpga_configure_signal_parameters_in_fpga(); + fpga_multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(); + fpga_multicorrelator_8sc::fpga_configure_signal_parameters_in_fpga(); fpga_multicorrelator_8sc::fpga_launch_multicorrelator_fpga(); - int irq_count; + int32_t irq_count; ssize_t nb; + //printf("$$$$$ waiting for interrupt ... \n"); nb = read(d_device_descriptor, &irq_count, sizeof(irq_count)); + //printf("$$$$$ interrupt received ... \n"); if (nb != sizeof(irq_count)) { printf("Tracking_module Read failed to retrieve 4 bytes!\n"); @@ -143,23 +155,35 @@ void fpga_multicorrelator_8sc::Carrier_wipeoff_multicorrelator_resampler( fpga_multicorrelator_8sc::read_tracking_gps_results(); } -fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int n_correlators, - std::string device_name, unsigned int device_base, int *ca_codes, unsigned int code_length) +fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int32_t n_correlators, + std::string device_name, uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, + uint32_t multicorr_type, uint32_t code_samples_per_chip) { + //printf("tracking fpga class created\n"); d_n_correlators = n_correlators; d_device_name = device_name; d_device_base = device_base; + d_track_pilot = track_pilot; d_device_descriptor = 0; d_map_base = nullptr; // instantiate variable length vectors - d_initial_index = static_cast(volk_gnsssdr_malloc( - n_correlators * sizeof(unsigned), volk_gnsssdr_get_alignment())); - d_initial_interp_counter = static_cast(volk_gnsssdr_malloc( - n_correlators * sizeof(unsigned), volk_gnsssdr_get_alignment())); - - //d_local_code_in = nullptr; + if (d_track_pilot) + { + d_initial_index = static_cast(volk_gnsssdr_malloc( + (n_correlators + 1) * sizeof(uint32_t), volk_gnsssdr_get_alignment())); + d_initial_interp_counter = static_cast(volk_gnsssdr_malloc( + (n_correlators + 1) * sizeof(uint32_t), volk_gnsssdr_get_alignment())); + } + else + { + d_initial_index = static_cast(volk_gnsssdr_malloc( + n_correlators * sizeof(uint32_t), volk_gnsssdr_get_alignment())); + d_initial_interp_counter = static_cast(volk_gnsssdr_malloc( + n_correlators * sizeof(uint32_t), volk_gnsssdr_get_alignment())); + } d_shifts_chips = nullptr; + d_prompt_data_shift = nullptr; d_corr_out = nullptr; d_code_length_chips = 0; d_rem_code_phase_chips = 0; @@ -171,23 +195,103 @@ fpga_multicorrelator_8sc::fpga_multicorrelator_8sc(int n_correlators, d_initial_sample_counter = 0; d_channel = 0; d_correlator_length_samples = 0, - d_code_length = code_length; - - // pre-compute all the codes -// d_ca_codes = static_cast(volk_gnsssdr_malloc(static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS*NUM_PRNs) * sizeof(int), volk_gnsssdr_get_alignment())); -// for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) -// { -// gps_l1_ca_code_gen_int(&d_ca_codes[(int(GPS_L1_CA_CODE_LENGTH_CHIPS)) * (PRN - 1)], PRN, 0); -// } + //d_code_length = code_length; + d_code_length_chips = code_length_chips; d_ca_codes = ca_codes; + d_data_codes = data_codes; + d_multicorr_type = multicorr_type; + + d_code_samples_per_chip = code_samples_per_chip; + // set up register mapping + + // write-only registers + d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR = 0; + d_INITIAL_INDEX_REG_BASE_ADDR = 1; + // if (d_multicorr_type == 0) + // { + // // multicorrelator with 3 correlators (16 registers only) + // d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR = 4; + // d_NSAMPLES_MINUS_1_REG_ADDR = 7; + // d_CODE_LENGTH_MINUS_1_REG_ADDR = 8; + // d_REM_CARR_PHASE_RAD_REG_ADDR = 9; + // d_PHASE_STEP_RAD_REG_ADDR = 10; + // d_PROG_MEMS_ADDR = 11; + // d_DROP_SAMPLES_REG_ADDR = 12; + // d_INITIAL_COUNTER_VALUE_REG_ADDR = 13; + // d_START_FLAG_ADDR = 14; + // } + // else + // { + // other types of multicorrelators (32 registers) + d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR = 7; + d_NSAMPLES_MINUS_1_REG_ADDR = 13; + d_CODE_LENGTH_MINUS_1_REG_ADDR = 14; + d_REM_CARR_PHASE_RAD_REG_ADDR = 15; + d_PHASE_STEP_RAD_REG_ADDR = 16; + d_PROG_MEMS_ADDR = 17; + d_DROP_SAMPLES_REG_ADDR = 18; + d_INITIAL_COUNTER_VALUE_REG_ADDR_LSW = 19; + d_INITIAL_COUNTER_VALUE_REG_ADDR_MSW = 20; + d_START_FLAG_ADDR = 30; + // } + + //printf("d_n_correlators = %d\n", d_n_correlators); + //printf("d_multicorr_type = %d\n", d_multicorr_type); + // read-write registers + // if (d_multicorr_type == 0) + // { + // // multicorrelator with 3 correlators (16 registers only) + // d_TEST_REG_ADDR = 15; + // } + // else + // { + // other types of multicorrelators (32 registers) + d_TEST_REG_ADDR = 31; + // } + + // result 2's complement saturation value + // if (d_multicorr_type == 0) + // { + // // multicorrelator with 3 correlators (16 registers only) + // d_result_SAT_value = 1048576; // 21 bits 2's complement -> 2^20 + // } + // else + // { + // // other types of multicorrelators (32 registers) + // d_result_SAT_value = 4194304; // 23 bits 2's complement -> 2^22 + // } + + // read only registers + d_RESULT_REG_REAL_BASE_ADDR = 1; + // if (d_multicorr_type == 0) + // { + // // multicorrelator with 3 correlators (16 registers only) + // d_RESULT_REG_IMAG_BASE_ADDR = 4; + // d_RESULT_REG_DATA_REAL_BASE_ADDR = 0; // no pilot tracking + // d_RESULT_REG_DATA_IMAG_BASE_ADDR = 0; + // d_SAMPLE_COUNTER_REG_ADDR = 7; + // + // } + // else + // { + // other types of multicorrelators (32 registers) + d_RESULT_REG_IMAG_BASE_ADDR = 7; + d_RESULT_REG_DATA_REAL_BASE_ADDR = 6; // no pilot tracking + d_RESULT_REG_DATA_IMAG_BASE_ADDR = 12; + d_SAMPLE_COUNTER_REG_ADDR_LSW = 13; + d_SAMPLE_COUNTER_REG_ADDR_MSW = 14; + + // } + + //printf("d_SAMPLE_COUNTER_REG_ADDR = %d\n", d_SAMPLE_COUNTER_REG_ADDR); + //printf("mmmmmmmmmmmmm d_n_correlators = %d\n", d_n_correlators); DLOG(INFO) << "TRACKING FPGA CLASS CREATED"; - } fpga_multicorrelator_8sc::~fpga_multicorrelator_8sc() { - delete[] d_ca_codes; + //delete[] d_ca_codes; close_device(); } @@ -195,7 +299,7 @@ fpga_multicorrelator_8sc::~fpga_multicorrelator_8sc() bool fpga_multicorrelator_8sc::free() { // unlock the channel - fpga_multicorrelator_8sc::unlock_channel(); + fpga_multicorrelator_8sc::unlock_channel(); // free the FPGA dynamically created variables if (d_initial_index != nullptr) @@ -214,73 +318,140 @@ bool fpga_multicorrelator_8sc::free() } -void fpga_multicorrelator_8sc::set_channel(unsigned int channel) +void fpga_multicorrelator_8sc::set_channel(uint32_t channel) { - char device_io_name[MAX_LENGTH_DEVICEIO_NAME]; // driver io name + //printf("www trk set channel\n"); + char device_io_name[MAX_LENGTH_DEVICEIO_NAME]; // driver io name d_channel = channel; // open the device corresponding to the assigned channel std::string mergedname; std::stringstream devicebasetemp; - int numdevice = d_device_base + d_channel; + int32_t numdevice = d_device_base + d_channel; devicebasetemp << numdevice; mergedname = d_device_name + devicebasetemp.str(); strcpy(device_io_name, mergedname.c_str()); + + //printf("ppps opening device %s\n", device_io_name); + if ((d_device_descriptor = open(device_io_name, O_RDWR | O_SYNC)) == -1) { LOG(WARNING) << "Cannot open deviceio" << device_io_name; - } - d_map_base = reinterpret_cast(mmap(NULL, PAGE_SIZE, - PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0)); + std::cout << "Cannot open deviceio" << device_io_name << std::endl; - if (d_map_base == reinterpret_cast(-1)) + //printf("error opening device\n"); + } + // else + // { + // std::cout << "deviceio" << device_io_name << " opened successfully" << std::endl; + // + // } + d_map_base = reinterpret_cast(mmap(NULL, PAGE_SIZE, + PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0)); + + if (d_map_base == reinterpret_cast(-1)) { LOG(WARNING) << "Cannot map the FPGA tracking module " - << d_channel << "into user memory"; + << d_channel << "into user memory"; + std::cout << "Cannot map deviceio" << device_io_name << std::endl; + //printf("error mapping registers\n"); } + // else + // { + // std::cout << "deviceio" << device_io_name << "mapped successfully" << std::endl; + // } + // else + // { + // printf("trk mapping registers succes\n"); // this is for debug -- remove ! + // } // sanity check : check test register - unsigned writeval = TEST_REGISTER_TRACK_WRITEVAL; - unsigned readval; + uint32_t writeval = TEST_REGISTER_TRACK_WRITEVAL; + uint32_t readval; readval = fpga_multicorrelator_8sc::fpga_acquisition_test_register(writeval); if (writeval != readval) { LOG(WARNING) << "Test register sanity check failed"; + printf("tracking test register sanity check failed\n"); + + //printf("lslslls test sanity check reg failure\n"); } else { LOG(INFO) << "Test register sanity check success !"; + //printf("tracking test register sanity check success\n"); + //printf("lslslls test sanity check reg success\n"); } } -unsigned fpga_multicorrelator_8sc::fpga_acquisition_test_register( - unsigned writeval) +uint32_t fpga_multicorrelator_8sc::fpga_acquisition_test_register( + uint32_t writeval) { - unsigned readval; + //printf("d_TEST_REG_ADDR = %d\n", d_TEST_REG_ADDR); + + uint32_t readval = 0; // write value to test register - d_map_base[15] = writeval; + d_map_base[d_TEST_REG_ADDR] = writeval; // read value from test register - readval = d_map_base[15]; + readval = d_map_base[d_TEST_REG_ADDR]; // return read value return readval; } -void fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int PRN) +void fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int32_t PRN) { - int k, s; - unsigned code_chip; - unsigned select_fpga_correlator; - select_fpga_correlator = 0; + uint32_t k; + uint32_t code_chip; + uint32_t select_pilot_corelator = LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT; + // select_fpga_correlator = 0; - for (s = 0; s < d_n_correlators; s++) + //printf("kkk d_n_correlators = %x\n", d_n_correlators); + //printf("kkk d_code_length_chips = %d\n", d_code_length_chips); + //printf("programming mems d map base %d\n", d_PROG_MEMS_ADDR); + + //FILE *fp; + //char str[80]; + //sprintf(str, "generated_code_PRN%d", PRN); + //fp = fopen(str,"w"); + // for (s = 0; s < d_n_correlators; s++) + // { + + //printf("kkk select_fpga_correlator = %x\n", select_fpga_correlator); + + d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER; + for (k = 0; k < d_code_length_chips * d_code_samples_per_chip; k++) { - d_map_base[11] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER; - for (k = 0; k < d_code_length_chips; k++) + //if (d_local_code_in[k] == 1) + //printf("kkk d_ca_codes %d = %d\n", k, d_ca_codes[((int(d_code_length)) * (PRN - 1)) + k]); + //fprintf(fp, "%d\n", d_ca_codes[((int(d_code_length_chips)) * d_code_samples_per_chip * (PRN - 1)) + k]); + if (d_ca_codes[((int(d_code_length_chips)) * d_code_samples_per_chip * (PRN - 1)) + k] == 1) + { + code_chip = 1; + } + else + { + code_chip = 0; + } + + // copy the local code to the FPGA memory one by one + d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY | code_chip; // | select_fpga_correlator; + } + // select_fpga_correlator = select_fpga_correlator + // + LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT; + // } + //fclose(fp); + //printf("kkk d_track_pilot = %d\n", d_track_pilot); + if (d_track_pilot) + { + //printf("kkk select_fpga_correlator = %x\n", select_fpga_correlator); + + d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_CLEAR_ADDRESS_COUNTER; + for (k = 0; k < d_code_length_chips * d_code_samples_per_chip; k++) { //if (d_local_code_in[k] == 1) - if (d_ca_codes[((int(d_code_length)) * (PRN - 1)) + k] == 1) + if (d_data_codes[((int(d_code_length_chips)) * d_code_samples_per_chip * (PRN - 1)) + k] == 1) { code_chip = 1; } @@ -288,51 +459,95 @@ void fpga_multicorrelator_8sc::fpga_configure_tracking_gps_local_code(int PRN) { code_chip = 0; } + //printf("%d %d | ", d_data_codes, code_chip); // copy the local code to the FPGA memory one by one - d_map_base[11] = LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY - | code_chip | select_fpga_correlator; + d_map_base[d_PROG_MEMS_ADDR] = LOCAL_CODE_FPGA_ENABLE_WRITE_MEMORY | code_chip | select_pilot_corelator; } - select_fpga_correlator = select_fpga_correlator - + LOCAL_CODE_FPGA_CORRELATOR_SELECT_COUNT; } + //printf("\n"); } void fpga_multicorrelator_8sc::fpga_compute_code_shift_parameters(void) { float temp_calculation; - int i; + int32_t i; + //printf("ppp d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips); for (i = 0; i < d_n_correlators; i++) { + //printf("ppp d_shifts_chips %d = %f\n", i, d_shifts_chips[i]); + //printf("ppp d_code_samples_per_chip = %d\n", d_code_samples_per_chip); temp_calculation = floor( - d_shifts_chips[i] - d_rem_code_phase_chips); - + d_shifts_chips[i] - d_rem_code_phase_chips); + + //printf("ppp d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips); + //printf("ppp temp calculation %d = %f ================================ \n", i, temp_calculation); if (temp_calculation < 0) { - temp_calculation = temp_calculation + d_code_length_chips; // % operator does not work as in Matlab with negative numbers + temp_calculation = temp_calculation + (d_code_length_chips * d_code_samples_per_chip); // % operator does not work as in Matlab with negative numbers } - d_initial_index[i] = static_cast( (static_cast(temp_calculation)) % d_code_length_chips); + //printf("ppp d_rem_code_phase_chips = %f\n", d_rem_code_phase_chips); + //printf("ppp temp calculation %d = %f ================================ \n", i, temp_calculation); + d_initial_index[i] = static_cast((static_cast(temp_calculation)) % (d_code_length_chips * d_code_samples_per_chip)); + //printf("ppp d_initial_index %d = %d\n", i, d_initial_index[i]); temp_calculation = fmod(d_shifts_chips[i] - d_rem_code_phase_chips, - 1.0); + 1.0); + //printf("ppp fmod %d = fmod(%f, 1) = %f\n", i, d_shifts_chips[i] - d_rem_code_phase_chips, temp_calculation); if (temp_calculation < 0) { - temp_calculation = temp_calculation + 1.0; // fmod operator does not work as in Matlab with negative numbers + temp_calculation = temp_calculation + 1.0; // fmod operator does not work as in Matlab with negative numbers } - d_initial_interp_counter[i] = static_cast( floor( MAX_CODE_RESAMPLER_COUNTER * temp_calculation)); + + d_initial_interp_counter[i] = static_cast(floor(MAX_CODE_RESAMPLER_COUNTER * temp_calculation)); + //printf("ppp d_initial_interp_counter %d = %d\n", i, d_initial_interp_counter[i]); + //printf("MAX_CODE_RESAMPLER_COUNTER = %d\n", MAX_CODE_RESAMPLER_COUNTER); } + if (d_track_pilot) + { + //printf("tracking pilot !!!!!!!!!!!!!!!!\n"); + temp_calculation = floor( + d_prompt_data_shift[0] - d_rem_code_phase_chips); + + if (temp_calculation < 0) + { + temp_calculation = temp_calculation + (d_code_length_chips * d_code_samples_per_chip); // % operator does not work as in Matlab with negative numbers + } + d_initial_index[d_n_correlators] = static_cast((static_cast(temp_calculation)) % (d_code_length_chips * d_code_samples_per_chip)); + temp_calculation = fmod(d_prompt_data_shift[0] - d_rem_code_phase_chips, + 1.0); + if (temp_calculation < 0) + { + temp_calculation = temp_calculation + 1.0; // fmod operator does not work as in Matlab with negative numbers + } + d_initial_interp_counter[d_n_correlators] = static_cast(floor(MAX_CODE_RESAMPLER_COUNTER * temp_calculation)); + } + //while(1); } void fpga_multicorrelator_8sc::fpga_configure_code_parameters_in_fpga(void) { - int i; + int32_t i; for (i = 0; i < d_n_correlators; i++) { - d_map_base[1 + i] = d_initial_index[i]; - d_map_base[1 + d_n_correlators + i] = d_initial_interp_counter[i]; + //printf("www writing d map base %d = d_initial_index %d = %d\n", d_INITIAL_INDEX_REG_BASE_ADDR + i, i, d_initial_index[i]); + d_map_base[d_INITIAL_INDEX_REG_BASE_ADDR + i] = d_initial_index[i]; + //d_map_base[1 + d_n_correlators + i] = d_initial_interp_counter[i]; + //printf("www writing d map base %d = d_initial_interp_counter %d = %d\n", d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + i, i, d_initial_interp_counter[i]); + d_map_base[d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + i] = d_initial_interp_counter[i]; } - d_map_base[8] = d_code_length_chips - 1; // number of samples - 1 + if (d_track_pilot) + { + //printf("www writing d map base %d = d_initial_index %d = %d\n", d_INITIAL_INDEX_REG_BASE_ADDR + d_n_correlators, d_n_correlators, d_initial_index[d_n_correlators]); + d_map_base[d_INITIAL_INDEX_REG_BASE_ADDR + d_n_correlators] = d_initial_index[d_n_correlators]; + //d_map_base[1 + d_n_correlators + i] = d_initial_interp_counter[i]; + //printf("www writing d map base %d = d_initial_interp_counter %d = %d\n", d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + d_n_correlators, d_n_correlators, d_initial_interp_counter[d_n_correlators]); + d_map_base[d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR + d_n_correlators] = d_initial_interp_counter[d_n_correlators]; + } + + //printf("www writing d map base %d = d_code_length_chips*d_code_samples_per_chip - 1 = %d\n", d_CODE_LENGTH_MINUS_1_REG_ADDR, (d_code_length_chips*d_code_samples_per_chip) - 1); + d_map_base[d_CODE_LENGTH_MINUS_1_REG_ADDR] = (d_code_length_chips * d_code_samples_per_chip) - 1; // number of samples - 1 } @@ -340,78 +555,148 @@ void fpga_multicorrelator_8sc::fpga_compute_signal_parameters_in_fpga(void) { float d_rem_carrier_phase_in_rad_temp; - d_code_phase_step_chips_num = static_cast( roundf(MAX_CODE_RESAMPLER_COUNTER * d_code_phase_step_chips)); + d_code_phase_step_chips_num = static_cast(roundf(MAX_CODE_RESAMPLER_COUNTER * d_code_phase_step_chips)); + if (d_code_phase_step_chips > 1.0) + { + printf("Warning : d_code_phase_step_chips = %f cannot be bigger than one\n", d_code_phase_step_chips); + } + + //printf("d_rem_carrier_phase_in_rad = %f\n", d_rem_carrier_phase_in_rad); + if (d_rem_carrier_phase_in_rad > M_PI) { - d_rem_carrier_phase_in_rad_temp = -2 * M_PI - + d_rem_carrier_phase_in_rad; + d_rem_carrier_phase_in_rad_temp = -2 * M_PI + d_rem_carrier_phase_in_rad; } else if (d_rem_carrier_phase_in_rad < -M_PI) { - d_rem_carrier_phase_in_rad_temp = 2 * M_PI - + d_rem_carrier_phase_in_rad; + d_rem_carrier_phase_in_rad_temp = 2 * M_PI + d_rem_carrier_phase_in_rad; } else { d_rem_carrier_phase_in_rad_temp = d_rem_carrier_phase_in_rad; } - d_rem_carr_phase_rad_int = static_cast( roundf( - (fabs(d_rem_carrier_phase_in_rad_temp) / M_PI) - * pow(2, PHASE_CARR_NBITS_FRAC))); + d_rem_carr_phase_rad_int = static_cast(roundf( + (fabs(d_rem_carrier_phase_in_rad_temp) / M_PI) * pow(2, PHASE_CARR_NBITS_FRAC))); if (d_rem_carrier_phase_in_rad_temp < 0) { d_rem_carr_phase_rad_int = -d_rem_carr_phase_rad_int; } - d_phase_step_rad_int = static_cast( roundf( - (fabs(d_phase_step_rad) / M_PI) * pow(2, PHASE_CARR_NBITS_FRAC))); // the FPGA accepts a range for the phase step between -pi and +pi + d_phase_step_rad_int = static_cast(roundf( + (fabs(d_phase_step_rad) / M_PI) * pow(2, PHASE_CARR_NBITS_FRAC))); // the FPGA accepts a range for the phase step between -pi and +pi + //printf("d_phase_step_rad_int = %d\n", d_phase_step_rad_int); if (d_phase_step_rad < 0) { d_phase_step_rad_int = -d_phase_step_rad_int; } + + //printf("d_phase_step_rad_int = %d\n", d_phase_step_rad_int); } void fpga_multicorrelator_8sc::fpga_configure_signal_parameters_in_fpga(void) { - d_map_base[0] = d_code_phase_step_chips_num; - d_map_base[7] = d_correlator_length_samples - 1; - d_map_base[9] = d_rem_carr_phase_rad_int; - d_map_base[10] = d_phase_step_rad_int; + //printf("www d map base %d = d_code_phase_step_chips_num = %d\n", d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR, d_code_phase_step_chips_num); + d_map_base[d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR] = d_code_phase_step_chips_num; + + //printf("www d map base %d = d_correlator_length_samples - 1 = %d\n", d_NSAMPLES_MINUS_1_REG_ADDR, d_correlator_length_samples - 1); + d_map_base[d_NSAMPLES_MINUS_1_REG_ADDR] = d_correlator_length_samples - 1; + + //printf("www d map base %d = d_rem_carr_phase_rad_int = %d\n", d_REM_CARR_PHASE_RAD_REG_ADDR, d_rem_carr_phase_rad_int); + d_map_base[d_REM_CARR_PHASE_RAD_REG_ADDR] = d_rem_carr_phase_rad_int; + + //printf("www d map base %d = d_phase_step_rad_int = %d\n", d_PHASE_STEP_RAD_REG_ADDR, d_phase_step_rad_int); + d_map_base[d_PHASE_STEP_RAD_REG_ADDR] = d_phase_step_rad_int; } void fpga_multicorrelator_8sc::fpga_launch_multicorrelator_fpga(void) { // enable interrupts - int reenable = 1; - write(d_device_descriptor, reinterpret_cast(&reenable), sizeof(int)); + int32_t reenable = 1; + write(d_device_descriptor, reinterpret_cast(&reenable), sizeof(int32_t)); - // writing 1 to reg 14 launches the tracking - d_map_base[14] = 1; + // writing 1 to reg 14 launches the tracking + //printf("www writing 1 to d map base %d = start flag\n", d_START_FLAG_ADDR); + d_map_base[d_START_FLAG_ADDR] = 1; + //while(1); } void fpga_multicorrelator_8sc::read_tracking_gps_results(void) { - int readval_real; - int readval_imag; - int k; + int32_t readval_real; + int32_t readval_imag; + int32_t k; + //printf("www reading trk results\n"); for (k = 0; k < d_n_correlators; k++) { - readval_real = d_map_base[1 + k]; - if (readval_real >= 1048576) // 0x100000 (21 bits two's complement) - { - readval_real = -2097152 + readval_real; - } + readval_real = d_map_base[d_RESULT_REG_REAL_BASE_ADDR + k]; + //printf("read real before checking d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_real); + //// if (readval_real > debug_max_readval_real[k]) + //// { + //// debug_max_readval_real[k] = readval_real; + //// } + // if (readval_real >= d_result_SAT_value) // 0x100000 (21 bits two's complement) + // { + // readval_real = -2*d_result_SAT_value + readval_real; + // } + //// if (readval_real > debug_max_readval_real_after_check[k]) + //// { + //// debug_max_readval_real_after_check[k] = readval_real; + //// } + //printf("read real d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_real); + readval_imag = d_map_base[d_RESULT_REG_IMAG_BASE_ADDR + k]; + //printf("read imag before checking d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_imag); + //// if (readval_imag > debug_max_readval_imag[k]) + //// { + //// debug_max_readval_imag[k] = readval_imag; + //// } + // + // if (readval_imag >= d_result_SAT_value) // 0x100000 (21 bits two's complement) + // { + // readval_imag = -2*d_result_SAT_value + readval_imag; + // } + //// if (readval_imag > debug_max_readval_imag_after_check[k]) + //// { + //// debug_max_readval_imag_after_check[k] = readval_real; + //// } + //printf("read imag d map base %d = %d\n", d_RESULT_REG_BASE_ADDR + k, readval_imag); + d_corr_out[k] = gr_complex(readval_real, readval_imag); - readval_imag = d_map_base[1 + d_n_correlators + k]; - if (readval_imag >= 1048576) // 0x100000 (21 bits two's complement) - { - readval_imag = -2097152 + readval_imag; - } - d_corr_out[k] = gr_complex(readval_real,readval_imag); + // if (printcounter > 100) + // { + // printcounter = 0; + // for (int32_t ll=0;ll= d_result_SAT_value) // 0x100000 (21 bits two's complement) + // { + // readval_real = -2*d_result_SAT_value + readval_real; + // } + + readval_imag = d_map_base[d_RESULT_REG_DATA_IMAG_BASE_ADDR]; + // if (readval_imag >= d_result_SAT_value) // 0x100000 (21 bits two's complement) + // { + // readval_imag = -2*d_result_SAT_value + readval_imag; + // } + d_Prompt_Data[0] = gr_complex(readval_real, readval_imag); } } @@ -419,40 +704,38 @@ void fpga_multicorrelator_8sc::read_tracking_gps_results(void) void fpga_multicorrelator_8sc::unlock_channel(void) { // unlock the channel to let the next samples go through - d_map_base[12] = 1; // unlock the channel + //printf("www writing 1 to d map base %d = drop samples\n", d_DROP_SAMPLES_REG_ADDR); + d_map_base[d_DROP_SAMPLES_REG_ADDR] = 1; // unlock the channel } void fpga_multicorrelator_8sc::close_device() { - unsigned * aux = const_cast(d_map_base); - if (munmap(static_cast(aux), PAGE_SIZE) == -1) + uint32_t *aux = const_cast(d_map_base); + if (munmap(static_cast(aux), PAGE_SIZE) == -1) { printf("Failed to unmap memory uio\n"); } -/* else - { - printf("memory uio unmapped\n"); - } */ close(d_device_descriptor); } - + void fpga_multicorrelator_8sc::lock_channel(void) { // lock the channel for processing - d_map_base[12] = 0; // lock the channel + //printf("www writing 0 to d map base %d = drop samples\n", d_DROP_SAMPLES_REG_ADDR); + d_map_base[d_DROP_SAMPLES_REG_ADDR] = 0; // lock the channel } -void fpga_multicorrelator_8sc::read_sample_counters(int *sample_counter, int *secondary_sample_counter, int *counter_corr_0_in, int *counter_corr_0_out) -{ - *sample_counter = d_map_base[11]; - *secondary_sample_counter = d_map_base[8]; - *counter_corr_0_in = d_map_base[10]; - *counter_corr_0_out = d_map_base[9]; - -} +//void fpga_multicorrelator_8sc::read_sample_counters(int32_t *sample_counter, int32_t *secondary_sample_counter, int32_t *counter_corr_0_in, int32_t *counter_corr_0_out) +//{ +// *sample_counter = d_map_base[11]; +// *secondary_sample_counter = d_map_base[8]; +// *counter_corr_0_in = d_map_base[10]; +// *counter_corr_0_out = d_map_base[9]; +// +//} -void fpga_multicorrelator_8sc::reset_multicorrelator(void) -{ - d_map_base[14] = 2; // writing a 2 to d_map_base[14] resets the multicorrelator -} +//void fpga_multicorrelator_8sc::reset_multicorrelator(void) +//{ +// d_map_base[14] = 2; // writing a 2 to d_map_base[14] resets the multicorrelator +//} diff --git a/src/algorithms/tracking/libs/fpga_multicorrelator.h b/src/algorithms/tracking/libs/fpga_multicorrelator.h index 3a56acfde..f7fffe1aa 100644 --- a/src/algorithms/tracking/libs/fpga_multicorrelator.h +++ b/src/algorithms/tracking/libs/fpga_multicorrelator.h @@ -1,6 +1,6 @@ /*! * \file fpga_multicorrelator_8sc.h - * \brief High optimized FPGA vector correlator class for lv_16sc_t (short int complex) + * \brief High optimized FPGA vector correlator class for lv_16sc_t (short int32_t complex) * \authors
            *
          • Marc Majoral, 2017. mmajoral(at)cttc.cat *
          • Javier Arribas, 2016. jarribas(at)cttc.es @@ -11,7 +11,7 @@ * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -29,7 +29,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ @@ -39,6 +39,7 @@ #include #include +#include #define MAX_LENGTH_DEVICEIO_NAME 50 @@ -48,84 +49,121 @@ class fpga_multicorrelator_8sc { public: - fpga_multicorrelator_8sc(int n_correlators, std::string device_name, - unsigned int device_base, int *ca_codes, unsigned int code_length); + fpga_multicorrelator_8sc(int32_t n_correlators, std::string device_name, + uint32_t device_base, int32_t *ca_codes, int32_t *data_codes, uint32_t code_length_chips, bool track_pilot, uint32_t multicorr_type, uint32_t code_samples_per_chip); ~fpga_multicorrelator_8sc(); //bool set_output_vectors(gr_complex* corr_out); - void set_output_vectors(gr_complex *corr_out); + void set_output_vectors(gr_complex *corr_out, gr_complex *Prompt_Data); // bool set_local_code_and_taps( - // int code_length_chips, const int* local_code_in, - // float *shifts_chips, int PRN); + // int32_t code_length_chips, const int* local_code_in, + // float *shifts_chips, int32_t PRN); //bool set_local_code_and_taps( void set_local_code_and_taps( - int code_length_chips, - float *shifts_chips, int PRN); + // int32_t code_length_chips, + float *shifts_chips, float *prompt_data_shift, int32_t PRN); //bool set_output_vectors(lv_16sc_t* corr_out); void update_local_code(float rem_code_phase_chips); //bool Carrier_wipeoff_multicorrelator_resampler( void Carrier_wipeoff_multicorrelator_resampler( float rem_carrier_phase_in_rad, float phase_step_rad, float rem_code_phase_chips, float code_phase_step_chips, - int signal_length_samples); + int32_t signal_length_samples); bool free(); - void set_channel(unsigned int channel); - void set_initial_sample(int samples_offset); - int read_sample_counter(); + void set_channel(uint32_t channel); + void set_initial_sample(uint64_t samples_offset); + uint64_t read_sample_counter(); void lock_channel(void); void unlock_channel(void); - void read_sample_counters(int *sample_counter, int *secondary_sample_counter, int *counter_corr_0_in, int *counter_corr_0_out); // debug - + //void read_sample_counters(int32_t *sample_counter, int32_t *secondary_sample_counter, int32_t *counter_corr_0_in, int32_t *counter_corr_0_out); // debug private: - //const int *d_local_code_in; + //const int32_t *d_local_code_in; gr_complex *d_corr_out; + gr_complex *d_Prompt_Data; float *d_shifts_chips; - int d_code_length_chips; - int d_n_correlators; + float *d_prompt_data_shift; + int32_t d_code_length_chips; + int32_t d_n_correlators; // data related to the hardware module and the driver - int d_device_descriptor; // driver descriptor - volatile unsigned *d_map_base; // driver memory map + int32_t d_device_descriptor; // driver descriptor + volatile uint32_t *d_map_base; // driver memory map // configuration data received from the interface - unsigned int d_channel; // channel number - unsigned d_correlator_length_samples; + uint32_t d_channel; // channel number + uint32_t d_ncorrelators; // number of correlators + uint32_t d_correlator_length_samples; float d_rem_code_phase_chips; float d_code_phase_step_chips; float d_rem_carrier_phase_in_rad; float d_phase_step_rad; // configuration data computed in the format that the FPGA expects - unsigned *d_initial_index; - unsigned *d_initial_interp_counter; - unsigned d_code_phase_step_chips_num; - int d_rem_carr_phase_rad_int; - int d_phase_step_rad_int; - unsigned d_initial_sample_counter; + uint32_t *d_initial_index; + uint32_t *d_initial_interp_counter; + uint32_t d_code_phase_step_chips_num; + int32_t d_rem_carr_phase_rad_int; + int32_t d_phase_step_rad_int; + uint64_t d_initial_sample_counter; // driver std::string d_device_name; - unsigned int d_device_base; + uint32_t d_device_base; + int32_t *d_ca_codes; + int32_t *d_data_codes; - int *d_ca_codes; + //uint32_t d_code_length; // nominal number of chips - unsigned int d_code_length; // nominal number of chips + uint32_t d_code_samples_per_chip; + bool d_track_pilot; + + uint32_t d_multicorr_type; + + // register addresses + // write-only regs + uint32_t d_CODE_PHASE_STEP_CHIPS_NUM_REG_ADDR; + uint32_t d_INITIAL_INDEX_REG_BASE_ADDR; + uint32_t d_INITIAL_INTERP_COUNTER_REG_BASE_ADDR; + uint32_t d_NSAMPLES_MINUS_1_REG_ADDR; + uint32_t d_CODE_LENGTH_MINUS_1_REG_ADDR; + uint32_t d_REM_CARR_PHASE_RAD_REG_ADDR; + uint32_t d_PHASE_STEP_RAD_REG_ADDR; + uint32_t d_PROG_MEMS_ADDR; + uint32_t d_DROP_SAMPLES_REG_ADDR; + uint32_t d_INITIAL_COUNTER_VALUE_REG_ADDR_LSW; + uint32_t d_INITIAL_COUNTER_VALUE_REG_ADDR_MSW; + uint32_t d_START_FLAG_ADDR; + // read-write regs + uint32_t d_TEST_REG_ADDR; + // read-only regs + uint32_t d_RESULT_REG_REAL_BASE_ADDR; + uint32_t d_RESULT_REG_IMAG_BASE_ADDR; + uint32_t d_RESULT_REG_DATA_REAL_BASE_ADDR; + uint32_t d_RESULT_REG_DATA_IMAG_BASE_ADDR; + uint32_t d_SAMPLE_COUNTER_REG_ADDR_LSW; + uint32_t d_SAMPLE_COUNTER_REG_ADDR_MSW; // private functions - unsigned fpga_acquisition_test_register(unsigned writeval); - void fpga_configure_tracking_gps_local_code(int PRN); + uint32_t fpga_acquisition_test_register(uint32_t writeval); + void fpga_configure_tracking_gps_local_code(int32_t PRN); void fpga_compute_code_shift_parameters(void); void fpga_configure_code_parameters_in_fpga(void); void fpga_compute_signal_parameters_in_fpga(void); void fpga_configure_signal_parameters_in_fpga(void); void fpga_launch_multicorrelator_fpga(void); void read_tracking_gps_results(void); - void reset_multicorrelator(void); + //void reset_multicorrelator(void); void close_device(void); - // debug - //unsigned int first_time = 1; + uint32_t d_result_SAT_value; + + int32_t debug_max_readval_real[5] = {0, 0, 0, 0, 0}; + int32_t debug_max_readval_imag[5] = {0, 0, 0, 0, 0}; + + int32_t debug_max_readval_real_after_check[5] = {0, 0, 0, 0, 0}; + int32_t debug_max_readval_imag_after_check[5] = {0, 0, 0, 0, 0}; + int32_t printcounter = 0; }; #endif /* GNSS_SDR_FPGA_MULTICORRELATOR_H_ */ diff --git a/src/core/interfaces/acquisition_interface.h b/src/core/interfaces/acquisition_interface.h index dcf140a5f..d76e79bfc 100644 --- a/src/core/interfaces/acquisition_interface.h +++ b/src/core/interfaces/acquisition_interface.h @@ -64,6 +64,7 @@ public: virtual void set_state(int state) = 0; virtual signed int mag() = 0; virtual void reset() = 0; + virtual void stop_acquisition() = 0; }; #endif /* GNSS_SDR_ACQUISITION_INTERFACE */ diff --git a/src/core/interfaces/channel_interface.h b/src/core/interfaces/channel_interface.h index 48232c674..db449941c 100644 --- a/src/core/interfaces/channel_interface.h +++ b/src/core/interfaces/channel_interface.h @@ -53,6 +53,7 @@ class ChannelInterface : public GNSSBlockInterface public: virtual Gnss_Signal get_signal() const = 0; virtual void start_acquisition() = 0; + virtual void stop_channel() = 0; virtual void set_signal(const Gnss_Signal&) = 0; }; diff --git a/src/core/interfaces/pvt_interface.h b/src/core/interfaces/pvt_interface.h index 69b23f541..afabfa590 100644 --- a/src/core/interfaces/pvt_interface.h +++ b/src/core/interfaces/pvt_interface.h @@ -38,6 +38,10 @@ #define GNSS_SDR_PVT_INTERFACE_H_ #include "gnss_block_interface.h" +#include "gps_ephemeris.h" +#include "galileo_ephemeris.h" +#include "gps_almanac.h" +#include "galileo_almanac.h" /*! * \brief This class represents an interface to a PVT block. @@ -52,6 +56,18 @@ class PvtInterface : public GNSSBlockInterface { public: virtual void reset() = 0; + virtual void clear_ephemeris() = 0; + virtual std::map get_gps_ephemeris() const = 0; + virtual std::map get_galileo_ephemeris() const = 0; + virtual std::map get_gps_almanac() const = 0; + virtual std::map get_galileo_almanac() const = 0; + + virtual bool get_latest_PVT(double* longitude_deg, + double* latitude_deg, + double* height_m, + double* ground_speed_kmh, + double* course_over_ground_deg, + time_t* UTC_time) = 0; }; #endif /* GNSS_SDR_PVT_INTERFACE_H_ */ diff --git a/src/core/interfaces/tracking_interface.h b/src/core/interfaces/tracking_interface.h index 010036d72..da2b3c41b 100644 --- a/src/core/interfaces/tracking_interface.h +++ b/src/core/interfaces/tracking_interface.h @@ -56,6 +56,7 @@ class TrackingInterface : public GNSSBlockInterface { public: virtual void start_tracking() = 0; + virtual void stop_tracking() = 0; virtual void set_gnss_synchro(Gnss_Synchro* gnss_synchro) = 0; virtual void set_channel(unsigned int channel) = 0; }; diff --git a/src/core/libs/CMakeLists.txt b/src/core/libs/CMakeLists.txt index c68d6d1d0..9557199c4 100644 --- a/src/core/libs/CMakeLists.txt +++ b/src/core/libs/CMakeLists.txt @@ -19,16 +19,23 @@ add_subdirectory(supl) if(OPENSSL_FOUND) - add_definitions( -DUSE_OPENSSL_FALLBACK=1 ) -endif(OPENSSL_FOUND) + add_definitions(-DUSE_OPENSSL_FALLBACK=1) +endif() -set(CORE_LIBS_SOURCES - ini.cc - INIReader.cc +set(CORE_LIBS_SOURCES + ini.cc + INIReader.cc string_converter.cc gnss_sdr_supl_client.cc ) - + +set(CORE_LIBS_HEADERS + ini.h + INIReader.h + string_converter.h + gnss_sdr_supl_client.h +) + include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src/core/system_parameters @@ -38,10 +45,16 @@ include_directories( ${GLOG_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} + ${PUGIXML_INCLUDE_DIR} ) -file(GLOB CORE_LIBS_HEADERS "*.h") list(SORT CORE_LIBS_HEADERS) +list(SORT CORE_LIBS_SOURCES) + add_library(rx_core_lib ${CORE_LIBS_SOURCES} ${CORE_LIBS_HEADERS}) source_group(Headers FILES ${CORE_LIBS_HEADERS}) -target_link_libraries(rx_core_lib supl_library) +target_link_libraries(rx_core_lib supl_library ${PUGIXML_LIBRARY}) + +if(PUGIXML_LOCAL) + add_dependencies(rx_core_lib pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION}) +endif() diff --git a/src/core/libs/gnss_sdr_supl_client.cc b/src/core/libs/gnss_sdr_supl_client.cc index 70517e7f2..f3774379d 100644 --- a/src/core/libs/gnss_sdr_supl_client.cc +++ b/src/core/libs/gnss_sdr_supl_client.cc @@ -32,6 +32,7 @@ */ #include "gnss_sdr_supl_client.h" +#include #include #include @@ -47,8 +48,10 @@ gnss_sdr_supl_client::gnss_sdr_supl_client() request = 0; } + gnss_sdr_supl_client::~gnss_sdr_supl_client() {} + void gnss_sdr_supl_client::print_assistance() { if (assist.set & SUPL_RRLP_ASSIST_REFTIME) @@ -189,6 +192,7 @@ int gnss_sdr_supl_client::get_assistance(int i_mcc, int i_mns, int i_lac, int i_ return err; } + void gnss_sdr_supl_client::read_supl_data() { // READ REFERENCE LOCATION @@ -264,13 +268,12 @@ void gnss_sdr_supl_client::read_supl_data() gps_almanac_iterator->second.d_OMEGA0 = static_cast(a->OMEGA_0) * pow(2.0, -23); gps_almanac_iterator->second.d_sqrt_A = static_cast(a->A_sqrt) * pow(2.0, -11); gps_almanac_iterator->second.d_OMEGA_DOT = static_cast(a->OMEGA_dot) * pow(2.0, -38); - gps_almanac_iterator->second.d_Toa = static_cast(a->toa) * pow(2.0, 12); - gps_almanac_iterator->second.d_e_eccentricity = static_cast(a->toa) * pow(2.0, -21); + gps_almanac_iterator->second.i_Toa = static_cast(a->toa) * pow(2.0, 12); + gps_almanac_iterator->second.d_e_eccentricity = static_cast(a->e) * pow(2.0, -21); gps_almanac_iterator->second.d_M_0 = static_cast(a->M0) * pow(2.0, -23); } } - // READ SV EPHEMERIS if (assist.cnt_eph) { @@ -368,13 +371,13 @@ void gnss_sdr_supl_client::read_supl_data() bool gnss_sdr_supl_client::load_ephemeris_xml(const std::string file_name) { + std::ifstream ifs; try { - std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); boost::archive::xml_iarchive xml(ifs); gps_ephemeris_map.clear(); xml >> boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", this->gps_ephemeris_map); - ifs.close(); LOG(INFO) << "Loaded Ephemeris map data with " << this->gps_ephemeris_map.size() << " satellites"; } catch (std::exception& e) @@ -385,16 +388,17 @@ bool gnss_sdr_supl_client::load_ephemeris_xml(const std::string file_name) return true; } + bool gnss_sdr_supl_client::save_ephemeris_map_xml(const std::string file_name, std::map eph_map) { - if (eph_map.size() > 0) + if (eph_map.empty() == false) { + std::ofstream ofs; try { - std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); boost::archive::xml_oarchive xml(ofs); xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", eph_map); - ofs.close(); LOG(INFO) << "Saved Ephemeris map data"; } catch (std::exception& e) @@ -402,23 +406,165 @@ bool gnss_sdr_supl_client::save_ephemeris_map_xml(const std::string file_name, s LOG(WARNING) << e.what(); return false; } - return true; } else { LOG(WARNING) << "Failed to save Ephemeris, map is empty"; return false; } + return true; } + +bool gnss_sdr_supl_client::load_gal_ephemeris_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gal_ephemeris_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", this->gal_ephemeris_map); + LOG(INFO) << "Loaded Ephemeris map data with " << this->gal_ephemeris_map.size() << " satellites"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool save_gal_ephemeris_map_xml(const std::string file_name, std::map eph_map) +{ + if (eph_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", eph_map); + LOG(INFO) << "Saved Galileo ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save Galileo ephemeris, map is empty"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_cnav_ephemeris_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gps_cnav_ephemeris_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_cnav_ephemeris_map", this->gps_cnav_ephemeris_map); + LOG(INFO) << "Loaded Ephemeris map data with " << this->gps_cnav_ephemeris_map.size() << " satellites"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool save_cnav_ephemeris_map_xml(const std::string file_name, std::map eph_map) +{ + if (eph_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_cnav_ephemeris_map", eph_map); + LOG(INFO) << "Saved GPS CNAV ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save GPS CNAV ephemeris, map is empty"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_gnav_ephemeris_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gps_cnav_ephemeris_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_gnav_ephemeris_map", this->glonass_gnav_ephemeris_map); + LOG(INFO) << "Loaded GLONASS ephemeris map data with " << this->gps_cnav_ephemeris_map.size() << " satellites"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool save_gnav_ephemeris_map_xml(const std::string file_name, std::map eph_map) +{ + if (eph_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gnav_ephemeris_map", eph_map); + LOG(INFO) << "Saved GLONASS GNAV ephemeris map data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save GLONASS GNAV ephemeris, map is empty"; + return false; + } + return true; +} + + bool gnss_sdr_supl_client::load_utc_xml(const std::string file_name) { + std::ifstream ifs; try { - std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); boost::archive::xml_iarchive xml(ifs); - xml >> boost::serialization::make_nvp("GNSS-SDR_utc_map", this->gps_utc); - ifs.close(); + xml >> boost::serialization::make_nvp("GNSS-SDR_utc_model", this->gps_utc); LOG(INFO) << "Loaded UTC model data"; } catch (std::exception& e) @@ -429,40 +575,134 @@ bool gnss_sdr_supl_client::load_utc_xml(const std::string file_name) return true; } -bool gnss_sdr_supl_client::save_utc_map_xml(const std::string file_name, std::map utc_map) + +bool gnss_sdr_supl_client::save_utc_xml(const std::string file_name, Gps_Utc_Model& utc) { - if (utc_map.size() > 0) + if (utc.valid) { + std::ofstream ofs; try { - std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_utc_map", utc_map); - ofs.close(); - LOG(INFO) << "Saved UTC Model data"; + xml << boost::serialization::make_nvp("GNSS-SDR_utc_model", utc); + LOG(INFO) << "Saved GPS UTC Model data"; } catch (std::exception& e) { LOG(WARNING) << e.what(); return false; } - return true; } else { - LOG(WARNING) << "Failed to save UTC model, map is empty"; + LOG(WARNING) << "Failed to save GPS UTC model, no valid data"; return false; } + return true; } + +bool gnss_sdr_supl_client::load_cnav_utc_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + xml >> boost::serialization::make_nvp("GNSS-SDR_cnav_utc_model", this->gps_cnav_utc); + LOG(INFO) << "Loaded CNAV UTC model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_cnav_utc_xml(const std::string file_name, Gps_CNAV_Utc_Model& utc) +{ + if (utc.valid) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_cnav_utc_model", utc); + LOG(INFO) << "Saved GPS CNAV UTC model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save GPS CNAV UTC model, no valid data"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_gal_utc_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + xml >> boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", this->gal_utc); + LOG(INFO) << "Loaded Galileo UTC model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_gal_utc_xml(const std::string file_name, Galileo_Utc_Model& utc) +{ + if (utc.flag_utc_model) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", utc); + LOG(INFO) << "Saved Galileo UTC Model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save Galileo UTC model, no valid data"; + return false; + } + return true; +} + + bool gnss_sdr_supl_client::load_iono_xml(const std::string file_name) { + std::ifstream ifs; try { - std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); boost::archive::xml_iarchive xml(ifs); - xml >> boost::serialization::make_nvp("GNSS-SDR_iono_map", this->gps_iono); - ifs.close(); + xml >> boost::serialization::make_nvp("GNSS-SDR_iono_model", this->gps_iono); LOG(INFO) << "Loaded IONO model data"; } catch (std::exception& e) @@ -473,16 +713,17 @@ bool gnss_sdr_supl_client::load_iono_xml(const std::string file_name) return true; } -bool gnss_sdr_supl_client::save_iono_map_xml(const std::string file_name, std::map iono_map) + +bool gnss_sdr_supl_client::save_iono_xml(const std::string file_name, Gps_Iono& iono) { - if (iono_map.size() > 0) + if (iono.valid) { + std::ofstream ofs; try { - std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_iono_map", iono_map); - ofs.close(); + xml << boost::serialization::make_nvp("GNSS-SDR_iono_model", iono); LOG(INFO) << "Saved IONO Model data"; } catch (std::exception& e) @@ -490,23 +731,260 @@ bool gnss_sdr_supl_client::save_iono_map_xml(const std::string file_name, std::m LOG(WARNING) << e.what(); return false; } - return true; } else { LOG(WARNING) << "Failed to save IONO model, map is empty"; return false; } + return true; } + +bool gnss_sdr_supl_client::load_gal_iono_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + xml >> boost::serialization::make_nvp("GNSS-SDR_gal_iono_model", this->gal_iono); + LOG(INFO) << "Loaded Galileo IONO model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_gal_iono_xml(const std::string file_name, Galileo_Iono& iono) +{ + if (iono.ai0_5 != 0.0) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_iono_model", iono); + LOG(INFO) << "Saved Galileo IONO Model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save Galileo IONO model, map is empty"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_gps_almanac_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gps_almanac_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_gps_almanac_map", this->gps_almanac_map); + LOG(INFO) << "Loaded GPS almanac map data with " << this->gps_almanac_map.size() << " satellites"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_gps_almanac_xml(const std::string file_name, std::map gps_almanac_map) +{ + if (gps_almanac_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gps_almanac_map", gps_almanac_map); + LOG(INFO) << "Saved GPS almanac data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save GPS almanac, map is empty"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_gal_almanac_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gal_almanac_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_gal_almanac_map", this->gal_almanac_map); + } + catch (std::exception& e) + { + // Maybe the file is from https://www.gsc-europa.eu/system-status/almanac-data ? + return this->read_gal_almanac_from_gsa(file_name); + } + LOG(INFO) << "Loaded Galileo almanac map data with " << this->gal_almanac_map.size() << " satellites"; + return true; +} + + +bool gnss_sdr_supl_client::read_gal_almanac_from_gsa(const std::string file_name) +{ + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(file_name.c_str()); + if (!result) + { + LOG(WARNING) << "Error loading file " << file_name << ":" << result.description(); + return false; + } + for (pugi::xml_node almanac : doc.child("signalData") + .child("body") + .child("Almanacs") + .children("svAlmanac")) + { + Galileo_Almanac gal_alm; + try + { + uint32_t prn = static_cast(std::stoi(almanac.child_value("SVID"))); + gal_alm.i_satellite_PRN = prn; + gal_alm.i_Toa = std::stoi(almanac.child("almanac").child_value("t0a")); + gal_alm.i_WNa = std::stoi(almanac.child("almanac").child_value("wna")); + gal_alm.i_IODa = std::stoi(almanac.child("almanac").child_value("iod")); + gal_alm.d_Delta_i = std::stod(almanac.child("almanac").child_value("deltai")); + gal_alm.d_M_0 = std::stod(almanac.child("almanac").child_value("m0")); + gal_alm.d_e_eccentricity = std::stod(almanac.child("almanac").child_value("ecc")); + gal_alm.d_Delta_sqrt_A = std::stod(almanac.child("almanac").child_value("aSqRoot")); + gal_alm.d_OMEGA0 = std::stod(almanac.child("almanac").child_value("omega0")); + gal_alm.d_OMEGA = std::stod(almanac.child("almanac").child_value("w")); + gal_alm.d_OMEGA_DOT = std::stod(almanac.child("almanac").child_value("omegaDot")); + gal_alm.d_A_f0 = std::stod(almanac.child("almanac").child_value("af0")); + gal_alm.d_A_f1 = std::stod(almanac.child("almanac").child_value("af1")); + gal_alm.E5b_HS = std::stoi(almanac.child("svINavSignalStatus").child_value("statusE5b")); + gal_alm.E1B_HS = std::stoi(almanac.child("svINavSignalStatus").child_value("statusE1B")); + gal_alm.E5a_HS = std::stoi(almanac.child("svFNavSignalStatus").child_value("statusE5a")); + + this->gal_almanac_map[static_cast(prn)] = gal_alm; + } + catch (const std::exception& e) + { + std::cerr << e.what() << std::endl; + } + } + if (this->gal_almanac_map.empty()) + { + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_gal_almanac_xml(const std::string file_name, std::map gal_almanac_map) +{ + if (gal_almanac_map.empty() == false) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_almanac_map", gal_almanac_map); + LOG(INFO) << "Saved Galileo almanac data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save Galileo almanac, map is empty"; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::load_glo_utc_xml(const std::string file_name) +{ + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + xml >> boost::serialization::make_nvp("GNSS-SDR_glo_utc_model", this->glo_gnav_utc); + LOG(INFO) << "Loaded UTC model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what() << "File: " << file_name; + return false; + } + return true; +} + + +bool gnss_sdr_supl_client::save_glo_utc_xml(const std::string file_name, Glonass_Gnav_Utc_Model& utc) +{ + if (utc.valid) + { + std::ofstream ofs; + try + { + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_glo_utc_model", utc); + LOG(INFO) << "Saved Glonass UTC Model data"; + } + catch (std::exception& e) + { + LOG(WARNING) << e.what(); + return false; + } + } + else + { + LOG(WARNING) << "Failed to save Glonass UTC model, no valid data"; + return false; + } + return true; +} + + bool gnss_sdr_supl_client::load_ref_time_xml(const std::string file_name) { + std::ifstream ifs; try { - std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); boost::archive::xml_iarchive xml(ifs); - xml >> boost::serialization::make_nvp("GNSS-SDR_ref_time_map", this->gps_time); - ifs.close(); + xml >> boost::serialization::make_nvp("GNSS-SDR_ref_time", this->gps_time); LOG(INFO) << "Loaded Ref Time data"; } catch (std::exception& e) @@ -517,16 +995,17 @@ bool gnss_sdr_supl_client::load_ref_time_xml(const std::string file_name) return true; } -bool gnss_sdr_supl_client::save_ref_time_map_xml(const std::string file_name, std::map ref_time_map) + +bool gnss_sdr_supl_client::save_ref_time_xml(const std::string file_name, Agnss_Ref_Time& ref_time) { - if (ref_time_map.size() > 0) + if (ref_time.valid == true) { + std::ofstream ofs; try { - std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ref_time_map", ref_time_map); - ofs.close(); + xml << boost::serialization::make_nvp("GNSS-SDR_ref_time", ref_time); LOG(INFO) << "Saved Ref Time data"; } catch (std::exception& e) @@ -534,23 +1013,24 @@ bool gnss_sdr_supl_client::save_ref_time_map_xml(const std::string file_name, st LOG(WARNING) << e.what(); return false; } - return true; } else { - LOG(WARNING) << "Failed to save Ref Time, map is empty"; + LOG(WARNING) << "Failed to save Ref Time"; return false; } + return true; } + bool gnss_sdr_supl_client::load_ref_location_xml(const std::string file_name) { + std::ifstream ifs; try { - std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); boost::archive::xml_iarchive xml(ifs); - xml >> boost::serialization::make_nvp("GNSS-SDR_ref_location_map", this->gps_ref_loc); - ifs.close(); + xml >> boost::serialization::make_nvp("GNSS-SDR_ref_location", this->gps_ref_loc); LOG(INFO) << "Loaded Ref Location data"; } catch (std::exception& e) @@ -561,16 +1041,17 @@ bool gnss_sdr_supl_client::load_ref_location_xml(const std::string file_name) return true; } -bool gnss_sdr_supl_client::save_ref_location_map_xml(const std::string file_name, std::map ref_location_map) + +bool gnss_sdr_supl_client::save_ref_location_xml(const std::string file_name, Agnss_Ref_Location& ref_location) { - if (ref_location_map.size() > 0) + if (ref_location.valid == true) { + std::ofstream ofs; try { - std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); + ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); boost::archive::xml_oarchive xml(ofs); - xml << boost::serialization::make_nvp("GNSS-SDR_ref_location_map", ref_location_map); - ofs.close(); + xml << boost::serialization::make_nvp("GNSS-SDR_ref_location", ref_location); LOG(INFO) << "Saved Ref Location data"; } catch (std::exception& e) @@ -578,11 +1059,11 @@ bool gnss_sdr_supl_client::save_ref_location_map_xml(const std::string file_name LOG(WARNING) << e.what(); return false; } - return true; } else { - LOG(WARNING) << "Failed to save Ref Location, map is empty"; + LOG(WARNING) << "Failed to save Ref Location"; return false; } + return true; } diff --git a/src/core/libs/gnss_sdr_supl_client.h b/src/core/libs/gnss_sdr_supl_client.h index 381045edb..2fd599bdf 100644 --- a/src/core/libs/gnss_sdr_supl_client.h +++ b/src/core/libs/gnss_sdr_supl_client.h @@ -38,14 +38,22 @@ extern "C" { #include "supl.h" } +#include "agnss_ref_location.h" +#include "agnss_ref_time.h" #include "GPS_L1_CA.h" #include "gps_ephemeris.h" #include "gps_iono.h" #include "gps_almanac.h" #include "gps_utc_model.h" +#include "gps_cnav_utc_model.h" #include "gps_acq_assist.h" -#include "gps_ref_time.h" -#include "gps_ref_location.h" +#include "gps_cnav_ephemeris.h" +#include "galileo_ephemeris.h" +#include "galileo_utc_model.h" +#include "galileo_iono.h" +#include "galileo_almanac.h" +#include "glonass_gnav_ephemeris.h" +#include "glonass_gnav_utc_model.h" #include #include #include @@ -69,6 +77,7 @@ private: supl_ctx_t ctx; // assistance data supl_assist_t assist; + bool read_gal_almanac_from_gsa(const std::string file_name); public: // SUPL SERVER INFO @@ -77,17 +86,26 @@ public: int request; // ephemeris map std::map gps_ephemeris_map; + std::map gal_ephemeris_map; + std::map gps_cnav_ephemeris_map; + std::map glonass_gnav_ephemeris_map; + // almanac map std::map gps_almanac_map; + std::map gal_almanac_map; // ionospheric model Gps_Iono gps_iono; + Galileo_Iono gal_iono; // reference time - Gps_Ref_Time gps_time; + Agnss_Ref_Time gps_time; // UTC model Gps_Utc_Model gps_utc; + Galileo_Utc_Model gal_utc; + Gps_CNAV_Utc_Model gps_cnav_utc; + Glonass_Gnav_Utc_Model glo_gnav_utc; // reference location - Gps_Ref_Location gps_ref_loc; + Agnss_Ref_Location gps_ref_loc; // Acquisition Assistance map std::map gps_acq_map; @@ -107,7 +125,7 @@ public: void read_supl_data(); /*! - * \brief Read ephemeris map from XML file + * \brief Read GPS NAV ephemeris map from XML file */ bool load_ephemeris_xml(const std::string file_name); @@ -118,16 +136,87 @@ public: std::map eph_map); /*! - * \brief Read utc model from XML file + * \brief Read GPS CNAV ephemeris map from XML file + */ + bool load_cnav_ephemeris_xml(const std::string file_name); + + /*! + * \brief Save GPS CNAV ephemeris map to XML file. + */ + bool save_cnav_ephemeris_map_xml(const std::string file_name, + std::map eph_map); + + /*! + * \brief Read Galileo ephemeris map from XML file + */ + bool load_gal_ephemeris_xml(const std::string file_name); + + /*! + * \brief Save Galileo ephemeris map to XML file. + */ + bool save_gal_ephemeris_map_xml(const std::string file_name, + std::map eph_map); + + /*! + * \brief Read GLONASS GNAV ephemeris map from XML file + */ + bool load_gnav_ephemeris_xml(const std::string file_name); + + /*! + * \brief Save GLONASS GNAV ephemeris map to XML file. + */ + bool save_gnav_ephemeris_map_xml(const std::string file_name, + std::map eph_map); + + /*! + * \brief Read GPS utc model from XML file */ bool load_utc_xml(const std::string file_name); /*! - * \brief Save utc model map to XML file - * To be called by ControlThread::gps_utc_model_data_write_to_XML() + * \brief Save UTC model map to XML file */ - bool save_utc_map_xml(const std::string file_name, - std::map utc_map); + bool save_utc_xml(const std::string file_name, Gps_Utc_Model& utc); + + /*! + * \brief Read CNAV GPS utc model from XML file + */ + bool load_cnav_utc_xml(const std::string file_name); + + /*! + * \brief Save CNAV UTC model map to XML file + */ + bool save_cnav_utc_xml(const std::string file_name, Gps_CNAV_Utc_Model& utc); + + /*! + * \brief Read Galileo utc model from XML file + */ + bool load_gal_utc_xml(const std::string file_name); + + /*! + * \brief Save Galileo UTC model map to XML file + */ + bool save_gal_utc_xml(const std::string file_name, Galileo_Utc_Model& utc); + + /*! + * \brief Read Galileo almanac map from XML file + */ + bool load_gal_almanac_xml(const std::string file_name); + + /*! + * \brief Save Galileo almanac map to XML file + */ + bool save_gal_almanac_xml(const std::string file_name, std::map gal_almanac); + + /*! + * \brief Read GPS almanac map from XML file + */ + bool load_gps_almanac_xml(const std::string file_name); + + /*! + * \brief Save GPS almanac map to XML file + */ + bool save_gps_almanac_xml(const std::string file_name, std::map gps_almanac_map); /*! * \brief Read iono from XML file @@ -137,8 +226,27 @@ public: /*! * \brief Save iono map to XML file */ - bool save_iono_map_xml(const std::string file_name, - std::map iono_map); + bool save_iono_xml(const std::string file_name, Gps_Iono& iono); + + /*! + * \brief Read Galileo iono from XML file + */ + bool load_gal_iono_xml(const std::string file_name); + + /*! + * \brief Save Galileo iono map to XML file + */ + bool save_gal_iono_xml(const std::string file_name, Galileo_Iono& iono); + + /*! + * \brief Read Glonass utc model from XML file + */ + bool load_glo_utc_xml(const std::string file_name); + + /*! + * \brief Save Glonass UTC model map to XML file + */ + bool save_glo_utc_xml(const std::string file_name, Glonass_Gnav_Utc_Model& utc); /*! * \brief Read ref time from XML file @@ -148,8 +256,8 @@ public: /*! * \brief Save ref time map to XML file */ - bool save_ref_time_map_xml(const std::string file_name, - std::map ref_time_map); + bool save_ref_time_xml(const std::string file_name, + Agnss_Ref_Time& ref_time_map); /*! * \brief Read ref location from XML file @@ -159,13 +267,14 @@ public: /*! * \brief Save ref location map to XML file */ - bool save_ref_location_map_xml(std::string file_name, - std::map ref_location_map); + bool save_ref_location_xml(std::string file_name, + Agnss_Ref_Location& ref_location); /* * Prints SUPL data to std::cout. Use it for debug purposes only. */ void print_assistance(); + gnss_sdr_supl_client(); ~gnss_sdr_supl_client(); }; diff --git a/src/core/libs/supl/CMakeLists.txt b/src/core/libs/supl/CMakeLists.txt index 6d0edd576..e8e1e69a6 100644 --- a/src/core/libs/supl/CMakeLists.txt +++ b/src/core/libs/supl/CMakeLists.txt @@ -21,13 +21,13 @@ list(SORT ASN_RRLP_SOURCES) file(GLOB ASN_SUPL_SOURCES "${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl/*.c") list(SORT ASN_SUPL_SOURCES) -set (SUPL_SOURCES - supl.c - ) +set(SUPL_SOURCES + supl.c +) if(OPENSSL_FOUND) - add_definitions( -DUSE_OPENSSL_FALLBACK=1 ) -endif(OPENSSL_FOUND) + add_definitions(-DUSE_OPENSSL_FALLBACK=1) +endif() include_directories( ${CMAKE_CURRENT_SOURCE_DIR} @@ -35,17 +35,15 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl ${GNUTLS_INCLUDE_DIR} - ) +) if(CMAKE_C_COMPILER_ID MATCHES "Clang") if(CMAKE_BUILD_TYPE MATCHES "Release") - set(MY_C_FLAGS "${MY_C_FLAGS} -Wno-parentheses-equality") - endif(CMAKE_BUILD_TYPE MATCHES "Release") -endif(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(MY_C_FLAGS "${MY_C_FLAGS} -Wno-parentheses-equality") + endif() +endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_C_FLAGS}") -add_library (supl_library STATIC ${ASN_RRLP_SOURCES} ${ASN_SUPL_SOURCES} ${SUPL_SOURCES}) -target_link_libraries (supl_library ${GNUTLS_LIBRARIES} ${GNUTLS_OPENSSL_LIBRARY} gnss_system_parameters) +add_library(supl_library STATIC ${ASN_RRLP_SOURCES} ${ASN_SUPL_SOURCES} ${SUPL_SOURCES}) +target_link_libraries(supl_library ${GNUTLS_LIBRARIES} ${GNUTLS_OPENSSL_LIBRARY} gnss_system_parameters) set_target_properties(supl_library PROPERTIES LINKER_LANGUAGE C) - - diff --git a/src/core/libs/supl/asn-rrlp/per_opentype.c b/src/core/libs/supl/asn-rrlp/per_opentype.c index c749c8c6c..c81caed44 100644 --- a/src/core/libs/supl/asn-rrlp/per_opentype.c +++ b/src/core/libs/supl/asn-rrlp/per_opentype.c @@ -7,11 +7,12 @@ #include #include -typedef struct uper_ugot_key { - asn_per_data_t oldpd; /* Old per data source */ - size_t unclaimed; - size_t ot_moved; /* Number of bits moved by OT processing */ - int repeat; +typedef struct uper_ugot_key +{ + asn_per_data_t oldpd; /* Old per data source */ + size_t unclaimed; + size_t ot_moved; /* Number of bits moved by OT processing */ + int repeat; } uper_ugot_key; static int uper_ugot_refill(asn_per_data_t *pd); @@ -24,243 +25,272 @@ int asn_debug_indent; * Encode an "open type field". * #10.1, #10.2 */ -int -uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - void *buf; - void *bptr; - ssize_t size; - size_t toGo; +int uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) +{ + void *buf; + void *bptr; + ssize_t size; + size_t toGo; - ASN_DEBUG("Open type put %s ...", td->name); + ASN_DEBUG("Open type put %s ...", td->name); - size = uper_encode_to_new_buffer(td, constraints, sptr, &buf); - if(size <= 0) return -1; + size = uper_encode_to_new_buffer(td, constraints, sptr, &buf); + if (size <= 0) return -1; - for(bptr = buf, toGo = size; toGo;) { - ssize_t maySave = uper_put_length(po, toGo); - if(maySave < 0) break; - if(per_put_many_bits(po, bptr, maySave * 8)) break; - bptr = (char *)bptr + maySave; - toGo -= maySave; - } + for (bptr = buf, toGo = size; toGo;) + { + ssize_t maySave = uper_put_length(po, toGo); + if (maySave < 0) break; + if (per_put_many_bits(po, bptr, maySave * 8)) break; + bptr = (char *)bptr + maySave; + toGo -= maySave; + } - FREEMEM(buf); - if(toGo) return -1; + FREEMEM(buf); + if (toGo) return -1; - ASN_DEBUG("Open type put %s of length %d + overhead (1byte?)", - td->name, size); + ASN_DEBUG("Open type put %s of length %d + overhead (1byte?)", + td->name, size); - return 0; + return 0; } static asn_dec_rval_t uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_dec_rval_t rv; - ssize_t chunk_bytes; - int repeat; - uint8_t *buf = 0; - size_t bufLen = 0; - size_t bufSize = 0; - asn_per_data_t spd; - size_t padding; + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) +{ + asn_dec_rval_t rv; + ssize_t chunk_bytes; + int repeat; + uint8_t *buf = 0; + size_t bufLen = 0; + size_t bufSize = 0; + asn_per_data_t spd; + size_t padding; - _ASN_STACK_OVERFLOW_CHECK(ctx); + _ASN_STACK_OVERFLOW_CHECK(ctx); - ASN_DEBUG("Getting open type %s...", td->name); + ASN_DEBUG("Getting open type %s...", td->name); - do { - chunk_bytes = uper_get_length(pd, -1, &repeat); - if(chunk_bytes < 0) { - FREEMEM(buf); - _ASN_DECODE_STARVED; - } - if(bufLen + chunk_bytes > bufSize) { - void *ptr; - bufSize = chunk_bytes + (bufSize << 2); - ptr = REALLOC(buf, bufSize); - if(!ptr) { - FREEMEM(buf); - _ASN_DECODE_FAILED; - } - buf = ptr; - } - if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) { - FREEMEM(buf); - _ASN_DECODE_STARVED; - } - bufLen += chunk_bytes; - } while(repeat); + do + { + chunk_bytes = uper_get_length(pd, -1, &repeat); + if (chunk_bytes < 0) + { + FREEMEM(buf); + _ASN_DECODE_STARVED; + } + if (bufLen + chunk_bytes > bufSize) + { + void *ptr; + bufSize = chunk_bytes + (bufSize << 2); + ptr = REALLOC(buf, bufSize); + if (!ptr) + { + FREEMEM(buf); + _ASN_DECODE_FAILED; + } + buf = ptr; + } + if (per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) + { + FREEMEM(buf); + _ASN_DECODE_STARVED; + } + bufLen += chunk_bytes; + } + while (repeat); - ASN_DEBUG("Getting open type %s encoded in %d bytes", td->name, - bufLen); + ASN_DEBUG("Getting open type %s encoded in %d bytes", td->name, + bufLen); - memset(&spd, 0, sizeof(spd)); - spd.buffer = buf; - spd.nbits = bufLen << 3; + memset(&spd, 0, sizeof(spd)); + spd.buffer = buf; + spd.nbits = bufLen << 3; - asn_debug_indent += 4; - rv = td->uper_decoder(ctx, td, constraints, sptr, &spd); - asn_debug_indent -= 4; + asn_debug_indent += 4; + rv = td->uper_decoder(ctx, td, constraints, sptr, &spd); + asn_debug_indent -= 4; - if(rv.code == RC_OK) { - /* Check padding validity */ - padding = spd.nbits - spd.nboff; - if(padding < 8 && per_get_few_bits(&spd, padding) == 0) { - /* Everything is cool */ - FREEMEM(buf); - return rv; - } - FREEMEM(buf); - if(padding >= 8) { - ASN_DEBUG("Too large padding %d in open type", padding); - _ASN_DECODE_FAILED; - } else { - ASN_DEBUG("Non-zero padding"); - _ASN_DECODE_FAILED; - } - } else { - FREEMEM(buf); - /* rv.code could be RC_WMORE, nonsense in this context */ - rv.code = RC_FAIL; /* Noone would give us more */ - } + if (rv.code == RC_OK) + { + /* Check padding validity */ + padding = spd.nbits - spd.nboff; + if (padding < 8 && per_get_few_bits(&spd, padding) == 0) + { + /* Everything is cool */ + FREEMEM(buf); + return rv; + } + FREEMEM(buf); + if (padding >= 8) + { + ASN_DEBUG("Too large padding %d in open type", padding); + _ASN_DECODE_FAILED; + } + else + { + ASN_DEBUG("Non-zero padding"); + _ASN_DECODE_FAILED; + } + } + else + { + FREEMEM(buf); + /* rv.code could be RC_WMORE, nonsense in this context */ + rv.code = RC_FAIL; /* Noone would give us more */ + } - return rv; + return rv; } static asn_dec_rval_t GCC_NOTUSED uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - uper_ugot_key arg; - asn_dec_rval_t rv; - ssize_t padding; + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) +{ + uper_ugot_key arg; + asn_dec_rval_t rv; + ssize_t padding; - _ASN_STACK_OVERFLOW_CHECK(ctx); + _ASN_STACK_OVERFLOW_CHECK(ctx); - ASN_DEBUG("Getting open type %s from %s", td->name, - per_data_string(pd)); - arg.oldpd = *pd; - arg.unclaimed = 0; - arg.ot_moved = 0; - arg.repeat = 1; - pd->refill = uper_ugot_refill; - pd->refill_key = &arg; - pd->nbits = pd->nboff; /* 0 good bits at this point, will refill */ - pd->moved = 0; /* This now counts the open type size in bits */ + ASN_DEBUG("Getting open type %s from %s", td->name, + per_data_string(pd)); + arg.oldpd = *pd; + arg.unclaimed = 0; + arg.ot_moved = 0; + arg.repeat = 1; + pd->refill = uper_ugot_refill; + pd->refill_key = &arg; + pd->nbits = pd->nboff; /* 0 good bits at this point, will refill */ + pd->moved = 0; /* This now counts the open type size in bits */ - asn_debug_indent += 4; - rv = td->uper_decoder(ctx, td, constraints, sptr, pd); - asn_debug_indent -= 4; + asn_debug_indent += 4; + rv = td->uper_decoder(ctx, td, constraints, sptr, pd); + asn_debug_indent -= 4; -#define UPDRESTOREPD do { \ - /* buffer and nboff are valid, preserve them. */ \ - pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved); \ - pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved); \ - pd->refill = arg.oldpd.refill; \ - pd->refill_key = arg.oldpd.refill_key; \ - } while(0) +#define UPDRESTOREPD \ + do \ + { \ + /* buffer and nboff are valid, preserve them. */ \ + pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved); \ + pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved); \ + pd->refill = arg.oldpd.refill; \ + pd->refill_key = arg.oldpd.refill_key; \ + } \ + while (0) - if(rv.code != RC_OK) { - UPDRESTOREPD; - return rv; - } + if (rv.code != RC_OK) + { + UPDRESTOREPD; + return rv; + } - ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d" - , td->name, - per_data_string(pd), - per_data_string(&arg.oldpd), - arg.unclaimed, arg.repeat); + ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d", td->name, + per_data_string(pd), + per_data_string(&arg.oldpd), + arg.unclaimed, arg.repeat); - padding = pd->moved % 8; - if(padding) { - int32_t pvalue; - if(padding > 7) { - ASN_DEBUG("Too large padding %d in open type", - padding); - rv.code = RC_FAIL; - UPDRESTOREPD; - return rv; - } - padding = 8 - padding; - ASN_DEBUG("Getting padding of %d bits", padding); - pvalue = per_get_few_bits(pd, padding); - switch(pvalue) { - case -1: - ASN_DEBUG("Padding skip failed"); - UPDRESTOREPD; - _ASN_DECODE_STARVED; - case 0: break; - default: - ASN_DEBUG("Non-blank padding (%d bits 0x%02x)", - padding, (int)pvalue); - UPDRESTOREPD; - _ASN_DECODE_FAILED; - } - } - if(pd->nboff != pd->nbits) { - ASN_DEBUG("Open type %s overhead pd%s old%s", td->name, - per_data_string(pd), per_data_string(&arg.oldpd)); - if(1) { - UPDRESTOREPD; - _ASN_DECODE_FAILED; - } else { - arg.unclaimed += pd->nbits - pd->nboff; - } - } + padding = pd->moved % 8; + if (padding) + { + int32_t pvalue; + if (padding > 7) + { + ASN_DEBUG("Too large padding %d in open type", + padding); + rv.code = RC_FAIL; + UPDRESTOREPD; + return rv; + } + padding = 8 - padding; + ASN_DEBUG("Getting padding of %d bits", padding); + pvalue = per_get_few_bits(pd, padding); + switch (pvalue) + { + case -1: + ASN_DEBUG("Padding skip failed"); + UPDRESTOREPD; + _ASN_DECODE_STARVED; + case 0: + break; + default: + ASN_DEBUG("Non-blank padding (%d bits 0x%02x)", + padding, (int)pvalue); + UPDRESTOREPD; + _ASN_DECODE_FAILED; + } + } + if (pd->nboff != pd->nbits) + { + ASN_DEBUG("Open type %s overhead pd%s old%s", td->name, + per_data_string(pd), per_data_string(&arg.oldpd)); + if (1) + { + UPDRESTOREPD; + _ASN_DECODE_FAILED; + } + else + { + arg.unclaimed += pd->nbits - pd->nboff; + } + } - /* Adjust pd back so it points to original data */ - UPDRESTOREPD; + /* Adjust pd back so it points to original data */ + UPDRESTOREPD; - /* Skip data not consumed by the decoder */ - if(arg.unclaimed) ASN_DEBUG("Getting unclaimed %d", arg.unclaimed); - if(arg.unclaimed) { - switch(per_skip_bits(pd, arg.unclaimed)) { - case -1: - ASN_DEBUG("Claim of %d failed", arg.unclaimed); - _ASN_DECODE_STARVED; - case 0: - ASN_DEBUG("Got claim of %d", arg.unclaimed); - break; - default: - /* Padding must be blank */ - ASN_DEBUG("Non-blank unconsumed padding"); - _ASN_DECODE_FAILED; - } - arg.unclaimed = 0; - } + /* Skip data not consumed by the decoder */ + if (arg.unclaimed) ASN_DEBUG("Getting unclaimed %d", arg.unclaimed); + if (arg.unclaimed) + { + switch (per_skip_bits(pd, arg.unclaimed)) + { + case -1: + ASN_DEBUG("Claim of %d failed", arg.unclaimed); + _ASN_DECODE_STARVED; + case 0: + ASN_DEBUG("Got claim of %d", arg.unclaimed); + break; + default: + /* Padding must be blank */ + ASN_DEBUG("Non-blank unconsumed padding"); + _ASN_DECODE_FAILED; + } + arg.unclaimed = 0; + } - if(arg.repeat) { - ASN_DEBUG("Not consumed the whole thing"); - rv.code = RC_FAIL; - return rv; - } + if (arg.repeat) + { + ASN_DEBUG("Not consumed the whole thing"); + rv.code = RC_FAIL; + return rv; + } - return rv; + return rv; } asn_dec_rval_t uper_open_type_get(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - - return uper_open_type_get_simple(ctx, td, constraints, - sptr, pd); - + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) +{ + return uper_open_type_get_simple(ctx, td, constraints, + sptr, pd); } -int -uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) { - asn_TYPE_descriptor_t s_td; - asn_dec_rval_t rv; +int uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) +{ + asn_TYPE_descriptor_t s_td; + asn_dec_rval_t rv; - s_td.name = ""; - s_td.uper_decoder = uper_sot_suck; + s_td.name = ""; + s_td.uper_decoder = uper_sot_suck; - rv = uper_open_type_get(ctx, &s_td, 0, 0, pd); - if(rv.code != RC_OK) - return -1; - else - return 0; + rv = uper_open_type_get(ctx, &s_td, 0, 0, pd); + if (rv.code != RC_OK) + return -1; + else + return 0; } /* @@ -269,105 +299,122 @@ uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) { static asn_dec_rval_t uper_sot_suck(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_dec_rval_t rv; + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) +{ + asn_dec_rval_t rv; - (void)ctx; - (void)td; - (void)constraints; - (void)sptr; + (void)ctx; + (void)td; + (void)constraints; + (void)sptr; - while(per_get_few_bits(pd, 24) >= 0); + while (per_get_few_bits(pd, 24) >= 0) + ; - rv.code = RC_OK; - rv.consumed = pd->moved; + rv.code = RC_OK; + rv.consumed = pd->moved; - return rv; + return rv; } static int -uper_ugot_refill(asn_per_data_t *pd) { - uper_ugot_key *arg = pd->refill_key; - ssize_t next_chunk_bytes, next_chunk_bits; - ssize_t avail; +uper_ugot_refill(asn_per_data_t *pd) +{ + uper_ugot_key *arg = pd->refill_key; + ssize_t next_chunk_bytes, next_chunk_bits; + ssize_t avail; - asn_per_data_t *oldpd = &arg->oldpd; + asn_per_data_t *oldpd = &arg->oldpd; - ASN_DEBUG("REFILLING pd->moved=%d, oldpd->moved=%d", - pd->moved, oldpd->moved); + ASN_DEBUG("REFILLING pd->moved=%d, oldpd->moved=%d", + pd->moved, oldpd->moved); - /* Advance our position to where pd is */ - oldpd->buffer = pd->buffer; - oldpd->nboff = pd->nboff; - oldpd->nbits -= pd->moved - arg->ot_moved; - oldpd->moved += pd->moved - arg->ot_moved; - arg->ot_moved = pd->moved; + /* Advance our position to where pd is */ + oldpd->buffer = pd->buffer; + oldpd->nboff = pd->nboff; + oldpd->nbits -= pd->moved - arg->ot_moved; + oldpd->moved += pd->moved - arg->ot_moved; + arg->ot_moved = pd->moved; - if(arg->unclaimed) { - /* Refill the container */ - if(per_get_few_bits(oldpd, 1)) - return -1; - if(oldpd->nboff == 0) { - assert(0); - return -1; - } - pd->buffer = oldpd->buffer; - pd->nboff = oldpd->nboff - 1; - pd->nbits = oldpd->nbits; - ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%d)", pd->moved); - return 0; - } + if (arg->unclaimed) + { + /* Refill the container */ + if (per_get_few_bits(oldpd, 1)) + return -1; + if (oldpd->nboff == 0) + { + assert(0); + return -1; + } + pd->buffer = oldpd->buffer; + pd->nboff = oldpd->nboff - 1; + pd->nbits = oldpd->nbits; + ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%d)", pd->moved); + return 0; + } - if(!arg->repeat) { - ASN_DEBUG("Want more but refill doesn't have it"); - return -1; - } + if (!arg->repeat) + { + ASN_DEBUG("Want more but refill doesn't have it"); + return -1; + } - next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat); - ASN_DEBUG("Open type LENGTH %d bytes at off %d, repeat %d", - next_chunk_bytes, oldpd->moved, arg->repeat); - if(next_chunk_bytes < 0) return -1; - if(next_chunk_bytes == 0) { - pd->refill = 0; /* No more refills, naturally */ - assert(!arg->repeat); /* Implementation guarantee */ - } - next_chunk_bits = next_chunk_bytes << 3; - avail = oldpd->nbits - oldpd->nboff; - if(avail >= next_chunk_bits) { - pd->nbits = oldpd->nboff + next_chunk_bits; - arg->unclaimed = 0; - ASN_DEBUG("!+Parent frame %d bits, alloting %d [%d..%d] (%d)", - next_chunk_bits, oldpd->moved, - oldpd->nboff, oldpd->nbits, - oldpd->nbits - oldpd->nboff); - } else { - pd->nbits = oldpd->nbits; - arg->unclaimed = next_chunk_bits - avail; - ASN_DEBUG("!-Parent frame %d, require %d, will claim %d", avail, next_chunk_bits, arg->unclaimed); - } - pd->buffer = oldpd->buffer; - pd->nboff = oldpd->nboff; - ASN_DEBUG("Refilled pd%s old%s", - per_data_string(pd), per_data_string(oldpd)); - return 0; + next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat); + ASN_DEBUG("Open type LENGTH %d bytes at off %d, repeat %d", + next_chunk_bytes, oldpd->moved, arg->repeat); + if (next_chunk_bytes < 0) return -1; + if (next_chunk_bytes == 0) + { + pd->refill = 0; /* No more refills, naturally */ + assert(!arg->repeat); /* Implementation guarantee */ + } + next_chunk_bits = next_chunk_bytes << 3; + avail = oldpd->nbits - oldpd->nboff; + if (avail >= next_chunk_bits) + { + pd->nbits = oldpd->nboff + next_chunk_bits; + arg->unclaimed = 0; + ASN_DEBUG("!+Parent frame %d bits, alloting %d [%d..%d] (%d)", + next_chunk_bits, oldpd->moved, + oldpd->nboff, oldpd->nbits, + oldpd->nbits - oldpd->nboff); + } + else + { + pd->nbits = oldpd->nbits; + arg->unclaimed = next_chunk_bits - avail; + ASN_DEBUG("!-Parent frame %d, require %d, will claim %d", avail, next_chunk_bits, arg->unclaimed); + } + pd->buffer = oldpd->buffer; + pd->nboff = oldpd->nboff; + ASN_DEBUG("Refilled pd%s old%s", + per_data_string(pd), per_data_string(oldpd)); + return 0; } static int -per_skip_bits(asn_per_data_t *pd, int skip_nbits) { - int hasNonZeroBits = 0; - while(skip_nbits > 0) { - int skip; - if(skip_nbits < skip) - skip = skip_nbits; - else - skip = 24; - skip_nbits -= skip; +per_skip_bits(asn_per_data_t *pd, int skip_nbits) +{ + int hasNonZeroBits = 0; + while (skip_nbits > 0) + { + int skip = 0; + if (skip_nbits < skip) + skip = skip_nbits; + else + skip = 24; + skip_nbits -= skip; - switch(per_get_few_bits(pd, skip)) { - case -1: return -1; /* Starving */ - case 0: continue; /* Skipped empty space */ - default: hasNonZeroBits = 1; continue; - } - } - return hasNonZeroBits; + switch (per_get_few_bits(pd, skip)) + { + case -1: + return -1; /* Starving */ + case 0: + continue; /* Skipped empty space */ + default: + hasNonZeroBits = 1; + continue; + } + } + return hasNonZeroBits; } diff --git a/src/core/libs/supl/asn-supl/Horandveruncert.c b/src/core/libs/supl/asn-supl/Horandveruncert.c index 6df8af075..a73928d71 100644 --- a/src/core/libs/supl/asn-supl/Horandveruncert.c +++ b/src/core/libs/supl/asn-supl/Horandveruncert.c @@ -8,318 +8,356 @@ static int memb_verdirect_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 1)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 1) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_bearing_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 9)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 9) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_horspeed_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 16)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 16) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_verspeed_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 8)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 8) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_horuncertspeed_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 8)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 8) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_veruncertspeed_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 8)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 8) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static asn_per_constraints_t asn_PER_memb_verdirect_constr_2 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 1, 1 } /* (SIZE(1..1)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 1, 1} /* (SIZE(1..1)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_bearing_constr_3 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 9, 9 } /* (SIZE(9..9)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 9, 9} /* (SIZE(9..9)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_horspeed_constr_4 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 16, 16 } /* (SIZE(16..16)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 16, 16} /* (SIZE(16..16)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_verspeed_constr_5 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 8, 8 } /* (SIZE(8..8)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 8, 8} /* (SIZE(8..8)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_horuncertspeed_constr_6 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 8, 8 } /* (SIZE(8..8)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 8, 8} /* (SIZE(8..8)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_veruncertspeed_constr_7 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 8, 8 } /* (SIZE(8..8)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 8, 8} /* (SIZE(8..8)) */, + 0, 0 /* No PER value map */ }; static asn_TYPE_member_t asn_MBR_Horandveruncert_1[] = { - { ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, verdirect), - (ASN_TAG_CLASS_CONTEXT | (0 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_verdirect_constraint_1, - &asn_PER_memb_verdirect_constr_2, - 0, - "verdirect" - }, - { ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, bearing), - (ASN_TAG_CLASS_CONTEXT | (1 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_bearing_constraint_1, - &asn_PER_memb_bearing_constr_3, - 0, - "bearing" - }, - { ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, horspeed), - (ASN_TAG_CLASS_CONTEXT | (2 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_horspeed_constraint_1, - &asn_PER_memb_horspeed_constr_4, - 0, - "horspeed" - }, - { ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, verspeed), - (ASN_TAG_CLASS_CONTEXT | (3 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_verspeed_constraint_1, - &asn_PER_memb_verspeed_constr_5, - 0, - "verspeed" - }, - { ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, horuncertspeed), - (ASN_TAG_CLASS_CONTEXT | (4 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_horuncertspeed_constraint_1, - &asn_PER_memb_horuncertspeed_constr_6, - 0, - "horuncertspeed" - }, - { ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, veruncertspeed), - (ASN_TAG_CLASS_CONTEXT | (5 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_veruncertspeed_constraint_1, - &asn_PER_memb_veruncertspeed_constr_7, - 0, - "veruncertspeed" - }, + {ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, verdirect), + (ASN_TAG_CLASS_CONTEXT | (0 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_verdirect_constraint_1, + &asn_PER_memb_verdirect_constr_2, + 0, + "verdirect"}, + {ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, bearing), + (ASN_TAG_CLASS_CONTEXT | (1 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_bearing_constraint_1, + &asn_PER_memb_bearing_constr_3, + 0, + "bearing"}, + {ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, horspeed), + (ASN_TAG_CLASS_CONTEXT | (2 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_horspeed_constraint_1, + &asn_PER_memb_horspeed_constr_4, + 0, + "horspeed"}, + {ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, verspeed), + (ASN_TAG_CLASS_CONTEXT | (3 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_verspeed_constraint_1, + &asn_PER_memb_verspeed_constr_5, + 0, + "verspeed"}, + {ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, horuncertspeed), + (ASN_TAG_CLASS_CONTEXT | (4 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_horuncertspeed_constraint_1, + &asn_PER_memb_horuncertspeed_constr_6, + 0, + "horuncertspeed"}, + {ATF_NOFLAGS, 0, offsetof(struct Horandveruncert, veruncertspeed), + (ASN_TAG_CLASS_CONTEXT | (5 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_veruncertspeed_constraint_1, + &asn_PER_memb_veruncertspeed_constr_7, + 0, + "veruncertspeed"}, }; static ber_tlv_tag_t asn_DEF_Horandveruncert_tags_1[] = { - (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) -}; + (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))}; static asn_TYPE_tag2member_t asn_MAP_Horandveruncert_tag2el_1[] = { - { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* verdirect at 251 */ - { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* bearing at 252 */ - { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* horspeed at 253 */ - { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 }, /* verspeed at 254 */ - { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 }, /* horuncertspeed at 255 */ - { (ASN_TAG_CLASS_CONTEXT | (5 << 2)), 5, 0, 0 } /* veruncertspeed at 256 */ + {(ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0}, /* verdirect at 251 */ + {(ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0}, /* bearing at 252 */ + {(ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0}, /* horspeed at 253 */ + {(ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0}, /* verspeed at 254 */ + {(ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0}, /* horuncertspeed at 255 */ + {(ASN_TAG_CLASS_CONTEXT | (5 << 2)), 5, 0, 0} /* veruncertspeed at 256 */ }; static asn_SEQUENCE_specifics_t asn_SPC_Horandveruncert_specs_1 = { - sizeof(struct Horandveruncert), - offsetof(struct Horandveruncert, _asn_ctx), - asn_MAP_Horandveruncert_tag2el_1, - 6, /* Count of tags in the map */ - 0, 0, 0, /* Optional elements (not needed) */ - 5, /* Start extensions */ - 7 /* Stop extensions */ + sizeof(struct Horandveruncert), + offsetof(struct Horandveruncert, _asn_ctx), + asn_MAP_Horandveruncert_tag2el_1, + 6, /* Count of tags in the map */ + 0, 0, 0, /* Optional elements (not needed) */ + 5, /* Start extensions */ + 7 /* Stop extensions */ }; asn_TYPE_descriptor_t asn_DEF_Horandveruncert = { - "Horandveruncert", - "Horandveruncert", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - SEQUENCE_decode_uper, - SEQUENCE_encode_uper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_Horandveruncert_tags_1, - sizeof(asn_DEF_Horandveruncert_tags_1) - /sizeof(asn_DEF_Horandveruncert_tags_1[0]), /* 1 */ - asn_DEF_Horandveruncert_tags_1, /* Same as above */ - sizeof(asn_DEF_Horandveruncert_tags_1) - /sizeof(asn_DEF_Horandveruncert_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ - asn_MBR_Horandveruncert_1, - 6, /* Elements count */ - &asn_SPC_Horandveruncert_specs_1 /* Additional specs */ + "Horandveruncert", + "Horandveruncert", + SEQUENCE_free, + SEQUENCE_print, + SEQUENCE_constraint, + SEQUENCE_decode_ber, + SEQUENCE_encode_der, + SEQUENCE_decode_xer, + SEQUENCE_encode_xer, + SEQUENCE_decode_uper, + SEQUENCE_encode_uper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_Horandveruncert_tags_1, + sizeof(asn_DEF_Horandveruncert_tags_1) / sizeof(asn_DEF_Horandveruncert_tags_1[0]), /* 1 */ + asn_DEF_Horandveruncert_tags_1, /* Same as above */ + sizeof(asn_DEF_Horandveruncert_tags_1) / sizeof(asn_DEF_Horandveruncert_tags_1[0]), /* 1 */ + 0, /* No PER visible constraints */ + asn_MBR_Horandveruncert_1, + 6, /* Elements count */ + &asn_SPC_Horandveruncert_specs_1 /* Additional specs */ }; - diff --git a/src/core/libs/supl/asn-supl/Horandvervel.c b/src/core/libs/supl/asn-supl/Horandvervel.c index cfc81cfc9..b91d072e1 100644 --- a/src/core/libs/supl/asn-supl/Horandvervel.c +++ b/src/core/libs/supl/asn-supl/Horandvervel.c @@ -8,226 +8,250 @@ static int memb_verdirect_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 1)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 1) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_bearing_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 9)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 9) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_horspeed_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 16)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 16) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_verspeed_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 8)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 8) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static asn_per_constraints_t asn_PER_memb_verdirect_constr_2 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 1, 1 } /* (SIZE(1..1)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 1, 1} /* (SIZE(1..1)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_bearing_constr_3 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 9, 9 } /* (SIZE(9..9)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 9, 9} /* (SIZE(9..9)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_horspeed_constr_4 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 16, 16 } /* (SIZE(16..16)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 16, 16} /* (SIZE(16..16)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_verspeed_constr_5 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 8, 8 } /* (SIZE(8..8)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 8, 8} /* (SIZE(8..8)) */, + 0, 0 /* No PER value map */ }; static asn_TYPE_member_t asn_MBR_Horandvervel_1[] = { - { ATF_NOFLAGS, 0, offsetof(struct Horandvervel, verdirect), - (ASN_TAG_CLASS_CONTEXT | (0 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_verdirect_constraint_1, - &asn_PER_memb_verdirect_constr_2, - 0, - "verdirect" - }, - { ATF_NOFLAGS, 0, offsetof(struct Horandvervel, bearing), - (ASN_TAG_CLASS_CONTEXT | (1 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_bearing_constraint_1, - &asn_PER_memb_bearing_constr_3, - 0, - "bearing" - }, - { ATF_NOFLAGS, 0, offsetof(struct Horandvervel, horspeed), - (ASN_TAG_CLASS_CONTEXT | (2 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_horspeed_constraint_1, - &asn_PER_memb_horspeed_constr_4, - 0, - "horspeed" - }, - { ATF_NOFLAGS, 0, offsetof(struct Horandvervel, verspeed), - (ASN_TAG_CLASS_CONTEXT | (3 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_verspeed_constraint_1, - &asn_PER_memb_verspeed_constr_5, - 0, - "verspeed" - }, + {ATF_NOFLAGS, 0, offsetof(struct Horandvervel, verdirect), + (ASN_TAG_CLASS_CONTEXT | (0 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_verdirect_constraint_1, + &asn_PER_memb_verdirect_constr_2, + 0, + "verdirect"}, + {ATF_NOFLAGS, 0, offsetof(struct Horandvervel, bearing), + (ASN_TAG_CLASS_CONTEXT | (1 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_bearing_constraint_1, + &asn_PER_memb_bearing_constr_3, + 0, + "bearing"}, + {ATF_NOFLAGS, 0, offsetof(struct Horandvervel, horspeed), + (ASN_TAG_CLASS_CONTEXT | (2 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_horspeed_constraint_1, + &asn_PER_memb_horspeed_constr_4, + 0, + "horspeed"}, + {ATF_NOFLAGS, 0, offsetof(struct Horandvervel, verspeed), + (ASN_TAG_CLASS_CONTEXT | (3 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_verspeed_constraint_1, + &asn_PER_memb_verspeed_constr_5, + 0, + "verspeed"}, }; static ber_tlv_tag_t asn_DEF_Horandvervel_tags_1[] = { - (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) -}; + (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))}; static asn_TYPE_tag2member_t asn_MAP_Horandvervel_tag2el_1[] = { - { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* verdirect at 238 */ - { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* bearing at 239 */ - { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* horspeed at 240 */ - { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 } /* verspeed at 241 */ + {(ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0}, /* verdirect at 238 */ + {(ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0}, /* bearing at 239 */ + {(ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0}, /* horspeed at 240 */ + {(ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0} /* verspeed at 241 */ }; static asn_SEQUENCE_specifics_t asn_SPC_Horandvervel_specs_1 = { - sizeof(struct Horandvervel), - offsetof(struct Horandvervel, _asn_ctx), - asn_MAP_Horandvervel_tag2el_1, - 4, /* Count of tags in the map */ - 0, 0, 0, /* Optional elements (not needed) */ - 3, /* Start extensions */ - 5 /* Stop extensions */ + sizeof(struct Horandvervel), + offsetof(struct Horandvervel, _asn_ctx), + asn_MAP_Horandvervel_tag2el_1, + 4, /* Count of tags in the map */ + 0, 0, 0, /* Optional elements (not needed) */ + 3, /* Start extensions */ + 5 /* Stop extensions */ }; asn_TYPE_descriptor_t asn_DEF_Horandvervel = { - "Horandvervel", - "Horandvervel", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - SEQUENCE_decode_uper, - SEQUENCE_encode_uper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_Horandvervel_tags_1, - sizeof(asn_DEF_Horandvervel_tags_1) - /sizeof(asn_DEF_Horandvervel_tags_1[0]), /* 1 */ - asn_DEF_Horandvervel_tags_1, /* Same as above */ - sizeof(asn_DEF_Horandvervel_tags_1) - /sizeof(asn_DEF_Horandvervel_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ - asn_MBR_Horandvervel_1, - 4, /* Elements count */ - &asn_SPC_Horandvervel_specs_1 /* Additional specs */ + "Horandvervel", + "Horandvervel", + SEQUENCE_free, + SEQUENCE_print, + SEQUENCE_constraint, + SEQUENCE_decode_ber, + SEQUENCE_encode_der, + SEQUENCE_decode_xer, + SEQUENCE_encode_xer, + SEQUENCE_decode_uper, + SEQUENCE_encode_uper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_Horandvervel_tags_1, + sizeof(asn_DEF_Horandvervel_tags_1) / sizeof(asn_DEF_Horandvervel_tags_1[0]), /* 1 */ + asn_DEF_Horandvervel_tags_1, /* Same as above */ + sizeof(asn_DEF_Horandvervel_tags_1) / sizeof(asn_DEF_Horandvervel_tags_1[0]), /* 1 */ + 0, /* No PER visible constraints */ + asn_MBR_Horandvervel_1, + 4, /* Elements count */ + &asn_SPC_Horandvervel_specs_1 /* Additional specs */ }; - diff --git a/src/core/libs/supl/asn-supl/Horvel.c b/src/core/libs/supl/asn-supl/Horvel.c index bf9914452..7c2080fff 100644 --- a/src/core/libs/supl/asn-supl/Horvel.c +++ b/src/core/libs/supl/asn-supl/Horvel.c @@ -8,134 +8,144 @@ static int memb_bearing_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 9)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 9) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_horspeed_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 16)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 16) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static asn_per_constraints_t asn_PER_memb_bearing_constr_2 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 9, 9 } /* (SIZE(9..9)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 9, 9} /* (SIZE(9..9)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_horspeed_constr_3 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 16, 16 } /* (SIZE(16..16)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 16, 16} /* (SIZE(16..16)) */, + 0, 0 /* No PER value map */ }; static asn_TYPE_member_t asn_MBR_Horvel_1[] = { - { ATF_NOFLAGS, 0, offsetof(struct Horvel, bearing), - (ASN_TAG_CLASS_CONTEXT | (0 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_bearing_constraint_1, - &asn_PER_memb_bearing_constr_2, - 0, - "bearing" - }, - { ATF_NOFLAGS, 0, offsetof(struct Horvel, horspeed), - (ASN_TAG_CLASS_CONTEXT | (1 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_horspeed_constraint_1, - &asn_PER_memb_horspeed_constr_3, - 0, - "horspeed" - }, + {ATF_NOFLAGS, 0, offsetof(struct Horvel, bearing), + (ASN_TAG_CLASS_CONTEXT | (0 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_bearing_constraint_1, + &asn_PER_memb_bearing_constr_2, + 0, + "bearing"}, + {ATF_NOFLAGS, 0, offsetof(struct Horvel, horspeed), + (ASN_TAG_CLASS_CONTEXT | (1 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_horspeed_constraint_1, + &asn_PER_memb_horspeed_constr_3, + 0, + "horspeed"}, }; static ber_tlv_tag_t asn_DEF_Horvel_tags_1[] = { - (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) -}; + (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))}; static asn_TYPE_tag2member_t asn_MAP_Horvel_tag2el_1[] = { - { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* bearing at 233 */ - { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* horspeed at 234 */ + {(ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0}, /* bearing at 233 */ + {(ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0} /* horspeed at 234 */ }; static asn_SEQUENCE_specifics_t asn_SPC_Horvel_specs_1 = { - sizeof(struct Horvel), - offsetof(struct Horvel, _asn_ctx), - asn_MAP_Horvel_tag2el_1, - 2, /* Count of tags in the map */ - 0, 0, 0, /* Optional elements (not needed) */ - 1, /* Start extensions */ - 3 /* Stop extensions */ + sizeof(struct Horvel), + offsetof(struct Horvel, _asn_ctx), + asn_MAP_Horvel_tag2el_1, + 2, /* Count of tags in the map */ + 0, 0, 0, /* Optional elements (not needed) */ + 1, /* Start extensions */ + 3 /* Stop extensions */ }; asn_TYPE_descriptor_t asn_DEF_Horvel = { - "Horvel", - "Horvel", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - SEQUENCE_decode_uper, - SEQUENCE_encode_uper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_Horvel_tags_1, - sizeof(asn_DEF_Horvel_tags_1) - /sizeof(asn_DEF_Horvel_tags_1[0]), /* 1 */ - asn_DEF_Horvel_tags_1, /* Same as above */ - sizeof(asn_DEF_Horvel_tags_1) - /sizeof(asn_DEF_Horvel_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ - asn_MBR_Horvel_1, - 2, /* Elements count */ - &asn_SPC_Horvel_specs_1 /* Additional specs */ + "Horvel", + "Horvel", + SEQUENCE_free, + SEQUENCE_print, + SEQUENCE_constraint, + SEQUENCE_decode_ber, + SEQUENCE_encode_der, + SEQUENCE_decode_xer, + SEQUENCE_encode_xer, + SEQUENCE_decode_uper, + SEQUENCE_encode_uper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_Horvel_tags_1, + sizeof(asn_DEF_Horvel_tags_1) / sizeof(asn_DEF_Horvel_tags_1[0]), /* 1 */ + asn_DEF_Horvel_tags_1, /* Same as above */ + sizeof(asn_DEF_Horvel_tags_1) / sizeof(asn_DEF_Horvel_tags_1[0]), /* 1 */ + 0, /* No PER visible constraints */ + asn_MBR_Horvel_1, + 2, /* Elements count */ + &asn_SPC_Horvel_specs_1 /* Additional specs */ }; - diff --git a/src/core/libs/supl/asn-supl/Horveluncert.c b/src/core/libs/supl/asn-supl/Horveluncert.c index ca12ff352..b3983f3f6 100644 --- a/src/core/libs/supl/asn-supl/Horveluncert.c +++ b/src/core/libs/supl/asn-supl/Horveluncert.c @@ -8,180 +8,197 @@ static int memb_bearing_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 9)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 9) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_horspeed_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 16)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 16) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_uncertspeed_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 8)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 8) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static asn_per_constraints_t asn_PER_memb_bearing_constr_2 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 9, 9 } /* (SIZE(9..9)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 9, 9} /* (SIZE(9..9)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_horspeed_constr_3 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 16, 16 } /* (SIZE(16..16)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 16, 16} /* (SIZE(16..16)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_uncertspeed_constr_4 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 8, 8 } /* (SIZE(8..8)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 8, 8} /* (SIZE(8..8)) */, + 0, 0 /* No PER value map */ }; static asn_TYPE_member_t asn_MBR_Horveluncert_1[] = { - { ATF_NOFLAGS, 0, offsetof(struct Horveluncert, bearing), - (ASN_TAG_CLASS_CONTEXT | (0 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_bearing_constraint_1, - &asn_PER_memb_bearing_constr_2, - 0, - "bearing" - }, - { ATF_NOFLAGS, 0, offsetof(struct Horveluncert, horspeed), - (ASN_TAG_CLASS_CONTEXT | (1 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_horspeed_constraint_1, - &asn_PER_memb_horspeed_constr_3, - 0, - "horspeed" - }, - { ATF_NOFLAGS, 0, offsetof(struct Horveluncert, uncertspeed), - (ASN_TAG_CLASS_CONTEXT | (2 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_uncertspeed_constraint_1, - &asn_PER_memb_uncertspeed_constr_4, - 0, - "uncertspeed" - }, + {ATF_NOFLAGS, 0, offsetof(struct Horveluncert, bearing), + (ASN_TAG_CLASS_CONTEXT | (0 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_bearing_constraint_1, + &asn_PER_memb_bearing_constr_2, + 0, + "bearing"}, + {ATF_NOFLAGS, 0, offsetof(struct Horveluncert, horspeed), + (ASN_TAG_CLASS_CONTEXT | (1 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_horspeed_constraint_1, + &asn_PER_memb_horspeed_constr_3, + 0, + "horspeed"}, + {ATF_NOFLAGS, 0, offsetof(struct Horveluncert, uncertspeed), + (ASN_TAG_CLASS_CONTEXT | (2 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_uncertspeed_constraint_1, + &asn_PER_memb_uncertspeed_constr_4, + 0, + "uncertspeed"}, }; static ber_tlv_tag_t asn_DEF_Horveluncert_tags_1[] = { - (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) -}; + (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))}; static asn_TYPE_tag2member_t asn_MAP_Horveluncert_tag2el_1[] = { - { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* bearing at 245 */ - { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* horspeed at 246 */ - { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* uncertspeed at 247 */ + {(ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0}, /* bearing at 245 */ + {(ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0}, /* horspeed at 246 */ + {(ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0} /* uncertspeed at 247 */ }; static asn_SEQUENCE_specifics_t asn_SPC_Horveluncert_specs_1 = { - sizeof(struct Horveluncert), - offsetof(struct Horveluncert, _asn_ctx), - asn_MAP_Horveluncert_tag2el_1, - 3, /* Count of tags in the map */ - 0, 0, 0, /* Optional elements (not needed) */ - 2, /* Start extensions */ - 4 /* Stop extensions */ + sizeof(struct Horveluncert), + offsetof(struct Horveluncert, _asn_ctx), + asn_MAP_Horveluncert_tag2el_1, + 3, /* Count of tags in the map */ + 0, 0, 0, /* Optional elements (not needed) */ + 2, /* Start extensions */ + 4 /* Stop extensions */ }; asn_TYPE_descriptor_t asn_DEF_Horveluncert = { - "Horveluncert", - "Horveluncert", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - SEQUENCE_decode_uper, - SEQUENCE_encode_uper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_Horveluncert_tags_1, - sizeof(asn_DEF_Horveluncert_tags_1) - /sizeof(asn_DEF_Horveluncert_tags_1[0]), /* 1 */ - asn_DEF_Horveluncert_tags_1, /* Same as above */ - sizeof(asn_DEF_Horveluncert_tags_1) - /sizeof(asn_DEF_Horveluncert_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ - asn_MBR_Horveluncert_1, - 3, /* Elements count */ - &asn_SPC_Horveluncert_specs_1 /* Additional specs */ + "Horveluncert", + "Horveluncert", + SEQUENCE_free, + SEQUENCE_print, + SEQUENCE_constraint, + SEQUENCE_decode_ber, + SEQUENCE_encode_der, + SEQUENCE_decode_xer, + SEQUENCE_encode_xer, + SEQUENCE_decode_uper, + SEQUENCE_encode_uper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_Horveluncert_tags_1, + sizeof(asn_DEF_Horveluncert_tags_1) / sizeof(asn_DEF_Horveluncert_tags_1[0]), /* 1 */ + asn_DEF_Horveluncert_tags_1, /* Same as above */ + sizeof(asn_DEF_Horveluncert_tags_1) / sizeof(asn_DEF_Horveluncert_tags_1[0]), /* 1 */ + 0, /* No PER visible constraints */ + asn_MBR_Horveluncert_1, + 3, /* Elements count */ + &asn_SPC_Horveluncert_specs_1 /* Additional specs */ }; - diff --git a/src/core/libs/supl/asn-supl/IPAddress.c b/src/core/libs/supl/asn-supl/IPAddress.c index ddbef08c4..f1861adac 100644 --- a/src/core/libs/supl/asn-supl/IPAddress.c +++ b/src/core/libs/supl/asn-supl/IPAddress.c @@ -8,125 +8,132 @@ static int memb_ipv4Address_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - size = st->size; - - if((size == 4)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + size = st->size; + + if (size == 4) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_ipv6Address_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - size = st->size; - - if((size == 16)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + size = st->size; + + if (size == 16) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static asn_per_constraints_t asn_PER_memb_ipv4Address_constr_2 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 4, 4 } /* (SIZE(4..4)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 4, 4} /* (SIZE(4..4)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_ipv6Address_constr_3 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 16, 16 } /* (SIZE(16..16)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 16, 16} /* (SIZE(16..16)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_type_IPAddress_constr_1 = { - { APC_CONSTRAINED, 1, 1, 0, 1 } /* (0..1) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - 0, 0 /* No PER value map */ + {APC_CONSTRAINED, 1, 1, 0, 1} /* (0..1) */, + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + 0, 0 /* No PER value map */ }; static asn_TYPE_member_t asn_MBR_IPAddress_1[] = { - { ATF_NOFLAGS, 0, offsetof(struct IPAddress, choice.ipv4Address), - (ASN_TAG_CLASS_CONTEXT | (0 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_OCTET_STRING, - memb_ipv4Address_constraint_1, - &asn_PER_memb_ipv4Address_constr_2, - 0, - "ipv4Address" - }, - { ATF_NOFLAGS, 0, offsetof(struct IPAddress, choice.ipv6Address), - (ASN_TAG_CLASS_CONTEXT | (1 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_OCTET_STRING, - memb_ipv6Address_constraint_1, - &asn_PER_memb_ipv6Address_constr_3, - 0, - "ipv6Address" - }, + {ATF_NOFLAGS, 0, offsetof(struct IPAddress, choice.ipv4Address), + (ASN_TAG_CLASS_CONTEXT | (0 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_OCTET_STRING, + memb_ipv4Address_constraint_1, + &asn_PER_memb_ipv4Address_constr_2, + 0, + "ipv4Address"}, + {ATF_NOFLAGS, 0, offsetof(struct IPAddress, choice.ipv6Address), + (ASN_TAG_CLASS_CONTEXT | (1 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_OCTET_STRING, + memb_ipv6Address_constraint_1, + &asn_PER_memb_ipv6Address_constr_3, + 0, + "ipv6Address"}, }; static asn_TYPE_tag2member_t asn_MAP_IPAddress_tag2el_1[] = { - { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* ipv4Address at 41 */ - { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* ipv6Address at 42 */ + {(ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0}, /* ipv4Address at 41 */ + {(ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0} /* ipv6Address at 42 */ }; static asn_CHOICE_specifics_t asn_SPC_IPAddress_specs_1 = { - sizeof(struct IPAddress), - offsetof(struct IPAddress, _asn_ctx), - offsetof(struct IPAddress, present), - sizeof(((struct IPAddress *)0)->present), - asn_MAP_IPAddress_tag2el_1, - 2, /* Count of tags in the map */ - 0, - -1 /* Extensions start */ + sizeof(struct IPAddress), + offsetof(struct IPAddress, _asn_ctx), + offsetof(struct IPAddress, present), + sizeof(((struct IPAddress *)0)->present), + asn_MAP_IPAddress_tag2el_1, + 2, /* Count of tags in the map */ + 0, + -1 /* Extensions start */ }; asn_TYPE_descriptor_t asn_DEF_IPAddress = { - "IPAddress", - "IPAddress", - CHOICE_free, - CHOICE_print, - CHOICE_constraint, - CHOICE_decode_ber, - CHOICE_encode_der, - CHOICE_decode_xer, - CHOICE_encode_xer, - CHOICE_decode_uper, - CHOICE_encode_uper, - CHOICE_outmost_tag, - 0, /* No effective tags (pointer) */ - 0, /* No effective tags (count) */ - 0, /* No tags (pointer) */ - 0, /* No tags (count) */ - &asn_PER_type_IPAddress_constr_1, - asn_MBR_IPAddress_1, - 2, /* Elements count */ - &asn_SPC_IPAddress_specs_1 /* Additional specs */ + "IPAddress", + "IPAddress", + CHOICE_free, + CHOICE_print, + CHOICE_constraint, + CHOICE_decode_ber, + CHOICE_encode_der, + CHOICE_decode_xer, + CHOICE_encode_xer, + CHOICE_decode_uper, + CHOICE_encode_uper, + CHOICE_outmost_tag, + 0, /* No effective tags (pointer) */ + 0, /* No effective tags (count) */ + 0, /* No tags (pointer) */ + 0, /* No tags (count) */ + &asn_PER_type_IPAddress_constr_1, + asn_MBR_IPAddress_1, + 2, /* Elements count */ + &asn_SPC_IPAddress_specs_1 /* Additional specs */ }; - diff --git a/src/core/libs/supl/asn-supl/KeyIdentity.c b/src/core/libs/supl/asn-supl/KeyIdentity.c index 210eacb06..49104664a 100644 --- a/src/core/libs/supl/asn-supl/KeyIdentity.c +++ b/src/core/libs/supl/asn-supl/KeyIdentity.c @@ -6,35 +6,42 @@ #include "KeyIdentity.h" -int -KeyIdentity_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 128)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } +int KeyIdentity_constraint(asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 128) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } /* @@ -42,110 +49,113 @@ KeyIdentity_constraint(asn_TYPE_descriptor_t *td, const void *sptr, * so here we adjust the DEF accordingly. */ static void -KeyIdentity_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_BIT_STRING.free_struct; - td->print_struct = asn_DEF_BIT_STRING.print_struct; - td->ber_decoder = asn_DEF_BIT_STRING.ber_decoder; - td->der_encoder = asn_DEF_BIT_STRING.der_encoder; - td->xer_decoder = asn_DEF_BIT_STRING.xer_decoder; - td->xer_encoder = asn_DEF_BIT_STRING.xer_encoder; - td->uper_decoder = asn_DEF_BIT_STRING.uper_decoder; - td->uper_encoder = asn_DEF_BIT_STRING.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_BIT_STRING.per_constraints; - td->elements = asn_DEF_BIT_STRING.elements; - td->elements_count = asn_DEF_BIT_STRING.elements_count; - td->specifics = asn_DEF_BIT_STRING.specifics; +KeyIdentity_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) +{ + td->free_struct = asn_DEF_BIT_STRING.free_struct; + td->print_struct = asn_DEF_BIT_STRING.print_struct; + td->ber_decoder = asn_DEF_BIT_STRING.ber_decoder; + td->der_encoder = asn_DEF_BIT_STRING.der_encoder; + td->xer_decoder = asn_DEF_BIT_STRING.xer_decoder; + td->xer_encoder = asn_DEF_BIT_STRING.xer_encoder; + td->uper_decoder = asn_DEF_BIT_STRING.uper_decoder; + td->uper_encoder = asn_DEF_BIT_STRING.uper_encoder; + if (!td->per_constraints) + td->per_constraints = asn_DEF_BIT_STRING.per_constraints; + td->elements = asn_DEF_BIT_STRING.elements; + td->elements_count = asn_DEF_BIT_STRING.elements_count; + td->specifics = asn_DEF_BIT_STRING.specifics; } -void -KeyIdentity_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - KeyIdentity_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); +void KeyIdentity_free(asn_TYPE_descriptor_t *td, + void *struct_ptr, int contents_only) +{ + KeyIdentity_1_inherit_TYPE_descriptor(td); + td->free_struct(td, struct_ptr, contents_only); } -int -KeyIdentity_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - KeyIdentity_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); +int KeyIdentity_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, + int ilevel, asn_app_consume_bytes_f *cb, void *app_key) +{ + KeyIdentity_1_inherit_TYPE_descriptor(td); + return td->print_struct(td, struct_ptr, ilevel, cb, app_key); } asn_dec_rval_t KeyIdentity_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - KeyIdentity_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); + void **structure, const void *bufptr, size_t size, int tag_mode) +{ + KeyIdentity_1_inherit_TYPE_descriptor(td); + return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); } asn_enc_rval_t KeyIdentity_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - KeyIdentity_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); + void *structure, int tag_mode, ber_tlv_tag_t tag, + asn_app_consume_bytes_f *cb, void *app_key) +{ + KeyIdentity_1_inherit_TYPE_descriptor(td); + return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); } asn_dec_rval_t KeyIdentity_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - KeyIdentity_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); + void **structure, const char *opt_mname, const void *bufptr, size_t size) +{ + KeyIdentity_1_inherit_TYPE_descriptor(td); + return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); } asn_enc_rval_t KeyIdentity_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - KeyIdentity_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) +{ + KeyIdentity_1_inherit_TYPE_descriptor(td); + return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); } asn_dec_rval_t KeyIdentity_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) { - KeyIdentity_1_inherit_TYPE_descriptor(td); - return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data); + asn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) +{ + KeyIdentity_1_inherit_TYPE_descriptor(td); + return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data); } asn_enc_rval_t KeyIdentity_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, - void *structure, asn_per_outp_t *per_out) { - KeyIdentity_1_inherit_TYPE_descriptor(td); - return td->uper_encoder(td, constraints, structure, per_out); + asn_per_constraints_t *constraints, + void *structure, asn_per_outp_t *per_out) +{ + KeyIdentity_1_inherit_TYPE_descriptor(td); + return td->uper_encoder(td, constraints, structure, per_out); } static asn_per_constraints_t asn_PER_type_KeyIdentity_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 128, 128 } /* (SIZE(128..128)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 128, 128} /* (SIZE(128..128)) */, + 0, 0 /* No PER value map */ }; static ber_tlv_tag_t asn_DEF_KeyIdentity_tags_1[] = { - (ASN_TAG_CLASS_UNIVERSAL | (3 << 2)) -}; + (ASN_TAG_CLASS_UNIVERSAL | (3 << 2))}; asn_TYPE_descriptor_t asn_DEF_KeyIdentity = { - "KeyIdentity", - "KeyIdentity", - KeyIdentity_free, - KeyIdentity_print, - KeyIdentity_constraint, - KeyIdentity_decode_ber, - KeyIdentity_encode_der, - KeyIdentity_decode_xer, - KeyIdentity_encode_xer, - KeyIdentity_decode_uper, - KeyIdentity_encode_uper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_KeyIdentity_tags_1, - sizeof(asn_DEF_KeyIdentity_tags_1) - /sizeof(asn_DEF_KeyIdentity_tags_1[0]), /* 1 */ - asn_DEF_KeyIdentity_tags_1, /* Same as above */ - sizeof(asn_DEF_KeyIdentity_tags_1) - /sizeof(asn_DEF_KeyIdentity_tags_1[0]), /* 1 */ - &asn_PER_type_KeyIdentity_constr_1, - 0, 0, /* No members */ - 0 /* No specifics */ + "KeyIdentity", + "KeyIdentity", + KeyIdentity_free, + KeyIdentity_print, + KeyIdentity_constraint, + KeyIdentity_decode_ber, + KeyIdentity_encode_der, + KeyIdentity_decode_xer, + KeyIdentity_encode_xer, + KeyIdentity_decode_uper, + KeyIdentity_encode_uper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_KeyIdentity_tags_1, + sizeof(asn_DEF_KeyIdentity_tags_1) / sizeof(asn_DEF_KeyIdentity_tags_1[0]), /* 1 */ + asn_DEF_KeyIdentity_tags_1, /* Same as above */ + sizeof(asn_DEF_KeyIdentity_tags_1) / sizeof(asn_DEF_KeyIdentity_tags_1[0]), /* 1 */ + &asn_PER_type_KeyIdentity_constr_1, + 0, 0, /* No members */ + 0 /* No specifics */ }; - diff --git a/src/core/libs/supl/asn-supl/KeyIdentity4.c b/src/core/libs/supl/asn-supl/KeyIdentity4.c index 1a993f1bd..ef652c319 100644 --- a/src/core/libs/supl/asn-supl/KeyIdentity4.c +++ b/src/core/libs/supl/asn-supl/KeyIdentity4.c @@ -6,35 +6,42 @@ #include "KeyIdentity4.h" -int -KeyIdentity4_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 128)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } +int KeyIdentity4_constraint(asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 128) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } /* @@ -42,110 +49,113 @@ KeyIdentity4_constraint(asn_TYPE_descriptor_t *td, const void *sptr, * so here we adjust the DEF accordingly. */ static void -KeyIdentity4_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_BIT_STRING.free_struct; - td->print_struct = asn_DEF_BIT_STRING.print_struct; - td->ber_decoder = asn_DEF_BIT_STRING.ber_decoder; - td->der_encoder = asn_DEF_BIT_STRING.der_encoder; - td->xer_decoder = asn_DEF_BIT_STRING.xer_decoder; - td->xer_encoder = asn_DEF_BIT_STRING.xer_encoder; - td->uper_decoder = asn_DEF_BIT_STRING.uper_decoder; - td->uper_encoder = asn_DEF_BIT_STRING.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_BIT_STRING.per_constraints; - td->elements = asn_DEF_BIT_STRING.elements; - td->elements_count = asn_DEF_BIT_STRING.elements_count; - td->specifics = asn_DEF_BIT_STRING.specifics; +KeyIdentity4_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) +{ + td->free_struct = asn_DEF_BIT_STRING.free_struct; + td->print_struct = asn_DEF_BIT_STRING.print_struct; + td->ber_decoder = asn_DEF_BIT_STRING.ber_decoder; + td->der_encoder = asn_DEF_BIT_STRING.der_encoder; + td->xer_decoder = asn_DEF_BIT_STRING.xer_decoder; + td->xer_encoder = asn_DEF_BIT_STRING.xer_encoder; + td->uper_decoder = asn_DEF_BIT_STRING.uper_decoder; + td->uper_encoder = asn_DEF_BIT_STRING.uper_encoder; + if (!td->per_constraints) + td->per_constraints = asn_DEF_BIT_STRING.per_constraints; + td->elements = asn_DEF_BIT_STRING.elements; + td->elements_count = asn_DEF_BIT_STRING.elements_count; + td->specifics = asn_DEF_BIT_STRING.specifics; } -void -KeyIdentity4_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - KeyIdentity4_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); +void KeyIdentity4_free(asn_TYPE_descriptor_t *td, + void *struct_ptr, int contents_only) +{ + KeyIdentity4_1_inherit_TYPE_descriptor(td); + td->free_struct(td, struct_ptr, contents_only); } -int -KeyIdentity4_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - KeyIdentity4_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); +int KeyIdentity4_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, + int ilevel, asn_app_consume_bytes_f *cb, void *app_key) +{ + KeyIdentity4_1_inherit_TYPE_descriptor(td); + return td->print_struct(td, struct_ptr, ilevel, cb, app_key); } asn_dec_rval_t KeyIdentity4_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - KeyIdentity4_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); + void **structure, const void *bufptr, size_t size, int tag_mode) +{ + KeyIdentity4_1_inherit_TYPE_descriptor(td); + return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); } asn_enc_rval_t KeyIdentity4_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - KeyIdentity4_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); + void *structure, int tag_mode, ber_tlv_tag_t tag, + asn_app_consume_bytes_f *cb, void *app_key) +{ + KeyIdentity4_1_inherit_TYPE_descriptor(td); + return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); } asn_dec_rval_t KeyIdentity4_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - KeyIdentity4_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); + void **structure, const char *opt_mname, const void *bufptr, size_t size) +{ + KeyIdentity4_1_inherit_TYPE_descriptor(td); + return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); } asn_enc_rval_t KeyIdentity4_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - KeyIdentity4_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) +{ + KeyIdentity4_1_inherit_TYPE_descriptor(td); + return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); } asn_dec_rval_t KeyIdentity4_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) { - KeyIdentity4_1_inherit_TYPE_descriptor(td); - return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data); + asn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) +{ + KeyIdentity4_1_inherit_TYPE_descriptor(td); + return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data); } asn_enc_rval_t KeyIdentity4_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, - void *structure, asn_per_outp_t *per_out) { - KeyIdentity4_1_inherit_TYPE_descriptor(td); - return td->uper_encoder(td, constraints, structure, per_out); + asn_per_constraints_t *constraints, + void *structure, asn_per_outp_t *per_out) +{ + KeyIdentity4_1_inherit_TYPE_descriptor(td); + return td->uper_encoder(td, constraints, structure, per_out); } static asn_per_constraints_t asn_PER_type_KeyIdentity4_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 128, 128 } /* (SIZE(128..128)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 128, 128} /* (SIZE(128..128)) */, + 0, 0 /* No PER value map */ }; static ber_tlv_tag_t asn_DEF_KeyIdentity4_tags_1[] = { - (ASN_TAG_CLASS_UNIVERSAL | (3 << 2)) -}; + (ASN_TAG_CLASS_UNIVERSAL | (3 << 2))}; asn_TYPE_descriptor_t asn_DEF_KeyIdentity4 = { - "KeyIdentity4", - "KeyIdentity4", - KeyIdentity4_free, - KeyIdentity4_print, - KeyIdentity4_constraint, - KeyIdentity4_decode_ber, - KeyIdentity4_encode_der, - KeyIdentity4_decode_xer, - KeyIdentity4_encode_xer, - KeyIdentity4_decode_uper, - KeyIdentity4_encode_uper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_KeyIdentity4_tags_1, - sizeof(asn_DEF_KeyIdentity4_tags_1) - /sizeof(asn_DEF_KeyIdentity4_tags_1[0]), /* 1 */ - asn_DEF_KeyIdentity4_tags_1, /* Same as above */ - sizeof(asn_DEF_KeyIdentity4_tags_1) - /sizeof(asn_DEF_KeyIdentity4_tags_1[0]), /* 1 */ - &asn_PER_type_KeyIdentity4_constr_1, - 0, 0, /* No members */ - 0 /* No specifics */ + "KeyIdentity4", + "KeyIdentity4", + KeyIdentity4_free, + KeyIdentity4_print, + KeyIdentity4_constraint, + KeyIdentity4_decode_ber, + KeyIdentity4_encode_der, + KeyIdentity4_decode_xer, + KeyIdentity4_encode_xer, + KeyIdentity4_decode_uper, + KeyIdentity4_encode_uper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_KeyIdentity4_tags_1, + sizeof(asn_DEF_KeyIdentity4_tags_1) / sizeof(asn_DEF_KeyIdentity4_tags_1[0]), /* 1 */ + asn_DEF_KeyIdentity4_tags_1, /* Same as above */ + sizeof(asn_DEF_KeyIdentity4_tags_1) / sizeof(asn_DEF_KeyIdentity4_tags_1[0]), /* 1 */ + &asn_PER_type_KeyIdentity4_constr_1, + 0, 0, /* No members */ + 0 /* No specifics */ }; - diff --git a/src/core/libs/supl/asn-supl/MAC.c b/src/core/libs/supl/asn-supl/MAC.c index 03ab5da2c..5592eaf53 100644 --- a/src/core/libs/supl/asn-supl/MAC.c +++ b/src/core/libs/supl/asn-supl/MAC.c @@ -6,35 +6,42 @@ #include "MAC.h" -int -MAC_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 64)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } +int MAC_constraint(asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 64) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } /* @@ -42,110 +49,113 @@ MAC_constraint(asn_TYPE_descriptor_t *td, const void *sptr, * so here we adjust the DEF accordingly. */ static void -MAC_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_BIT_STRING.free_struct; - td->print_struct = asn_DEF_BIT_STRING.print_struct; - td->ber_decoder = asn_DEF_BIT_STRING.ber_decoder; - td->der_encoder = asn_DEF_BIT_STRING.der_encoder; - td->xer_decoder = asn_DEF_BIT_STRING.xer_decoder; - td->xer_encoder = asn_DEF_BIT_STRING.xer_encoder; - td->uper_decoder = asn_DEF_BIT_STRING.uper_decoder; - td->uper_encoder = asn_DEF_BIT_STRING.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_BIT_STRING.per_constraints; - td->elements = asn_DEF_BIT_STRING.elements; - td->elements_count = asn_DEF_BIT_STRING.elements_count; - td->specifics = asn_DEF_BIT_STRING.specifics; +MAC_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) +{ + td->free_struct = asn_DEF_BIT_STRING.free_struct; + td->print_struct = asn_DEF_BIT_STRING.print_struct; + td->ber_decoder = asn_DEF_BIT_STRING.ber_decoder; + td->der_encoder = asn_DEF_BIT_STRING.der_encoder; + td->xer_decoder = asn_DEF_BIT_STRING.xer_decoder; + td->xer_encoder = asn_DEF_BIT_STRING.xer_encoder; + td->uper_decoder = asn_DEF_BIT_STRING.uper_decoder; + td->uper_encoder = asn_DEF_BIT_STRING.uper_encoder; + if (!td->per_constraints) + td->per_constraints = asn_DEF_BIT_STRING.per_constraints; + td->elements = asn_DEF_BIT_STRING.elements; + td->elements_count = asn_DEF_BIT_STRING.elements_count; + td->specifics = asn_DEF_BIT_STRING.specifics; } -void -MAC_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - MAC_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); +void MAC_free(asn_TYPE_descriptor_t *td, + void *struct_ptr, int contents_only) +{ + MAC_1_inherit_TYPE_descriptor(td); + td->free_struct(td, struct_ptr, contents_only); } -int -MAC_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - MAC_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); +int MAC_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, + int ilevel, asn_app_consume_bytes_f *cb, void *app_key) +{ + MAC_1_inherit_TYPE_descriptor(td); + return td->print_struct(td, struct_ptr, ilevel, cb, app_key); } asn_dec_rval_t MAC_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - MAC_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); + void **structure, const void *bufptr, size_t size, int tag_mode) +{ + MAC_1_inherit_TYPE_descriptor(td); + return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); } asn_enc_rval_t MAC_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - MAC_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); + void *structure, int tag_mode, ber_tlv_tag_t tag, + asn_app_consume_bytes_f *cb, void *app_key) +{ + MAC_1_inherit_TYPE_descriptor(td); + return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); } asn_dec_rval_t MAC_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - MAC_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); + void **structure, const char *opt_mname, const void *bufptr, size_t size) +{ + MAC_1_inherit_TYPE_descriptor(td); + return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); } asn_enc_rval_t MAC_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - MAC_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) +{ + MAC_1_inherit_TYPE_descriptor(td); + return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); } asn_dec_rval_t MAC_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) { - MAC_1_inherit_TYPE_descriptor(td); - return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data); + asn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) +{ + MAC_1_inherit_TYPE_descriptor(td); + return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data); } asn_enc_rval_t MAC_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, - void *structure, asn_per_outp_t *per_out) { - MAC_1_inherit_TYPE_descriptor(td); - return td->uper_encoder(td, constraints, structure, per_out); + asn_per_constraints_t *constraints, + void *structure, asn_per_outp_t *per_out) +{ + MAC_1_inherit_TYPE_descriptor(td); + return td->uper_encoder(td, constraints, structure, per_out); } static asn_per_constraints_t asn_PER_type_MAC_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 64, 64 } /* (SIZE(64..64)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 64, 64} /* (SIZE(64..64)) */, + 0, 0 /* No PER value map */ }; static ber_tlv_tag_t asn_DEF_MAC_tags_1[] = { - (ASN_TAG_CLASS_UNIVERSAL | (3 << 2)) -}; + (ASN_TAG_CLASS_UNIVERSAL | (3 << 2))}; asn_TYPE_descriptor_t asn_DEF_MAC = { - "MAC", - "MAC", - MAC_free, - MAC_print, - MAC_constraint, - MAC_decode_ber, - MAC_encode_der, - MAC_decode_xer, - MAC_encode_xer, - MAC_decode_uper, - MAC_encode_uper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_MAC_tags_1, - sizeof(asn_DEF_MAC_tags_1) - /sizeof(asn_DEF_MAC_tags_1[0]), /* 1 */ - asn_DEF_MAC_tags_1, /* Same as above */ - sizeof(asn_DEF_MAC_tags_1) - /sizeof(asn_DEF_MAC_tags_1[0]), /* 1 */ - &asn_PER_type_MAC_constr_1, - 0, 0, /* No members */ - 0 /* No specifics */ + "MAC", + "MAC", + MAC_free, + MAC_print, + MAC_constraint, + MAC_decode_ber, + MAC_encode_der, + MAC_decode_xer, + MAC_encode_xer, + MAC_decode_uper, + MAC_encode_uper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_MAC_tags_1, + sizeof(asn_DEF_MAC_tags_1) / sizeof(asn_DEF_MAC_tags_1[0]), /* 1 */ + asn_DEF_MAC_tags_1, /* Same as above */ + sizeof(asn_DEF_MAC_tags_1) / sizeof(asn_DEF_MAC_tags_1[0]), /* 1 */ + &asn_PER_type_MAC_constr_1, + 0, 0, /* No members */ + 0 /* No specifics */ }; - diff --git a/src/core/libs/supl/asn-supl/SETAuthKey.c b/src/core/libs/supl/asn-supl/SETAuthKey.c index 75b01ca3b..3069866a2 100644 --- a/src/core/libs/supl/asn-supl/SETAuthKey.c +++ b/src/core/libs/supl/asn-supl/SETAuthKey.c @@ -8,135 +8,148 @@ static int memb_shortKey_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 128)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 128) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_longKey_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 256)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 256) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static asn_per_constraints_t asn_PER_memb_shortKey_constr_2 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 128, 128 } /* (SIZE(128..128)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 128, 128} /* (SIZE(128..128)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_longKey_constr_3 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 256, 256 } /* (SIZE(256..256)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 256, 256} /* (SIZE(256..256)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_type_SETAuthKey_constr_1 = { - { APC_CONSTRAINED | APC_EXTENSIBLE, 1, 1, 0, 1 } /* (0..1,...) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - 0, 0 /* No PER value map */ + {APC_CONSTRAINED | APC_EXTENSIBLE, 1, 1, 0, 1} /* (0..1,...) */, + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + 0, 0 /* No PER value map */ }; static asn_TYPE_member_t asn_MBR_SETAuthKey_1[] = { - { ATF_NOFLAGS, 0, offsetof(struct SETAuthKey, choice.shortKey), - (ASN_TAG_CLASS_CONTEXT | (0 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_shortKey_constraint_1, - &asn_PER_memb_shortKey_constr_2, - 0, - "shortKey" - }, - { ATF_NOFLAGS, 0, offsetof(struct SETAuthKey, choice.longKey), - (ASN_TAG_CLASS_CONTEXT | (1 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_longKey_constraint_1, - &asn_PER_memb_longKey_constr_3, - 0, - "longKey" - }, + {ATF_NOFLAGS, 0, offsetof(struct SETAuthKey, choice.shortKey), + (ASN_TAG_CLASS_CONTEXT | (0 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_shortKey_constraint_1, + &asn_PER_memb_shortKey_constr_2, + 0, + "shortKey"}, + {ATF_NOFLAGS, 0, offsetof(struct SETAuthKey, choice.longKey), + (ASN_TAG_CLASS_CONTEXT | (1 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_longKey_constraint_1, + &asn_PER_memb_longKey_constr_3, + 0, + "longKey"}, }; static asn_TYPE_tag2member_t asn_MAP_SETAuthKey_tag2el_1[] = { - { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* shortKey at 17 */ - { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* longKey at 18 */ + {(ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0}, /* shortKey at 17 */ + {(ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0} /* longKey at 18 */ }; static asn_CHOICE_specifics_t asn_SPC_SETAuthKey_specs_1 = { - sizeof(struct SETAuthKey), - offsetof(struct SETAuthKey, _asn_ctx), - offsetof(struct SETAuthKey, present), - sizeof(((struct SETAuthKey *)0)->present), - asn_MAP_SETAuthKey_tag2el_1, - 2, /* Count of tags in the map */ - 0, - 2 /* Extensions start */ + sizeof(struct SETAuthKey), + offsetof(struct SETAuthKey, _asn_ctx), + offsetof(struct SETAuthKey, present), + sizeof(((struct SETAuthKey *)0)->present), + asn_MAP_SETAuthKey_tag2el_1, + 2, /* Count of tags in the map */ + 0, + 2 /* Extensions start */ }; asn_TYPE_descriptor_t asn_DEF_SETAuthKey = { - "SETAuthKey", - "SETAuthKey", - CHOICE_free, - CHOICE_print, - CHOICE_constraint, - CHOICE_decode_ber, - CHOICE_encode_der, - CHOICE_decode_xer, - CHOICE_encode_xer, - CHOICE_decode_uper, - CHOICE_encode_uper, - CHOICE_outmost_tag, - 0, /* No effective tags (pointer) */ - 0, /* No effective tags (count) */ - 0, /* No tags (pointer) */ - 0, /* No tags (count) */ - &asn_PER_type_SETAuthKey_constr_1, - asn_MBR_SETAuthKey_1, - 2, /* Elements count */ - &asn_SPC_SETAuthKey_specs_1 /* Additional specs */ + "SETAuthKey", + "SETAuthKey", + CHOICE_free, + CHOICE_print, + CHOICE_constraint, + CHOICE_decode_ber, + CHOICE_encode_der, + CHOICE_decode_xer, + CHOICE_encode_xer, + CHOICE_decode_uper, + CHOICE_encode_uper, + CHOICE_outmost_tag, + 0, /* No effective tags (pointer) */ + 0, /* No effective tags (count) */ + 0, /* No tags (pointer) */ + 0, /* No tags (count) */ + &asn_PER_type_SETAuthKey_constr_1, + asn_MBR_SETAuthKey_1, + 2, /* Elements count */ + &asn_SPC_SETAuthKey_specs_1 /* Additional specs */ }; - diff --git a/src/core/libs/supl/asn-supl/SETId.c b/src/core/libs/supl/asn-supl/SETId.c index 6da7efdf5..93a635e23 100644 --- a/src/core/libs/supl/asn-supl/SETId.c +++ b/src/core/libs/supl/asn-supl/SETId.c @@ -6,279 +6,301 @@ #include "SETId.h" -static int check_permitted_alphabet_6(const void *sptr) { - /* The underlying type is IA5String */ - const IA5String_t *st = (const IA5String_t *)sptr; - const uint8_t *ch = st->buf; - const uint8_t *end = ch + st->size; - - for(; ch < end; ch++) { - uint8_t cv = *ch; - if(!(cv <= 127)) return -1; - } - return 0; +static int check_permitted_alphabet_6(const void *sptr) +{ + /* The underlying type is IA5String */ + const IA5String_t *st = (const IA5String_t *)sptr; + const uint8_t *ch = st->buf; + const uint8_t *end = ch + st->size; + + for (; ch < end; ch++) + { + uint8_t cv = *ch; + if (!(cv <= 127)) return -1; + } + return 0; } static int memb_msisdn_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - size = st->size; - - if((size == 8)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + size = st->size; + + if (size == 8) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_mdn_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - size = st->size; - - if((size == 8)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + size = st->size; + + if (size == 8) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_min_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 34)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 34) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_imsi_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - size = st->size; - - if((size == 8)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + size = st->size; + + if (size == 8) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static int memb_nai_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const IA5String_t *st = (const IA5String_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - size = st->size; - - if((size >= 1 && size <= 1000) - && !check_permitted_alphabet_6(st)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const IA5String_t *st = (const IA5String_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + size = st->size; + + if ((size >= 1 && size <= 1000) && !check_permitted_alphabet_6(st)) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static asn_per_constraints_t asn_PER_memb_msisdn_constr_2 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 8, 8 } /* (SIZE(8..8)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 8, 8} /* (SIZE(8..8)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_mdn_constr_3 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 8, 8 } /* (SIZE(8..8)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 8, 8} /* (SIZE(8..8)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_min_constr_4 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 34, 34 } /* (SIZE(34..34)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 34, 34} /* (SIZE(34..34)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_imsi_constr_5 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 8, 8 } /* (SIZE(8..8)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 8, 8} /* (SIZE(8..8)) */, + 0, 0 /* No PER value map */ }; static asn_per_constraints_t asn_PER_memb_nai_constr_6 = { - { APC_CONSTRAINED, 7, 7, 0, 127 } /* (0..127) */, - { APC_CONSTRAINED, 10, 10, 1, 1000 } /* (SIZE(1..1000)) */, - 0, 0 /* No PER character map necessary */ + {APC_CONSTRAINED, 7, 7, 0, 127} /* (0..127) */, + {APC_CONSTRAINED, 10, 10, 1, 1000} /* (SIZE(1..1000)) */, + 0, 0 /* No PER character map necessary */ }; static asn_per_constraints_t asn_PER_type_SETId_constr_1 = { - { APC_CONSTRAINED | APC_EXTENSIBLE, 3, 3, 0, 5 } /* (0..5,...) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - 0, 0 /* No PER value map */ + {APC_CONSTRAINED | APC_EXTENSIBLE, 3, 3, 0, 5} /* (0..5,...) */, + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + 0, 0 /* No PER value map */ }; static asn_TYPE_member_t asn_MBR_SETId_1[] = { - { ATF_NOFLAGS, 0, offsetof(struct SETId, choice.msisdn), - (ASN_TAG_CLASS_CONTEXT | (0 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_OCTET_STRING, - memb_msisdn_constraint_1, - &asn_PER_memb_msisdn_constr_2, - 0, - "msisdn" - }, - { ATF_NOFLAGS, 0, offsetof(struct SETId, choice.mdn), - (ASN_TAG_CLASS_CONTEXT | (1 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_OCTET_STRING, - memb_mdn_constraint_1, - &asn_PER_memb_mdn_constr_3, - 0, - "mdn" - }, - { ATF_NOFLAGS, 0, offsetof(struct SETId, choice.min), - (ASN_TAG_CLASS_CONTEXT | (2 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_BIT_STRING, - memb_min_constraint_1, - &asn_PER_memb_min_constr_4, - 0, - "min" - }, - { ATF_NOFLAGS, 0, offsetof(struct SETId, choice.imsi), - (ASN_TAG_CLASS_CONTEXT | (3 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_OCTET_STRING, - memb_imsi_constraint_1, - &asn_PER_memb_imsi_constr_5, - 0, - "imsi" - }, - { ATF_NOFLAGS, 0, offsetof(struct SETId, choice.nai), - (ASN_TAG_CLASS_CONTEXT | (4 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_IA5String, - memb_nai_constraint_1, - &asn_PER_memb_nai_constr_6, - 0, - "nai" - }, - { ATF_NOFLAGS, 0, offsetof(struct SETId, choice.iPAddress), - (ASN_TAG_CLASS_CONTEXT | (5 << 2)), - +1, /* EXPLICIT tag at current level */ - &asn_DEF_IPAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* No PER visible constraints */ - 0, - "iPAddress" - }, + {ATF_NOFLAGS, 0, offsetof(struct SETId, choice.msisdn), + (ASN_TAG_CLASS_CONTEXT | (0 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_OCTET_STRING, + memb_msisdn_constraint_1, + &asn_PER_memb_msisdn_constr_2, + 0, + "msisdn"}, + {ATF_NOFLAGS, 0, offsetof(struct SETId, choice.mdn), + (ASN_TAG_CLASS_CONTEXT | (1 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_OCTET_STRING, + memb_mdn_constraint_1, + &asn_PER_memb_mdn_constr_3, + 0, + "mdn"}, + {ATF_NOFLAGS, 0, offsetof(struct SETId, choice.min), + (ASN_TAG_CLASS_CONTEXT | (2 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_BIT_STRING, + memb_min_constraint_1, + &asn_PER_memb_min_constr_4, + 0, + "min"}, + {ATF_NOFLAGS, 0, offsetof(struct SETId, choice.imsi), + (ASN_TAG_CLASS_CONTEXT | (3 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_OCTET_STRING, + memb_imsi_constraint_1, + &asn_PER_memb_imsi_constr_5, + 0, + "imsi"}, + {ATF_NOFLAGS, 0, offsetof(struct SETId, choice.nai), + (ASN_TAG_CLASS_CONTEXT | (4 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_IA5String, + memb_nai_constraint_1, + &asn_PER_memb_nai_constr_6, + 0, + "nai"}, + {ATF_NOFLAGS, 0, offsetof(struct SETId, choice.iPAddress), + (ASN_TAG_CLASS_CONTEXT | (5 << 2)), + +1, /* EXPLICIT tag at current level */ + &asn_DEF_IPAddress, + 0, /* Defer constraints checking to the member type */ + 0, /* No PER visible constraints */ + 0, + "iPAddress"}, }; static asn_TYPE_tag2member_t asn_MAP_SETId_tag2el_1[] = { - { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* msisdn at 22 */ - { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* mdn at 23 */ - { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* min at 24 */ - { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 }, /* imsi at 25 */ - { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 }, /* nai at 26 */ - { (ASN_TAG_CLASS_CONTEXT | (5 << 2)), 5, 0, 0 } /* iPAddress at 27 */ + {(ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0}, /* msisdn at 22 */ + {(ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0}, /* mdn at 23 */ + {(ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0}, /* min at 24 */ + {(ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0}, /* imsi at 25 */ + {(ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0}, /* nai at 26 */ + {(ASN_TAG_CLASS_CONTEXT | (5 << 2)), 5, 0, 0} /* iPAddress at 27 */ }; static asn_CHOICE_specifics_t asn_SPC_SETId_specs_1 = { - sizeof(struct SETId), - offsetof(struct SETId, _asn_ctx), - offsetof(struct SETId, present), - sizeof(((struct SETId *)0)->present), - asn_MAP_SETId_tag2el_1, - 6, /* Count of tags in the map */ - 0, - 6 /* Extensions start */ + sizeof(struct SETId), + offsetof(struct SETId, _asn_ctx), + offsetof(struct SETId, present), + sizeof(((struct SETId *)0)->present), + asn_MAP_SETId_tag2el_1, + 6, /* Count of tags in the map */ + 0, + 6 /* Extensions start */ }; asn_TYPE_descriptor_t asn_DEF_SETId = { - "SETId", - "SETId", - CHOICE_free, - CHOICE_print, - CHOICE_constraint, - CHOICE_decode_ber, - CHOICE_encode_der, - CHOICE_decode_xer, - CHOICE_encode_xer, - CHOICE_decode_uper, - CHOICE_encode_uper, - CHOICE_outmost_tag, - 0, /* No effective tags (pointer) */ - 0, /* No effective tags (count) */ - 0, /* No tags (pointer) */ - 0, /* No tags (count) */ - &asn_PER_type_SETId_constr_1, - asn_MBR_SETId_1, - 6, /* Elements count */ - &asn_SPC_SETId_specs_1 /* Additional specs */ + "SETId", + "SETId", + CHOICE_free, + CHOICE_print, + CHOICE_constraint, + CHOICE_decode_ber, + CHOICE_encode_der, + CHOICE_decode_xer, + CHOICE_encode_xer, + CHOICE_decode_uper, + CHOICE_encode_uper, + CHOICE_outmost_tag, + 0, /* No effective tags (pointer) */ + 0, /* No effective tags (count) */ + 0, /* No tags (pointer) */ + 0, /* No tags (count) */ + &asn_PER_type_SETId_constr_1, + asn_MBR_SETId_1, + 6, /* Elements count */ + &asn_SPC_SETId_specs_1 /* Additional specs */ }; - diff --git a/src/core/libs/supl/asn-supl/SlpSessionID.c b/src/core/libs/supl/asn-supl/SlpSessionID.c index 173724cd6..0e52d2d34 100644 --- a/src/core/libs/supl/asn-supl/SlpSessionID.c +++ b/src/core/libs/supl/asn-supl/SlpSessionID.c @@ -8,93 +8,92 @@ static int memb_sessionID_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - size = st->size; - - if((size == 4)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + size = st->size; + + if (size == 4) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } static asn_per_constraints_t asn_PER_memb_sessionID_constr_2 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 4, 4 } /* (SIZE(4..4)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 4, 4} /* (SIZE(4..4)) */, + 0, 0 /* No PER value map */ }; static asn_TYPE_member_t asn_MBR_SlpSessionID_1[] = { - { ATF_NOFLAGS, 0, offsetof(struct SlpSessionID, sessionID), - (ASN_TAG_CLASS_CONTEXT | (0 << 2)), - -1, /* IMPLICIT tag at current level */ - &asn_DEF_OCTET_STRING, - memb_sessionID_constraint_1, - &asn_PER_memb_sessionID_constr_2, - 0, - "sessionID" - }, - { ATF_NOFLAGS, 0, offsetof(struct SlpSessionID, slpId), - (ASN_TAG_CLASS_CONTEXT | (1 << 2)), - +1, /* EXPLICIT tag at current level */ - &asn_DEF_SLPAddress, - 0, /* Defer constraints checking to the member type */ - 0, /* No PER visible constraints */ - 0, - "slpId" - }, + {ATF_NOFLAGS, 0, offsetof(struct SlpSessionID, sessionID), + (ASN_TAG_CLASS_CONTEXT | (0 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_OCTET_STRING, + memb_sessionID_constraint_1, + &asn_PER_memb_sessionID_constr_2, + 0, + "sessionID"}, + {ATF_NOFLAGS, 0, offsetof(struct SlpSessionID, slpId), + (ASN_TAG_CLASS_CONTEXT | (1 << 2)), + +1, /* EXPLICIT tag at current level */ + &asn_DEF_SLPAddress, + 0, /* Defer constraints checking to the member type */ + 0, /* No PER visible constraints */ + 0, + "slpId"}, }; static ber_tlv_tag_t asn_DEF_SlpSessionID_tags_1[] = { - (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) -}; + (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))}; static asn_TYPE_tag2member_t asn_MAP_SlpSessionID_tag2el_1[] = { - { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* sessionID at 37 */ - { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* slpId at 38 */ + {(ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0}, /* sessionID at 37 */ + {(ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0} /* slpId at 38 */ }; static asn_SEQUENCE_specifics_t asn_SPC_SlpSessionID_specs_1 = { - sizeof(struct SlpSessionID), - offsetof(struct SlpSessionID, _asn_ctx), - asn_MAP_SlpSessionID_tag2el_1, - 2, /* Count of tags in the map */ - 0, 0, 0, /* Optional elements (not needed) */ - -1, /* Start extensions */ - -1 /* Stop extensions */ + sizeof(struct SlpSessionID), + offsetof(struct SlpSessionID, _asn_ctx), + asn_MAP_SlpSessionID_tag2el_1, + 2, /* Count of tags in the map */ + 0, 0, 0, /* Optional elements (not needed) */ + -1, /* Start extensions */ + -1 /* Stop extensions */ }; asn_TYPE_descriptor_t asn_DEF_SlpSessionID = { - "SlpSessionID", - "SlpSessionID", - SEQUENCE_free, - SEQUENCE_print, - SEQUENCE_constraint, - SEQUENCE_decode_ber, - SEQUENCE_encode_der, - SEQUENCE_decode_xer, - SEQUENCE_encode_xer, - SEQUENCE_decode_uper, - SEQUENCE_encode_uper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_SlpSessionID_tags_1, - sizeof(asn_DEF_SlpSessionID_tags_1) - /sizeof(asn_DEF_SlpSessionID_tags_1[0]), /* 1 */ - asn_DEF_SlpSessionID_tags_1, /* Same as above */ - sizeof(asn_DEF_SlpSessionID_tags_1) - /sizeof(asn_DEF_SlpSessionID_tags_1[0]), /* 1 */ - 0, /* No PER visible constraints */ - asn_MBR_SlpSessionID_1, - 2, /* Elements count */ - &asn_SPC_SlpSessionID_specs_1 /* Additional specs */ + "SlpSessionID", + "SlpSessionID", + SEQUENCE_free, + SEQUENCE_print, + SEQUENCE_constraint, + SEQUENCE_decode_ber, + SEQUENCE_encode_der, + SEQUENCE_decode_xer, + SEQUENCE_encode_xer, + SEQUENCE_decode_uper, + SEQUENCE_encode_uper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_SlpSessionID_tags_1, + sizeof(asn_DEF_SlpSessionID_tags_1) / sizeof(asn_DEF_SlpSessionID_tags_1[0]), /* 1 */ + asn_DEF_SlpSessionID_tags_1, /* Same as above */ + sizeof(asn_DEF_SlpSessionID_tags_1) / sizeof(asn_DEF_SlpSessionID_tags_1[0]), /* 1 */ + 0, /* No PER visible constraints */ + asn_MBR_SlpSessionID_1, + 2, /* Elements count */ + &asn_SPC_SlpSessionID_specs_1 /* Additional specs */ }; - diff --git a/src/core/libs/supl/asn-supl/Ver.c b/src/core/libs/supl/asn-supl/Ver.c index 664fb9517..5c99a89fc 100644 --- a/src/core/libs/supl/asn-supl/Ver.c +++ b/src/core/libs/supl/asn-supl/Ver.c @@ -6,35 +6,42 @@ #include "Ver.h" -int -Ver_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - size_t size; - - if(!sptr) { - _ASN_CTFAIL(app_key, td, sptr, - "%s: value not given (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } - - if(st->size > 0) { - /* Size in bits */ - size = 8 * st->size - (st->bits_unused & 0x07); - } else { - size = 0; - } - - if((size == 64)) { - /* Constraint check succeeded */ - return 0; - } else { - _ASN_CTFAIL(app_key, td, sptr, - "%s: constraint failed (%s:%d)", - td->name, __FILE__, __LINE__); - return -1; - } +int Ver_constraint(asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_constraint_failed_f *ctfailcb, void *app_key) +{ + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + size_t size; + + if (!sptr) + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + if (st->size > 0) + { + /* Size in bits */ + size = 8 * st->size - (st->bits_unused & 0x07); + } + else + { + size = 0; + } + + if (size == 64) + { + /* Constraint check succeeded */ + return 0; + } + else + { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } } /* @@ -42,110 +49,113 @@ Ver_constraint(asn_TYPE_descriptor_t *td, const void *sptr, * so here we adjust the DEF accordingly. */ static void -Ver_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) { - td->free_struct = asn_DEF_BIT_STRING.free_struct; - td->print_struct = asn_DEF_BIT_STRING.print_struct; - td->ber_decoder = asn_DEF_BIT_STRING.ber_decoder; - td->der_encoder = asn_DEF_BIT_STRING.der_encoder; - td->xer_decoder = asn_DEF_BIT_STRING.xer_decoder; - td->xer_encoder = asn_DEF_BIT_STRING.xer_encoder; - td->uper_decoder = asn_DEF_BIT_STRING.uper_decoder; - td->uper_encoder = asn_DEF_BIT_STRING.uper_encoder; - if(!td->per_constraints) - td->per_constraints = asn_DEF_BIT_STRING.per_constraints; - td->elements = asn_DEF_BIT_STRING.elements; - td->elements_count = asn_DEF_BIT_STRING.elements_count; - td->specifics = asn_DEF_BIT_STRING.specifics; +Ver_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) +{ + td->free_struct = asn_DEF_BIT_STRING.free_struct; + td->print_struct = asn_DEF_BIT_STRING.print_struct; + td->ber_decoder = asn_DEF_BIT_STRING.ber_decoder; + td->der_encoder = asn_DEF_BIT_STRING.der_encoder; + td->xer_decoder = asn_DEF_BIT_STRING.xer_decoder; + td->xer_encoder = asn_DEF_BIT_STRING.xer_encoder; + td->uper_decoder = asn_DEF_BIT_STRING.uper_decoder; + td->uper_encoder = asn_DEF_BIT_STRING.uper_encoder; + if (!td->per_constraints) + td->per_constraints = asn_DEF_BIT_STRING.per_constraints; + td->elements = asn_DEF_BIT_STRING.elements; + td->elements_count = asn_DEF_BIT_STRING.elements_count; + td->specifics = asn_DEF_BIT_STRING.specifics; } -void -Ver_free(asn_TYPE_descriptor_t *td, - void *struct_ptr, int contents_only) { - Ver_1_inherit_TYPE_descriptor(td); - td->free_struct(td, struct_ptr, contents_only); +void Ver_free(asn_TYPE_descriptor_t *td, + void *struct_ptr, int contents_only) +{ + Ver_1_inherit_TYPE_descriptor(td); + td->free_struct(td, struct_ptr, contents_only); } -int -Ver_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, - int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - Ver_1_inherit_TYPE_descriptor(td); - return td->print_struct(td, struct_ptr, ilevel, cb, app_key); +int Ver_print(asn_TYPE_descriptor_t *td, const void *struct_ptr, + int ilevel, asn_app_consume_bytes_f *cb, void *app_key) +{ + Ver_1_inherit_TYPE_descriptor(td); + return td->print_struct(td, struct_ptr, ilevel, cb, app_key); } asn_dec_rval_t Ver_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const void *bufptr, size_t size, int tag_mode) { - Ver_1_inherit_TYPE_descriptor(td); - return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); + void **structure, const void *bufptr, size_t size, int tag_mode) +{ + Ver_1_inherit_TYPE_descriptor(td); + return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode); } asn_enc_rval_t Ver_encode_der(asn_TYPE_descriptor_t *td, - void *structure, int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - Ver_1_inherit_TYPE_descriptor(td); - return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); + void *structure, int tag_mode, ber_tlv_tag_t tag, + asn_app_consume_bytes_f *cb, void *app_key) +{ + Ver_1_inherit_TYPE_descriptor(td); + return td->der_encoder(td, structure, tag_mode, tag, cb, app_key); } asn_dec_rval_t Ver_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **structure, const char *opt_mname, const void *bufptr, size_t size) { - Ver_1_inherit_TYPE_descriptor(td); - return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); + void **structure, const char *opt_mname, const void *bufptr, size_t size) +{ + Ver_1_inherit_TYPE_descriptor(td); + return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size); } asn_enc_rval_t Ver_encode_xer(asn_TYPE_descriptor_t *td, void *structure, - int ilevel, enum xer_encoder_flags_e flags, - asn_app_consume_bytes_f *cb, void *app_key) { - Ver_1_inherit_TYPE_descriptor(td); - return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); + int ilevel, enum xer_encoder_flags_e flags, + asn_app_consume_bytes_f *cb, void *app_key) +{ + Ver_1_inherit_TYPE_descriptor(td); + return td->xer_encoder(td, structure, ilevel, flags, cb, app_key); } asn_dec_rval_t Ver_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) { - Ver_1_inherit_TYPE_descriptor(td); - return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data); + asn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) +{ + Ver_1_inherit_TYPE_descriptor(td); + return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data); } asn_enc_rval_t Ver_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, - void *structure, asn_per_outp_t *per_out) { - Ver_1_inherit_TYPE_descriptor(td); - return td->uper_encoder(td, constraints, structure, per_out); + asn_per_constraints_t *constraints, + void *structure, asn_per_outp_t *per_out) +{ + Ver_1_inherit_TYPE_descriptor(td); + return td->uper_encoder(td, constraints, structure, per_out); } static asn_per_constraints_t asn_PER_type_Ver_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 0, 0, 64, 64 } /* (SIZE(64..64)) */, - 0, 0 /* No PER value map */ + {APC_UNCONSTRAINED, -1, -1, 0, 0}, + {APC_CONSTRAINED, 0, 0, 64, 64} /* (SIZE(64..64)) */, + 0, 0 /* No PER value map */ }; static ber_tlv_tag_t asn_DEF_Ver_tags_1[] = { - (ASN_TAG_CLASS_UNIVERSAL | (3 << 2)) -}; + (ASN_TAG_CLASS_UNIVERSAL | (3 << 2))}; asn_TYPE_descriptor_t asn_DEF_Ver = { - "Ver", - "Ver", - Ver_free, - Ver_print, - Ver_constraint, - Ver_decode_ber, - Ver_encode_der, - Ver_decode_xer, - Ver_encode_xer, - Ver_decode_uper, - Ver_encode_uper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_Ver_tags_1, - sizeof(asn_DEF_Ver_tags_1) - /sizeof(asn_DEF_Ver_tags_1[0]), /* 1 */ - asn_DEF_Ver_tags_1, /* Same as above */ - sizeof(asn_DEF_Ver_tags_1) - /sizeof(asn_DEF_Ver_tags_1[0]), /* 1 */ - &asn_PER_type_Ver_constr_1, - 0, 0, /* No members */ - 0 /* No specifics */ + "Ver", + "Ver", + Ver_free, + Ver_print, + Ver_constraint, + Ver_decode_ber, + Ver_encode_der, + Ver_decode_xer, + Ver_encode_xer, + Ver_decode_uper, + Ver_encode_uper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_Ver_tags_1, + sizeof(asn_DEF_Ver_tags_1) / sizeof(asn_DEF_Ver_tags_1[0]), /* 1 */ + asn_DEF_Ver_tags_1, /* Same as above */ + sizeof(asn_DEF_Ver_tags_1) / sizeof(asn_DEF_Ver_tags_1[0]), /* 1 */ + &asn_PER_type_Ver_constr_1, + 0, 0, /* No members */ + 0 /* No specifics */ }; - diff --git a/src/core/libs/supl/asn-supl/per_opentype.c b/src/core/libs/supl/asn-supl/per_opentype.c index c749c8c6c..c81caed44 100644 --- a/src/core/libs/supl/asn-supl/per_opentype.c +++ b/src/core/libs/supl/asn-supl/per_opentype.c @@ -7,11 +7,12 @@ #include #include -typedef struct uper_ugot_key { - asn_per_data_t oldpd; /* Old per data source */ - size_t unclaimed; - size_t ot_moved; /* Number of bits moved by OT processing */ - int repeat; +typedef struct uper_ugot_key +{ + asn_per_data_t oldpd; /* Old per data source */ + size_t unclaimed; + size_t ot_moved; /* Number of bits moved by OT processing */ + int repeat; } uper_ugot_key; static int uper_ugot_refill(asn_per_data_t *pd); @@ -24,243 +25,272 @@ int asn_debug_indent; * Encode an "open type field". * #10.1, #10.2 */ -int -uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - void *buf; - void *bptr; - ssize_t size; - size_t toGo; +int uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) +{ + void *buf; + void *bptr; + ssize_t size; + size_t toGo; - ASN_DEBUG("Open type put %s ...", td->name); + ASN_DEBUG("Open type put %s ...", td->name); - size = uper_encode_to_new_buffer(td, constraints, sptr, &buf); - if(size <= 0) return -1; + size = uper_encode_to_new_buffer(td, constraints, sptr, &buf); + if (size <= 0) return -1; - for(bptr = buf, toGo = size; toGo;) { - ssize_t maySave = uper_put_length(po, toGo); - if(maySave < 0) break; - if(per_put_many_bits(po, bptr, maySave * 8)) break; - bptr = (char *)bptr + maySave; - toGo -= maySave; - } + for (bptr = buf, toGo = size; toGo;) + { + ssize_t maySave = uper_put_length(po, toGo); + if (maySave < 0) break; + if (per_put_many_bits(po, bptr, maySave * 8)) break; + bptr = (char *)bptr + maySave; + toGo -= maySave; + } - FREEMEM(buf); - if(toGo) return -1; + FREEMEM(buf); + if (toGo) return -1; - ASN_DEBUG("Open type put %s of length %d + overhead (1byte?)", - td->name, size); + ASN_DEBUG("Open type put %s of length %d + overhead (1byte?)", + td->name, size); - return 0; + return 0; } static asn_dec_rval_t uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_dec_rval_t rv; - ssize_t chunk_bytes; - int repeat; - uint8_t *buf = 0; - size_t bufLen = 0; - size_t bufSize = 0; - asn_per_data_t spd; - size_t padding; + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) +{ + asn_dec_rval_t rv; + ssize_t chunk_bytes; + int repeat; + uint8_t *buf = 0; + size_t bufLen = 0; + size_t bufSize = 0; + asn_per_data_t spd; + size_t padding; - _ASN_STACK_OVERFLOW_CHECK(ctx); + _ASN_STACK_OVERFLOW_CHECK(ctx); - ASN_DEBUG("Getting open type %s...", td->name); + ASN_DEBUG("Getting open type %s...", td->name); - do { - chunk_bytes = uper_get_length(pd, -1, &repeat); - if(chunk_bytes < 0) { - FREEMEM(buf); - _ASN_DECODE_STARVED; - } - if(bufLen + chunk_bytes > bufSize) { - void *ptr; - bufSize = chunk_bytes + (bufSize << 2); - ptr = REALLOC(buf, bufSize); - if(!ptr) { - FREEMEM(buf); - _ASN_DECODE_FAILED; - } - buf = ptr; - } - if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) { - FREEMEM(buf); - _ASN_DECODE_STARVED; - } - bufLen += chunk_bytes; - } while(repeat); + do + { + chunk_bytes = uper_get_length(pd, -1, &repeat); + if (chunk_bytes < 0) + { + FREEMEM(buf); + _ASN_DECODE_STARVED; + } + if (bufLen + chunk_bytes > bufSize) + { + void *ptr; + bufSize = chunk_bytes + (bufSize << 2); + ptr = REALLOC(buf, bufSize); + if (!ptr) + { + FREEMEM(buf); + _ASN_DECODE_FAILED; + } + buf = ptr; + } + if (per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) + { + FREEMEM(buf); + _ASN_DECODE_STARVED; + } + bufLen += chunk_bytes; + } + while (repeat); - ASN_DEBUG("Getting open type %s encoded in %d bytes", td->name, - bufLen); + ASN_DEBUG("Getting open type %s encoded in %d bytes", td->name, + bufLen); - memset(&spd, 0, sizeof(spd)); - spd.buffer = buf; - spd.nbits = bufLen << 3; + memset(&spd, 0, sizeof(spd)); + spd.buffer = buf; + spd.nbits = bufLen << 3; - asn_debug_indent += 4; - rv = td->uper_decoder(ctx, td, constraints, sptr, &spd); - asn_debug_indent -= 4; + asn_debug_indent += 4; + rv = td->uper_decoder(ctx, td, constraints, sptr, &spd); + asn_debug_indent -= 4; - if(rv.code == RC_OK) { - /* Check padding validity */ - padding = spd.nbits - spd.nboff; - if(padding < 8 && per_get_few_bits(&spd, padding) == 0) { - /* Everything is cool */ - FREEMEM(buf); - return rv; - } - FREEMEM(buf); - if(padding >= 8) { - ASN_DEBUG("Too large padding %d in open type", padding); - _ASN_DECODE_FAILED; - } else { - ASN_DEBUG("Non-zero padding"); - _ASN_DECODE_FAILED; - } - } else { - FREEMEM(buf); - /* rv.code could be RC_WMORE, nonsense in this context */ - rv.code = RC_FAIL; /* Noone would give us more */ - } + if (rv.code == RC_OK) + { + /* Check padding validity */ + padding = spd.nbits - spd.nboff; + if (padding < 8 && per_get_few_bits(&spd, padding) == 0) + { + /* Everything is cool */ + FREEMEM(buf); + return rv; + } + FREEMEM(buf); + if (padding >= 8) + { + ASN_DEBUG("Too large padding %d in open type", padding); + _ASN_DECODE_FAILED; + } + else + { + ASN_DEBUG("Non-zero padding"); + _ASN_DECODE_FAILED; + } + } + else + { + FREEMEM(buf); + /* rv.code could be RC_WMORE, nonsense in this context */ + rv.code = RC_FAIL; /* Noone would give us more */ + } - return rv; + return rv; } static asn_dec_rval_t GCC_NOTUSED uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - uper_ugot_key arg; - asn_dec_rval_t rv; - ssize_t padding; + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) +{ + uper_ugot_key arg; + asn_dec_rval_t rv; + ssize_t padding; - _ASN_STACK_OVERFLOW_CHECK(ctx); + _ASN_STACK_OVERFLOW_CHECK(ctx); - ASN_DEBUG("Getting open type %s from %s", td->name, - per_data_string(pd)); - arg.oldpd = *pd; - arg.unclaimed = 0; - arg.ot_moved = 0; - arg.repeat = 1; - pd->refill = uper_ugot_refill; - pd->refill_key = &arg; - pd->nbits = pd->nboff; /* 0 good bits at this point, will refill */ - pd->moved = 0; /* This now counts the open type size in bits */ + ASN_DEBUG("Getting open type %s from %s", td->name, + per_data_string(pd)); + arg.oldpd = *pd; + arg.unclaimed = 0; + arg.ot_moved = 0; + arg.repeat = 1; + pd->refill = uper_ugot_refill; + pd->refill_key = &arg; + pd->nbits = pd->nboff; /* 0 good bits at this point, will refill */ + pd->moved = 0; /* This now counts the open type size in bits */ - asn_debug_indent += 4; - rv = td->uper_decoder(ctx, td, constraints, sptr, pd); - asn_debug_indent -= 4; + asn_debug_indent += 4; + rv = td->uper_decoder(ctx, td, constraints, sptr, pd); + asn_debug_indent -= 4; -#define UPDRESTOREPD do { \ - /* buffer and nboff are valid, preserve them. */ \ - pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved); \ - pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved); \ - pd->refill = arg.oldpd.refill; \ - pd->refill_key = arg.oldpd.refill_key; \ - } while(0) +#define UPDRESTOREPD \ + do \ + { \ + /* buffer and nboff are valid, preserve them. */ \ + pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved); \ + pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved); \ + pd->refill = arg.oldpd.refill; \ + pd->refill_key = arg.oldpd.refill_key; \ + } \ + while (0) - if(rv.code != RC_OK) { - UPDRESTOREPD; - return rv; - } + if (rv.code != RC_OK) + { + UPDRESTOREPD; + return rv; + } - ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d" - , td->name, - per_data_string(pd), - per_data_string(&arg.oldpd), - arg.unclaimed, arg.repeat); + ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d", td->name, + per_data_string(pd), + per_data_string(&arg.oldpd), + arg.unclaimed, arg.repeat); - padding = pd->moved % 8; - if(padding) { - int32_t pvalue; - if(padding > 7) { - ASN_DEBUG("Too large padding %d in open type", - padding); - rv.code = RC_FAIL; - UPDRESTOREPD; - return rv; - } - padding = 8 - padding; - ASN_DEBUG("Getting padding of %d bits", padding); - pvalue = per_get_few_bits(pd, padding); - switch(pvalue) { - case -1: - ASN_DEBUG("Padding skip failed"); - UPDRESTOREPD; - _ASN_DECODE_STARVED; - case 0: break; - default: - ASN_DEBUG("Non-blank padding (%d bits 0x%02x)", - padding, (int)pvalue); - UPDRESTOREPD; - _ASN_DECODE_FAILED; - } - } - if(pd->nboff != pd->nbits) { - ASN_DEBUG("Open type %s overhead pd%s old%s", td->name, - per_data_string(pd), per_data_string(&arg.oldpd)); - if(1) { - UPDRESTOREPD; - _ASN_DECODE_FAILED; - } else { - arg.unclaimed += pd->nbits - pd->nboff; - } - } + padding = pd->moved % 8; + if (padding) + { + int32_t pvalue; + if (padding > 7) + { + ASN_DEBUG("Too large padding %d in open type", + padding); + rv.code = RC_FAIL; + UPDRESTOREPD; + return rv; + } + padding = 8 - padding; + ASN_DEBUG("Getting padding of %d bits", padding); + pvalue = per_get_few_bits(pd, padding); + switch (pvalue) + { + case -1: + ASN_DEBUG("Padding skip failed"); + UPDRESTOREPD; + _ASN_DECODE_STARVED; + case 0: + break; + default: + ASN_DEBUG("Non-blank padding (%d bits 0x%02x)", + padding, (int)pvalue); + UPDRESTOREPD; + _ASN_DECODE_FAILED; + } + } + if (pd->nboff != pd->nbits) + { + ASN_DEBUG("Open type %s overhead pd%s old%s", td->name, + per_data_string(pd), per_data_string(&arg.oldpd)); + if (1) + { + UPDRESTOREPD; + _ASN_DECODE_FAILED; + } + else + { + arg.unclaimed += pd->nbits - pd->nboff; + } + } - /* Adjust pd back so it points to original data */ - UPDRESTOREPD; + /* Adjust pd back so it points to original data */ + UPDRESTOREPD; - /* Skip data not consumed by the decoder */ - if(arg.unclaimed) ASN_DEBUG("Getting unclaimed %d", arg.unclaimed); - if(arg.unclaimed) { - switch(per_skip_bits(pd, arg.unclaimed)) { - case -1: - ASN_DEBUG("Claim of %d failed", arg.unclaimed); - _ASN_DECODE_STARVED; - case 0: - ASN_DEBUG("Got claim of %d", arg.unclaimed); - break; - default: - /* Padding must be blank */ - ASN_DEBUG("Non-blank unconsumed padding"); - _ASN_DECODE_FAILED; - } - arg.unclaimed = 0; - } + /* Skip data not consumed by the decoder */ + if (arg.unclaimed) ASN_DEBUG("Getting unclaimed %d", arg.unclaimed); + if (arg.unclaimed) + { + switch (per_skip_bits(pd, arg.unclaimed)) + { + case -1: + ASN_DEBUG("Claim of %d failed", arg.unclaimed); + _ASN_DECODE_STARVED; + case 0: + ASN_DEBUG("Got claim of %d", arg.unclaimed); + break; + default: + /* Padding must be blank */ + ASN_DEBUG("Non-blank unconsumed padding"); + _ASN_DECODE_FAILED; + } + arg.unclaimed = 0; + } - if(arg.repeat) { - ASN_DEBUG("Not consumed the whole thing"); - rv.code = RC_FAIL; - return rv; - } + if (arg.repeat) + { + ASN_DEBUG("Not consumed the whole thing"); + rv.code = RC_FAIL; + return rv; + } - return rv; + return rv; } asn_dec_rval_t uper_open_type_get(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - - return uper_open_type_get_simple(ctx, td, constraints, - sptr, pd); - + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) +{ + return uper_open_type_get_simple(ctx, td, constraints, + sptr, pd); } -int -uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) { - asn_TYPE_descriptor_t s_td; - asn_dec_rval_t rv; +int uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) +{ + asn_TYPE_descriptor_t s_td; + asn_dec_rval_t rv; - s_td.name = ""; - s_td.uper_decoder = uper_sot_suck; + s_td.name = ""; + s_td.uper_decoder = uper_sot_suck; - rv = uper_open_type_get(ctx, &s_td, 0, 0, pd); - if(rv.code != RC_OK) - return -1; - else - return 0; + rv = uper_open_type_get(ctx, &s_td, 0, 0, pd); + if (rv.code != RC_OK) + return -1; + else + return 0; } /* @@ -269,105 +299,122 @@ uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) { static asn_dec_rval_t uper_sot_suck(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - asn_dec_rval_t rv; + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) +{ + asn_dec_rval_t rv; - (void)ctx; - (void)td; - (void)constraints; - (void)sptr; + (void)ctx; + (void)td; + (void)constraints; + (void)sptr; - while(per_get_few_bits(pd, 24) >= 0); + while (per_get_few_bits(pd, 24) >= 0) + ; - rv.code = RC_OK; - rv.consumed = pd->moved; + rv.code = RC_OK; + rv.consumed = pd->moved; - return rv; + return rv; } static int -uper_ugot_refill(asn_per_data_t *pd) { - uper_ugot_key *arg = pd->refill_key; - ssize_t next_chunk_bytes, next_chunk_bits; - ssize_t avail; +uper_ugot_refill(asn_per_data_t *pd) +{ + uper_ugot_key *arg = pd->refill_key; + ssize_t next_chunk_bytes, next_chunk_bits; + ssize_t avail; - asn_per_data_t *oldpd = &arg->oldpd; + asn_per_data_t *oldpd = &arg->oldpd; - ASN_DEBUG("REFILLING pd->moved=%d, oldpd->moved=%d", - pd->moved, oldpd->moved); + ASN_DEBUG("REFILLING pd->moved=%d, oldpd->moved=%d", + pd->moved, oldpd->moved); - /* Advance our position to where pd is */ - oldpd->buffer = pd->buffer; - oldpd->nboff = pd->nboff; - oldpd->nbits -= pd->moved - arg->ot_moved; - oldpd->moved += pd->moved - arg->ot_moved; - arg->ot_moved = pd->moved; + /* Advance our position to where pd is */ + oldpd->buffer = pd->buffer; + oldpd->nboff = pd->nboff; + oldpd->nbits -= pd->moved - arg->ot_moved; + oldpd->moved += pd->moved - arg->ot_moved; + arg->ot_moved = pd->moved; - if(arg->unclaimed) { - /* Refill the container */ - if(per_get_few_bits(oldpd, 1)) - return -1; - if(oldpd->nboff == 0) { - assert(0); - return -1; - } - pd->buffer = oldpd->buffer; - pd->nboff = oldpd->nboff - 1; - pd->nbits = oldpd->nbits; - ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%d)", pd->moved); - return 0; - } + if (arg->unclaimed) + { + /* Refill the container */ + if (per_get_few_bits(oldpd, 1)) + return -1; + if (oldpd->nboff == 0) + { + assert(0); + return -1; + } + pd->buffer = oldpd->buffer; + pd->nboff = oldpd->nboff - 1; + pd->nbits = oldpd->nbits; + ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%d)", pd->moved); + return 0; + } - if(!arg->repeat) { - ASN_DEBUG("Want more but refill doesn't have it"); - return -1; - } + if (!arg->repeat) + { + ASN_DEBUG("Want more but refill doesn't have it"); + return -1; + } - next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat); - ASN_DEBUG("Open type LENGTH %d bytes at off %d, repeat %d", - next_chunk_bytes, oldpd->moved, arg->repeat); - if(next_chunk_bytes < 0) return -1; - if(next_chunk_bytes == 0) { - pd->refill = 0; /* No more refills, naturally */ - assert(!arg->repeat); /* Implementation guarantee */ - } - next_chunk_bits = next_chunk_bytes << 3; - avail = oldpd->nbits - oldpd->nboff; - if(avail >= next_chunk_bits) { - pd->nbits = oldpd->nboff + next_chunk_bits; - arg->unclaimed = 0; - ASN_DEBUG("!+Parent frame %d bits, alloting %d [%d..%d] (%d)", - next_chunk_bits, oldpd->moved, - oldpd->nboff, oldpd->nbits, - oldpd->nbits - oldpd->nboff); - } else { - pd->nbits = oldpd->nbits; - arg->unclaimed = next_chunk_bits - avail; - ASN_DEBUG("!-Parent frame %d, require %d, will claim %d", avail, next_chunk_bits, arg->unclaimed); - } - pd->buffer = oldpd->buffer; - pd->nboff = oldpd->nboff; - ASN_DEBUG("Refilled pd%s old%s", - per_data_string(pd), per_data_string(oldpd)); - return 0; + next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat); + ASN_DEBUG("Open type LENGTH %d bytes at off %d, repeat %d", + next_chunk_bytes, oldpd->moved, arg->repeat); + if (next_chunk_bytes < 0) return -1; + if (next_chunk_bytes == 0) + { + pd->refill = 0; /* No more refills, naturally */ + assert(!arg->repeat); /* Implementation guarantee */ + } + next_chunk_bits = next_chunk_bytes << 3; + avail = oldpd->nbits - oldpd->nboff; + if (avail >= next_chunk_bits) + { + pd->nbits = oldpd->nboff + next_chunk_bits; + arg->unclaimed = 0; + ASN_DEBUG("!+Parent frame %d bits, alloting %d [%d..%d] (%d)", + next_chunk_bits, oldpd->moved, + oldpd->nboff, oldpd->nbits, + oldpd->nbits - oldpd->nboff); + } + else + { + pd->nbits = oldpd->nbits; + arg->unclaimed = next_chunk_bits - avail; + ASN_DEBUG("!-Parent frame %d, require %d, will claim %d", avail, next_chunk_bits, arg->unclaimed); + } + pd->buffer = oldpd->buffer; + pd->nboff = oldpd->nboff; + ASN_DEBUG("Refilled pd%s old%s", + per_data_string(pd), per_data_string(oldpd)); + return 0; } static int -per_skip_bits(asn_per_data_t *pd, int skip_nbits) { - int hasNonZeroBits = 0; - while(skip_nbits > 0) { - int skip; - if(skip_nbits < skip) - skip = skip_nbits; - else - skip = 24; - skip_nbits -= skip; +per_skip_bits(asn_per_data_t *pd, int skip_nbits) +{ + int hasNonZeroBits = 0; + while (skip_nbits > 0) + { + int skip = 0; + if (skip_nbits < skip) + skip = skip_nbits; + else + skip = 24; + skip_nbits -= skip; - switch(per_get_few_bits(pd, skip)) { - case -1: return -1; /* Starving */ - case 0: continue; /* Skipped empty space */ - default: hasNonZeroBits = 1; continue; - } - } - return hasNonZeroBits; + switch (per_get_few_bits(pd, skip)) + { + case -1: + return -1; /* Starving */ + case 0: + continue; /* Skipped empty space */ + default: + hasNonZeroBits = 1; + continue; + } + } + return hasNonZeroBits; } diff --git a/src/core/monitor/CMakeLists.txt b/src/core/monitor/CMakeLists.txt index a6bc9c2f3..54ee2a589 100644 --- a/src/core/monitor/CMakeLists.txt +++ b/src/core/monitor/CMakeLists.txt @@ -17,22 +17,35 @@ # -set(CORE_MONITOR_LIBS_SOURCES - gnss_synchro_monitor.cc - gnss_synchro_udp_sink.cc +set(CORE_MONITOR_LIBS_SOURCES + gnss_synchro_monitor.cc + gnss_synchro_udp_sink.cc ) - + +set(CORE_MONITOR_LIBS_HEADERS + gnss_synchro_monitor.h + gnss_synchro_udp_sink.h +) + include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src/core/system_parameters ${GLOG_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ) -file(GLOB CORE_MONITOR_LIBS_HEADERS "*.h") list(SORT CORE_MONITOR_LIBS_HEADERS) -add_library(core_monitor_lib ${CORE_MONITOR_LIBS_SOURCES} ${CORE_MONITOR_LIBS_HEADERS}) +list(SORT CORE_MONITOR_LIBS_SOURCES) + +add_library(core_monitor_lib + ${CORE_MONITOR_LIBS_SOURCES} + ${CORE_MONITOR_LIBS_HEADERS} +) + source_group(Headers FILES ${CORE_MONITOR_LIBS_HEADERS}) -target_link_libraries(core_monitor_lib ${Boost_LIBRARIES}) + +target_link_libraries(core_monitor_lib ${Boost_LIBRARIES}) + add_dependencies(core_monitor_lib glog-${glog_RELEASE}) diff --git a/src/core/monitor/gnss_synchro_monitor.cc b/src/core/monitor/gnss_synchro_monitor.cc index bde09ef69..d788b52b0 100644 --- a/src/core/monitor/gnss_synchro_monitor.cc +++ b/src/core/monitor/gnss_synchro_monitor.cc @@ -1,6 +1,9 @@ /*! * \file gnss_synchro_monitor.cc - * \brief Interface of a Position Velocity and Time computation block + * \brief Implementation of a receiver monitoring block which allows sending + * a data stream with the receiver internal parameters (Gnss_Synchro objects) + * to local or remote clients over UDP. + * * \author Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com * * ------------------------------------------------------------------------- @@ -61,6 +64,8 @@ gnss_synchro_monitor::gnss_synchro_monitor(unsigned int n_channels, d_nchannels = n_channels; udp_sink_ptr = std::unique_ptr(new Gnss_Synchro_Udp_Sink(udp_addresses, udp_port)); + + count = 0; } @@ -75,17 +80,16 @@ int gnss_synchro_monitor::work(int noutput_items, gr_vector_const_void_star& inp const Gnss_Synchro** in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer for (int epoch = 0; epoch < noutput_items; epoch++) { - // ############ 1. READ PSEUDORANGES #### - for (unsigned int i = 0; i < d_nchannels; i++) + count++; + if (count >= d_output_rate_ms) { - //if (in[i][epoch].Flag_valid_pseudorange) - // { - // } - //todo: send the gnss_synchro objects - - std::vector stocks; - stocks.push_back(in[i][epoch]); - udp_sink_ptr->write_gnss_synchro(stocks); + for (unsigned int i = 0; i < d_nchannels; i++) + { + std::vector stocks; + stocks.push_back(in[i][epoch]); + udp_sink_ptr->write_gnss_synchro(stocks); + } + count = 0; } } return noutput_items; diff --git a/src/core/monitor/gnss_synchro_monitor.h b/src/core/monitor/gnss_synchro_monitor.h index 36b6f1e3a..9547bf12d 100644 --- a/src/core/monitor/gnss_synchro_monitor.h +++ b/src/core/monitor/gnss_synchro_monitor.h @@ -1,6 +1,9 @@ /*! * \file gnss_synchro_monitor.h - * \brief Interface of a Position Velocity and Time computation block + * \brief Interface of a receiver monitoring block which allows sending + * a data stream with the receiver internal parameters (Gnss_Synchro objects) + * to local or remote clients over UDP. + * * \author Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com * * ------------------------------------------------------------------------- @@ -65,6 +68,8 @@ private: std::unique_ptr udp_sink_ptr; + int count; + public: gnss_synchro_monitor(unsigned int nchannels, diff --git a/src/core/receiver/CMakeLists.txt b/src/core/receiver/CMakeLists.txt index 46a13614e..239e8cf00 100644 --- a/src/core/receiver/CMakeLists.txt +++ b/src/core/receiver/CMakeLists.txt @@ -18,166 +18,207 @@ set(GNSS_RECEIVER_SOURCES - control_thread.cc - control_message_factory.cc - file_configuration.cc - gnss_block_factory.cc - gnss_flowgraph.cc - in_memory_configuration.cc + control_thread.cc + control_message_factory.cc + file_configuration.cc + gnss_block_factory.cc + gnss_flowgraph.cc + in_memory_configuration.cc + tcp_cmd_interface.cc ) +set(GNSS_RECEIVER_HEADERS + control_thread.h + control_message_factory.h + file_configuration.h + gnss_block_factory.h + gnss_flowgraph.h + in_memory_configuration.h + tcp_cmd_interface.h + concurrent_map.h + concurrent_queue.h + control_message.h +) if(PC_GNURADIO_RUNTIME_VERSION VERSION_GREATER 3.7.3) - add_definitions(-DMODERN_GNURADIO=1) -endif(PC_GNURADIO_RUNTIME_VERSION VERSION_GREATER 3.7.3) + add_definitions(-DMODERN_GNURADIO=1) +endif() if(ENABLE_CUDA) - add_definitions(-DCUDA_GPU_ACCEL=1) - set(OPT_RECEIVER_INCLUDE_DIRS ${OPT_RECEIVER_INCLUDE_DIRS} ${CUDA_INCLUDE_DIRS}) -endif(ENABLE_CUDA) + add_definitions(-DCUDA_GPU_ACCEL=1) + set(OPT_RECEIVER_INCLUDE_DIRS + ${OPT_RECEIVER_INCLUDE_DIRS} ${CUDA_INCLUDE_DIRS} + ) +endif() if(ENABLE_FPGA) - add_definitions(-DENABLE_FPGA=1) -endif(ENABLE_FPGA) + add_definitions(-DENABLE_FPGA=1) +endif() if(ENABLE_RAW_UDP) add_definitions(-DRAW_UDP=1) -endif(ENABLE_RAW_UDP) +endif() if(Boost_VERSION LESS 105000) - add_definitions(-DOLD_BOOST=1) -endif(Boost_VERSION LESS 105000) + add_definitions(-DOLD_BOOST=1) +endif() if(OPENSSL_FOUND) - add_definitions( -DUSE_OPENSSL_FALLBACK=1 ) -endif(OPENSSL_FOUND) + add_definitions(-DUSE_OPENSSL_FALLBACK=1) +endif() if(ENABLE_GN3S) add_definitions(-DGN3S_DRIVER=1) -endif(ENABLE_GN3S) +endif() if(ENABLE_ARRAY) add_definitions(-DRAW_ARRAY_DRIVER=1) -endif(ENABLE_ARRAY) +endif() if(ENABLE_FLEXIBAND) add_definitions(-DFLEXIBAND_DRIVER=1) -endif(ENABLE_FLEXIBAND) +endif() if(ENABLE_OSMOSDR) if(GROSMOSDR_FOUND) add_definitions(-DOSMOSDR_DRIVER=1) - endif(GROSMOSDR_FOUND) -endif(ENABLE_OSMOSDR) + endif() +endif() if(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd) add_definitions(-DUHD_DRIVER=1) -endif(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd) +endif() #Enable OpenCL if found in the system if(OPENCL_FOUND) - message(STATUS "Adding processing blocks implemented using OpenCL" ) + message(STATUS "Adding processing blocks implemented using OpenCL") add_definitions(-DOPENCL_BLOCKS=1) -else(OPENCL_FOUND) +else() add_definitions(-DOPENCL_BLOCKS=0) -endif(OPENCL_FOUND) +endif() #enable SDR Hardware based on fmcomms2 if(ENABLE_PLUTOSDR) - add_definitions(-DPLUTOSDR_DRIVER=1) - set(OPT_RECEIVER_INCLUDE_DIRS ${OPT_RECEIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) -endif(ENABLE_PLUTOSDR) + add_definitions(-DPLUTOSDR_DRIVER=1) + set(OPT_RECEIVER_INCLUDE_DIRS + ${OPT_RECEIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS} + ) +endif() if(ENABLE_FMCOMMS2) - add_definitions(-DFMCOMMS2_DRIVER=1) - set(OPT_RECEIVER_INCLUDE_DIRS ${OPT_RECEIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) -endif(ENABLE_FMCOMMS2) + add_definitions(-DFMCOMMS2_DRIVER=1) + set(OPT_RECEIVER_INCLUDE_DIRS + ${OPT_RECEIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS} + ) +endif() if(ENABLE_AD9361) add_definitions(-DAD9361_DRIVER=1) - set(OPT_RECEIVER_INCLUDE_DIRS ${OPT_RECEIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS}) -endif(ENABLE_AD9361) + set(OPT_RECEIVER_INCLUDE_DIRS + ${OPT_RECEIVER_INCLUDE_DIRS} ${IIO_INCLUDE_DIRS} + ) +endif() -if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.15" ) - add_definitions( -DGR_GREATER_38=1 ) -endif(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.15" ) +if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.13.4") + add_definitions(-DGR_GREATER_38=1) +endif() include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/libs - ${CMAKE_SOURCE_DIR}/src/core/libs/supl - ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp - ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl - ${CMAKE_SOURCE_DIR}/src/core/monitor - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/channel/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/channel/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/conditioner/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/resampler/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/input_filter/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/input_filter/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs/libswiftcnav - ${CMAKE_SOURCE_DIR}/src/algorithms/observables/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/observables/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib - ${ARMADILLO_INCLUDE_DIRS} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${OPT_RECEIVER_INCLUDE_DIRS} - ${VOLK_GNSSSDR_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/libs + ${CMAKE_SOURCE_DIR}/src/core/libs/supl + ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp + ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl + ${CMAKE_SOURCE_DIR}/src/core/monitor + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/channel/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/channel/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/conditioner/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/resampler/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/input_filter/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/input_filter/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs/libswiftcnav + ${CMAKE_SOURCE_DIR}/src/algorithms/observables/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/observables/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib + ${ARMADILLO_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${PUGIXML_INCLUDE_DIR} + ${OPT_RECEIVER_INCLUDE_DIRS} + ${VOLK_GNSSSDR_INCLUDE_DIRS} ) -file(GLOB GNSS_RECEIVER_HEADERS "*.h") list(SORT GNSS_RECEIVER_HEADERS) -file(GLOB GNSS_RECEIVER_INTERFACE_HEADERS "../interfaces/*.h") -list(SORT GNSS_RECEIVER_INTERFACE_HEADERS) -add_library(gnss_rx ${GNSS_RECEIVER_SOURCES} ${GNSS_RECEIVER_HEADERS} ${GNSS_RECEIVER_INTERFACE_HEADERS}) -source_group(Headers FILES ${GNSS_RECEIVER_HEADERS} ${GNSS_RECEIVER_INTERFACE_HEADERS}) +list(SORT GNSS_RECEIVER_SOURCES) -target_link_libraries(gnss_rx ${Boost_LIBRARIES} - ${ARMADILLO_LIBRARIES} - ${GNURADIO_RUNTIME_LIBRARIES} - ${GNURADIO_BLOCKS_LIBRARIES} - ${GNURADIO_FFT_LIBRARIES} - ${GNURADIO_FILTER_LIBRARIES} - gnss_system_parameters - gnss_sp_libs - signal_source_adapters - datatype_adapters - input_filter_adapters - conditioner_adapters - resampler_adapters - acq_adapters - tracking_adapters - channel_adapters - telemetry_decoder_libswiftcnav - telemetry_decoder_lib - telemetry_decoder_adapters - obs_adapters - pvt_adapters - pvt_lib - rx_core_lib - core_monitor_lib +set(GNSS_RECEIVER_INTERFACE_HEADERS + ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/acquisition_interface.h + ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/channel_interface.h + ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/configuration_interface.h + ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/gnss_block_interface.h + ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/observables_interface.h + ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/pvt_interface.h + ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/telemetry_decoder_interface.h + ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/tracking_interface.h +) + +list(SORT GNSS_RECEIVER_INTERFACE_HEADERS) + +add_library(gnss_rx + ${GNSS_RECEIVER_SOURCES} + ${GNSS_RECEIVER_HEADERS} + ${GNSS_RECEIVER_INTERFACE_HEADERS} +) + +source_group(Headers FILES ${GNSS_RECEIVER_HEADERS} + ${GNSS_RECEIVER_INTERFACE_HEADERS}) + +target_link_libraries(gnss_rx + ${Boost_LIBRARIES} + ${ARMADILLO_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${GNURADIO_FFT_LIBRARIES} + ${GNURADIO_FILTER_LIBRARIES} + gnss_system_parameters + gnss_sp_libs + signal_source_adapters + datatype_adapters + input_filter_adapters + conditioner_adapters + resampler_adapters + acq_adapters + tracking_adapters + channel_adapters + telemetry_decoder_libswiftcnav + telemetry_decoder_lib + telemetry_decoder_adapters + obs_adapters + pvt_adapters + pvt_lib + rx_core_lib + core_monitor_lib ) diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index 8eb49563c..fa7001e97 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -35,6 +35,7 @@ #include "control_thread.h" #include "concurrent_queue.h" #include "concurrent_map.h" +#include "pvt_interface.h" #include "control_message_factory.h" #include "file_configuration.h" #include "gnss_flowgraph.h" @@ -47,6 +48,12 @@ #include "gps_iono.h" #include "gps_utc_model.h" #include "gps_almanac.h" +#include "glonass_gnav_ephemeris.h" +#include "glonass_gnav_utc_model.h" +#include "geofunctions.h" +#include "rtklib_rtkcmn.h" +#include "rtklib_conversions.h" +#include "rtklib_ephemeris.h" #include #include #include @@ -54,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -78,6 +86,7 @@ ControlThread::ControlThread() configuration_ = std::make_shared(FLAGS_c); } delete_configuration_ = false; + restart_ = false; init(); } @@ -86,364 +95,16 @@ ControlThread::ControlThread(std::shared_ptr configurati { configuration_ = configuration; delete_configuration_ = false; + restart_ = false; init(); } -ControlThread::~ControlThread() -{ - // save navigation data to files - // if (save_assistance_to_XML() == true) {} - if (msqid != -1) msgctl(msqid, IPC_RMID, NULL); -} - - -/* - * Runs the control thread that manages the receiver control plane - * - * This is the main loop that reads and process the control messages - * 1- Connect the GNSS receiver flowgraph - * 2- Start the GNSS receiver flowgraph - * while (flowgraph_->running() && !stop)_{ - * 3- Read control messages and process them } - */ -void ControlThread::run() -{ - // Connect the flowgraph - try - { - flowgraph_->connect(); - } - catch (const std::exception &e) - { - LOG(ERROR) << e.what(); - return; - } - if (flowgraph_->connected()) - { - LOG(INFO) << "Flowgraph connected"; - } - else - { - LOG(ERROR) << "Unable to connect flowgraph"; - return; - } - // Start the flowgraph - flowgraph_->start(); - if (flowgraph_->running()) - { - LOG(INFO) << "Flowgraph started"; - } - else - { - LOG(ERROR) << "Unable to start flowgraph"; - return; - } - - //launch GNSS assistance process AFTER the flowgraph is running because the GNURadio asynchronous queues must be already running to transport msgs - assist_GNSS(); - // start the keyboard_listener thread - keyboard_thread_ = boost::thread(&ControlThread::keyboard_listener, this); - sysv_queue_thread_ = boost::thread(&ControlThread::sysv_queue_listener, this); - - bool enable_FPGA = configuration_->property("Channel.enable_FPGA", false); - - if (enable_FPGA == true) - { - flowgraph_->start_acquisition_helper(); - } - - // Main loop to read and process the control messages - while (flowgraph_->running() && !stop_) - { - //TODO re-enable the blocking read messages functions and fork the process - read_control_messages(); - if (control_messages_ != 0) process_control_messages(); - } - std::cout << "Stopping GNSS-SDR, please wait!" << std::endl; - flowgraph_->stop(); - stop_ = true; - flowgraph_->disconnect(); - - //Join keyboard thread -#ifdef OLD_BOOST - keyboard_thread_.timed_join(boost::posix_time::seconds(1)); - sysv_queue_thread_.timed_join(boost::posix_time::seconds(1)); -#endif -#ifndef OLD_BOOST - keyboard_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000)); - sysv_queue_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000)); -#endif - - LOG(INFO) << "Flowgraph stopped"; -} - - -void ControlThread::set_control_queue(gr::msg_queue::sptr control_queue) -{ - if (flowgraph_->running()) - { - LOG(WARNING) << "Unable to set control queue while flowgraph is running"; - return; - } - control_queue_ = control_queue; -} - - -/* - * Returns true if reading was successful - */ -bool ControlThread::read_assistance_from_XML() -{ - // return variable (true == succeeded) - bool ret = false; - // getting names from the config file, if available - std::string eph_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_xml", eph_default_xml_filename); - std::string utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_utc_model.xml", utc_default_xml_filename); - std::string iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_iono_xml", iono_default_xml_filename); - std::string ref_time_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_time_xml", ref_time_default_xml_filename); - std::string ref_location_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_location_xml", ref_location_default_xml_filename); - - std::cout << "SUPL: Try read GPS ephemeris from XML file " << eph_xml_filename << std::endl; - if (supl_client_ephemeris_.load_ephemeris_xml(eph_xml_filename) == true) - { - std::map::const_iterator gps_eph_iter; - for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.cbegin(); - gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); - gps_eph_iter++) - { - std::cout << "SUPL: Read XML Ephemeris for GPS SV " << gps_eph_iter->first << std::endl; - std::shared_ptr tmp_obj = std::make_shared(gps_eph_iter->second); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - ret = true; - } - else - { - std::cout << "ERROR: SUPL client error reading XML" << std::endl; - std::cout << "Disabling SUPL assistance..." << std::endl; - } - // Only look for {utc, iono, ref time, ref location} if SUPL is enabled - bool enable_gps_supl_assistance = configuration_->property("GNSS-SDR.SUPL_gps_enabled", false); - if (enable_gps_supl_assistance == true) - { - // Try to read UTC model from XML - if (supl_client_acquisition_.load_utc_xml(utc_xml_filename) == true) - { - LOG(INFO) << "SUPL: Read XML UTC model"; - std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_utc); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - else - { - LOG(INFO) << "SUPL: couldn't read UTC model XML"; - } - - // Try to read Iono model from XML - if (supl_client_acquisition_.load_iono_xml(iono_xml_filename) == true) - { - LOG(INFO) << "SUPL: Read XML IONO model"; - std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_iono); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - else - { - LOG(INFO) << "SUPL: couldn't read IONO model XML"; - } - - // Try to read Ref Time from XML - if (supl_client_acquisition_.load_ref_time_xml(ref_time_xml_filename) == true) - { - LOG(INFO) << "SUPL: Read XML Ref Time"; - std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_time); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - else - { - LOG(INFO) << "SUPL: couldn't read Ref Time XML"; - } - - // Try to read Ref Location from XML - if (supl_client_acquisition_.load_ref_location_xml(ref_location_xml_filename) == true) - { - LOG(INFO) << "SUPL: Read XML Ref Location"; - std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_ref_loc); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - else - { - LOG(INFO) << "SUPL: couldn't read Ref Location XML"; - } - } - - return ret; -} - - -void ControlThread::assist_GNSS() -{ - //######### GNSS Assistance ################################# - // GNSS Assistance configuration - bool enable_gps_supl_assistance = configuration_->property("GNSS-SDR.SUPL_gps_enabled", false); - if (enable_gps_supl_assistance == true) - //SUPL SERVER TEST. Not operational yet! - { - std::cout << "SUPL RRLP GPS assistance enabled!" << std::endl; - std::string default_acq_server = "supl.nokia.com"; - std::string default_eph_server = "supl.google.com"; - supl_client_ephemeris_.server_name = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_server", default_acq_server); - supl_client_acquisition_.server_name = configuration_->property("GNSS-SDR.SUPL_gps_acquisition_server", default_eph_server); - supl_client_ephemeris_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_port", 7275); - supl_client_acquisition_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_acquisition_port", 7275); - supl_mcc = configuration_->property("GNSS-SDR.SUPL_MCC", 244); - supl_mns = configuration_->property("GNSS-SDR.SUPL_MNS", 5); - - std::string default_lac = "0x59e2"; - std::string default_ci = "0x31b0"; - try - { - supl_lac = boost::lexical_cast(configuration_->property("GNSS-SDR.SUPL_LAC", default_lac)); - } - catch (boost::bad_lexical_cast &) - { - supl_lac = 0x59e2; - } - - try - { - supl_ci = boost::lexical_cast(configuration_->property("GNSS-SDR.SUPL_CI", default_ci)); - } - catch (boost::bad_lexical_cast &) - { - supl_ci = 0x31b0; - } - - bool SUPL_read_gps_assistance_xml = configuration_->property("GNSS-SDR.SUPL_read_gps_assistance_xml", false); - if (SUPL_read_gps_assistance_xml == true) - { - // read assistance from file - if (read_assistance_from_XML()) - { - std::cout << "GPS assistance data loaded from local XML file." << std::endl; - } - } - else - { - // Request ephemeris from SUPL server - int error; - supl_client_ephemeris_.request = 1; - std::cout << "SUPL: Try to read GPS ephemeris from SUPL server..." << std::endl; - error = supl_client_ephemeris_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci); - if (error == 0) - { - std::map::const_iterator gps_eph_iter; - for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.cbegin(); - gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); - gps_eph_iter++) - { - std::cout << "SUPL: Received Ephemeris for GPS SV " << gps_eph_iter->first << std::endl; - std::shared_ptr tmp_obj = std::make_shared(gps_eph_iter->second); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - //Save ephemeris to XML file - std::string eph_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_xml", eph_default_xml_filename); - if (supl_client_ephemeris_.save_ephemeris_map_xml(eph_xml_filename, supl_client_ephemeris_.gps_ephemeris_map) == true) - { - std::cout << "SUPL: XML Ephemeris file created" << std::endl; - } - else - { - std::cout << "SUPL: Failed to create XML Ephemeris file" << std::endl; - } - } - else - { - std::cout << "ERROR: SUPL client for Ephemeris returned " << error << std::endl; - std::cout << "Please check internet connection and SUPL server configuration" << error << std::endl; - std::cout << "Trying to read ephemeris from XML file" << std::endl; - if (read_assistance_from_XML() == false) - { - std::cout << "ERROR: Could not read Ephemeris file: Disabling SUPL assistance." << std::endl; - } - } - - // Request almanac , IONO and UTC Model - supl_client_ephemeris_.request = 0; - std::cout << "SUPL: Try read Almanac, Iono, Utc Model, Ref Time and Ref Location from SUPL server..." << std::endl; - error = supl_client_ephemeris_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci); - if (error == 0) - { - std::map::const_iterator gps_alm_iter; - for (gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.cbegin(); - gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.cend(); - gps_alm_iter++) - { - std::cout << "SUPL: Received Almanac for GPS SV " << gps_alm_iter->first << std::endl; - std::shared_ptr tmp_obj = std::make_shared(gps_alm_iter->second); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - if (supl_client_ephemeris_.gps_iono.valid == true) - { - std::cout << "SUPL: Received GPS Iono" << std::endl; - std::shared_ptr tmp_obj = std::make_shared(supl_client_ephemeris_.gps_iono); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - if (supl_client_ephemeris_.gps_utc.valid == true) - { - std::cout << "SUPL: Received GPS UTC Model" << std::endl; - std::shared_ptr tmp_obj = std::make_shared(supl_client_ephemeris_.gps_utc); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - } - else - { - std::cout << "ERROR: SUPL client for Almanac returned " << error << std::endl; - std::cout << "Please check internet connection and SUPL server configuration" << error << std::endl; - std::cout << "Disabling SUPL assistance." << std::endl; - } - - // Request acquisition assistance - supl_client_acquisition_.request = 2; - std::cout << "SUPL: Try read Acquisition assistance from SUPL server..." << std::endl; - error = supl_client_acquisition_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci); - if (error == 0) - { - std::map::const_iterator gps_acq_iter; - for (gps_acq_iter = supl_client_acquisition_.gps_acq_map.cbegin(); - gps_acq_iter != supl_client_acquisition_.gps_acq_map.cend(); - gps_acq_iter++) - { - std::cout << "SUPL: Received Acquisition assistance for GPS SV " << gps_acq_iter->first << std::endl; - global_gps_acq_assist_map.write(gps_acq_iter->second.i_satellite_PRN, gps_acq_iter->second); - } - if (supl_client_acquisition_.gps_ref_loc.valid == true) - { - std::cout << "SUPL: Received Ref Location (Acquisition Assistance)" << std::endl; - std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_ref_loc); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - if (supl_client_acquisition_.gps_time.valid == true) - { - std::cout << "SUPL: Received Ref Time (Acquisition Assistance)" << std::endl; - std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_time); - flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); - } - } - else - { - std::cout << "ERROR: SUPL client for Acquisition assistance returned " << error << std::endl; - std::cout << "Please check internet connection and SUPL server configuration" << error << std::endl; - std::cout << "Disabling SUPL assistance.." << std::endl; - } - } - } -} - - void ControlThread::init() { // Instantiates a control queue, a GNSS flowgraph, and a control message factory control_queue_ = gr::msg_queue::make(0); + cmd_interface_.set_msg_queue(control_queue_); //set also the queue pointer for the telecommand thread try { flowgraph_ = std::make_shared(configuration_, control_queue_); @@ -461,6 +122,645 @@ void ControlThread::init() supl_lac = 0; supl_ci = 0; msqid = -1; + agnss_ref_location_ = Agnss_Ref_Location(); + agnss_ref_time_ = Agnss_Ref_Time(); + + std::string empty_string = ""; + std::string ref_location_str = configuration_->property("GNSS-SDR.AGNSS_ref_location", empty_string); + std::string ref_time_str = configuration_->property("GNSS-SDR.AGNSS_ref_utc_time", empty_string); + if (ref_location_str.compare(empty_string) != 0) + { + std::vector vect; + std::stringstream ss(ref_location_str); + double d; + while (ss >> d) + { + vect.push_back(d); + if ((ss.peek() == ',') or (ss.peek() == ' ')) + ss.ignore(); + } + // fill agnss_ref_location_ + if (vect.size() >= 2) + { + if ((vect[0] < 90.0) and (vect[0] > -90) and (vect[1] < 180.0) and (vect[1] > -180.0)) + { + agnss_ref_location_.lat = vect[0]; + agnss_ref_location_.lon = vect[1]; + agnss_ref_location_.valid = true; + } + else + { + std::cerr << "GNSS-SDR.AGNSS_ref_location=" << ref_location_str << " is not a valid position." << std::endl; + agnss_ref_location_.valid = false; + } + } + } + if (ref_time_str.compare(empty_string) == 0) + { + // Make an educated guess + time_t rawtime; + time(&rawtime); + agnss_ref_time_.d_tv_sec = rawtime; + agnss_ref_time_.valid = true; + } + else + { + // fill agnss_ref_time_ + struct tm tm; + if (strptime(ref_time_str.c_str(), "%d/%m/%Y %H:%M:%S", &tm) != nullptr) + { + agnss_ref_time_.d_tv_sec = timegm(&tm); + if (agnss_ref_time_.d_tv_sec > 0) + { + agnss_ref_time_.valid = true; + } + else + { + std::cerr << "GNSS-SDR.AGNSS_ref_utc_time=" << ref_time_str << " is not well-formed. Please use four digits for the year: DD/MM/YYYY HH:MM:SS" << std::endl; + } + } + else + { + std::cerr << "GNSS-SDR.AGNSS_ref_utc_time=" << ref_time_str << " is not well-formed. Should be DD/MM/YYYY HH:MM:SS in UTC" << std::endl; + agnss_ref_time_.valid = false; + } + } +} + + +ControlThread::~ControlThread() +{ + // save navigation data to files + // if (save_assistance_to_XML() == true) {} + if (msqid != -1) msgctl(msqid, IPC_RMID, NULL); +} + + +void ControlThread::telecommand_listener() +{ + int tcp_cmd_port = configuration_->property("GNSS-SDR.telecontrol_tcp_port", 3333); + cmd_interface_.run_cmd_server(tcp_cmd_port); +} + + +/* + * Runs the control thread that manages the receiver control plane + * + * This is the main loop that reads and process the control messages + * 1- Connect the GNSS receiver flowgraph + * 2- Start the GNSS receiver flowgraph + * while (flowgraph_->running() && !stop)_{ + * 3- Read control messages and process them } + */ +int ControlThread::run() +{ + // Connect the flowgraph + try + { + flowgraph_->connect(); + } + catch (const std::exception &e) + { + LOG(ERROR) << e.what(); + return 0; + } + if (flowgraph_->connected()) + { + LOG(INFO) << "Flowgraph connected"; + } + else + { + LOG(ERROR) << "Unable to connect flowgraph"; + return 0; + } + // Start the flowgraph + flowgraph_->start(); + if (flowgraph_->running()) + { + LOG(INFO) << "Flowgraph started"; + } + else + { + LOG(ERROR) << "Unable to start flowgraph"; + return 0; + } + + // launch GNSS assistance process AFTER the flowgraph is running because the GNU Radio asynchronous queues must be already running to transport msgs + assist_GNSS(); + // start the keyboard_listener thread + keyboard_thread_ = boost::thread(&ControlThread::keyboard_listener, this); + sysv_queue_thread_ = boost::thread(&ControlThread::sysv_queue_listener, this); + + // start the telecommand listener thread + cmd_interface_.set_pvt(flowgraph_->get_pvt()); + cmd_interface_thread_ = boost::thread(&ControlThread::telecommand_listener, this); + + bool enable_FPGA = configuration_->property("Channel.enable_FPGA", false); + if (enable_FPGA == true) + { + flowgraph_->start_acquisition_helper(); + } + + // Main loop to read and process the control messages + while (flowgraph_->running() && !stop_) + { + //TODO re-enable the blocking read messages functions and fork the process + read_control_messages(); + if (control_messages_ != 0) process_control_messages(); + } + std::cout << "Stopping GNSS-SDR, please wait!" << std::endl; + flowgraph_->stop(); + stop_ = true; + flowgraph_->disconnect(); + +// Join keyboard thread +#ifdef OLD_BOOST + keyboard_thread_.timed_join(boost::posix_time::seconds(1)); + sysv_queue_thread_.timed_join(boost::posix_time::seconds(1)); + cmd_interface_thread_.timed_join(boost::posix_time::seconds(1)); +#endif +#ifndef OLD_BOOST + keyboard_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000)); + sysv_queue_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000)); + cmd_interface_thread_.try_join_until(boost::chrono::steady_clock::now() + boost::chrono::milliseconds(1000)); +#endif + + LOG(INFO) << "Flowgraph stopped"; + + if (restart_) + { + return 42; // signal the gnss-sdr-harness.sh to restart the receiver program + } + else + { + return 0; // normal shutdown + } +} + + +void ControlThread::set_control_queue(gr::msg_queue::sptr control_queue) +{ + if (flowgraph_->running()) + { + LOG(WARNING) << "Unable to set control queue while flowgraph is running"; + return; + } + control_queue_ = control_queue; + cmd_interface_.set_msg_queue(control_queue_); +} + + +/* + * Returns true if reading was successful + */ +bool ControlThread::read_assistance_from_XML() +{ + // return variable (true == succeeded) + bool ret = false; + // getting names from the config file, if available + std::string eph_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_xml", eph_default_xml_filename); + std::string utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_utc_model_xml", utc_default_xml_filename); + std::string iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_iono_xml", iono_default_xml_filename); + std::string gal_iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_iono_xml", gal_iono_default_xml_filename); + std::string ref_time_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_time_xml", ref_time_default_xml_filename); + std::string ref_location_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_location_xml", ref_location_default_xml_filename); + std::string eph_gal_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_ephemeris_xml", eph_gal_default_xml_filename); + std::string eph_cnav_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_cnav_ephemeris_xml", eph_cnav_default_xml_filename); + std::string gal_utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_utc_model_xml", gal_utc_default_xml_filename); + std::string cnav_utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_cnav_utc_model_xml", cnav_utc_default_xml_filename); + std::string eph_glo_xml_filename = configuration_->property("GNSS-SDR.SUPL_glo_ephemeris_xml", eph_glo_gnav_default_xml_filename); + std::string glo_utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_glo_utc_model_xml", glo_utc_default_xml_filename); + std::string gal_almanac_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_almanac_xml", gal_almanac_default_xml_filename); + std::string gps_almanac_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_almanac_xml", gps_almanac_default_xml_filename); + + if (configuration_->property("GNSS-SDR.AGNSS_XML_enabled", false) == true) + { + eph_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_ephemeris_xml", eph_default_xml_filename); + utc_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_utc_model_xml", utc_default_xml_filename); + iono_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_iono_xml", iono_default_xml_filename); + gal_iono_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gal_iono_xml", gal_iono_default_xml_filename); + ref_time_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_ref_time_xml", ref_time_default_xml_filename); + ref_location_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_ref_location_xml", ref_location_default_xml_filename); + eph_gal_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gal_ephemeris_xml", eph_gal_default_xml_filename); + eph_cnav_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_cnav_ephemeris_xml", eph_cnav_default_xml_filename); + gal_utc_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gal_utc_model_xml", gal_utc_default_xml_filename); + cnav_utc_xml_filename = configuration_->property("GNSS-SDR.AGNSS_cnav_utc_model_xml", cnav_utc_default_xml_filename); + eph_glo_xml_filename = configuration_->property("GNSS-SDR.AGNSS_glo_ephemeris_xml", eph_glo_gnav_default_xml_filename); + glo_utc_xml_filename = configuration_->property("GNSS-SDR.AGNSS_glo_utc_model_xml", glo_utc_default_xml_filename); + gal_almanac_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gal_almanac_xml", gal_almanac_default_xml_filename); + gps_almanac_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_almanac_xml", gps_almanac_default_xml_filename); + } + + std::cout << "Trying to read GNSS ephemeris from XML file(s)..." << std::endl; + + if (configuration_->property("Channels_1C.count", 0) > 0) + { + if (supl_client_ephemeris_.load_ephemeris_xml(eph_xml_filename) == true) + { + std::map::const_iterator gps_eph_iter; + for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.cbegin(); + gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); + gps_eph_iter++) + { + std::cout << "From XML file: Read NAV ephemeris for satellite " << Gnss_Satellite("GPS", gps_eph_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gps_eph_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; + } + + if (supl_client_acquisition_.load_utc_xml(utc_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_utc); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read GPS UTC model parameters." << std::endl; + ret = true; + } + + if (supl_client_acquisition_.load_iono_xml(iono_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_iono); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read GPS ionosphere model parameters." << std::endl; + ret = true; + } + + if (supl_client_ephemeris_.load_gps_almanac_xml(gps_almanac_xml_filename) == true) + { + std::map::const_iterator gps_alm_iter; + for (gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.cbegin(); + gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.cend(); + gps_alm_iter++) + { + std::cout << "From XML file: Read GPS almanac for satellite " << Gnss_Satellite("GPS", gps_alm_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gps_alm_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; + } + } + + if ((configuration_->property("Channels_1B.count", 0) > 0) or (configuration_->property("Channels_5X.count", 0) > 0)) + { + if (supl_client_ephemeris_.load_gal_ephemeris_xml(eph_gal_xml_filename) == true) + { + std::map::const_iterator gal_eph_iter; + for (gal_eph_iter = supl_client_ephemeris_.gal_ephemeris_map.cbegin(); + gal_eph_iter != supl_client_ephemeris_.gal_ephemeris_map.cend(); + gal_eph_iter++) + { + std::cout << "From XML file: Read ephemeris for satellite " << Gnss_Satellite("Galileo", gal_eph_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gal_eph_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; + } + + if (supl_client_acquisition_.load_gal_iono_xml(gal_iono_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gal_iono); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read Galileo ionosphere model parameters." << std::endl; + ret = true; + } + + if (supl_client_acquisition_.load_gal_utc_xml(gal_utc_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gal_utc); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read Galileo UTC model parameters." << std::endl; + ret = true; + } + + if (supl_client_ephemeris_.load_gal_almanac_xml(gal_almanac_xml_filename) == true) + { + std::map::const_iterator gal_alm_iter; + for (gal_alm_iter = supl_client_ephemeris_.gal_almanac_map.cbegin(); + gal_alm_iter != supl_client_ephemeris_.gal_almanac_map.cend(); + gal_alm_iter++) + { + std::cout << "From XML file: Read Galileo almanac for satellite " << Gnss_Satellite("Galileo", gal_alm_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gal_alm_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; + } + } + + if ((configuration_->property("Channels_2S.count", 0) > 0) or (configuration_->property("Channels_L5.count", 0) > 0)) + { + if (supl_client_ephemeris_.load_cnav_ephemeris_xml(eph_cnav_xml_filename) == true) + { + std::map::const_iterator gps_cnav_eph_iter; + for (gps_cnav_eph_iter = supl_client_ephemeris_.gps_cnav_ephemeris_map.cbegin(); + gps_cnav_eph_iter != supl_client_ephemeris_.gps_cnav_ephemeris_map.cend(); + gps_cnav_eph_iter++) + { + std::cout << "From XML file: Read CNAV ephemeris for satellite " << Gnss_Satellite("GPS", gps_cnav_eph_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gps_cnav_eph_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; + } + + if (supl_client_acquisition_.load_cnav_utc_xml(cnav_utc_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_cnav_utc); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read GPS CNAV UTC model parameters." << std::endl; + ret = true; + } + } + + if ((configuration_->property("Channels_1G.count", 0) > 0) or (configuration_->property("Channels_2G.count", 0) > 0)) + { + if (supl_client_ephemeris_.load_gnav_ephemeris_xml(eph_glo_xml_filename) == true) + { + std::map::const_iterator glo_gnav_eph_iter; + for (glo_gnav_eph_iter = supl_client_ephemeris_.glonass_gnav_ephemeris_map.cbegin(); + glo_gnav_eph_iter != supl_client_ephemeris_.glonass_gnav_ephemeris_map.cend(); + glo_gnav_eph_iter++) + { + std::cout << "From XML file: Read GLONASS GNAV ephemeris for satellite " << Gnss_Satellite("GLONASS", glo_gnav_eph_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(glo_gnav_eph_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + ret = true; + } + + if (supl_client_acquisition_.load_glo_utc_xml(glo_utc_xml_filename) == true) + { + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.glo_gnav_utc); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + std::cout << "From XML file: Read GLONASS UTC model parameters." << std::endl; + ret = true; + } + } + + if (ret == false) + { + std::cout << "Error reading XML files" << std::endl; + std::cout << "Disabling GNSS assistance..." << std::endl; + } + + // Only look for {ref time, ref location} if SUPL is enabled + bool enable_gps_supl_assistance = configuration_->property("GNSS-SDR.SUPL_gps_enabled", false); + if (enable_gps_supl_assistance == true) + { + // Try to read Ref Time from XML + if (supl_client_acquisition_.load_ref_time_xml(ref_time_xml_filename) == true) + { + LOG(INFO) << "SUPL: Read XML Ref Time"; + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_time); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + else + { + LOG(INFO) << "SUPL: could not read Ref Time XML"; + } + + // Try to read Ref Location from XML + if (supl_client_acquisition_.load_ref_location_xml(ref_location_xml_filename) == true) + { + LOG(INFO) << "SUPL: Read XML Ref Location"; + std::shared_ptr tmp_obj = std::make_shared(supl_client_acquisition_.gps_ref_loc); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + else + { + LOG(INFO) << "SUPL: could not read Ref Location XML"; + } + } + + return ret; +} + + +void ControlThread::assist_GNSS() +{ + //######### GNSS Assistance ################################# + // GNSS Assistance configuration + bool enable_gps_supl_assistance = configuration_->property("GNSS-SDR.SUPL_gps_enabled", false); + bool enable_agnss_xml = configuration_->property("GNSS-SDR.AGNSS_XML_enabled", false); + if ((enable_gps_supl_assistance == true) and (enable_agnss_xml == false)) + { + std::cout << "SUPL RRLP GPS assistance enabled!" << std::endl; + std::string default_acq_server = "supl.google.com"; + std::string default_eph_server = "supl.google.com"; + supl_client_ephemeris_.server_name = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_server", default_acq_server); + supl_client_acquisition_.server_name = configuration_->property("GNSS-SDR.SUPL_gps_acquisition_server", default_eph_server); + supl_client_ephemeris_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_port", 7275); + supl_client_acquisition_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_acquisition_port", 7275); + supl_mcc = configuration_->property("GNSS-SDR.SUPL_MCC", 244); + supl_mns = configuration_->property("GNSS-SDR.SUPL_MNC ", 5); + + std::string default_lac = "0x59e2"; + std::string default_ci = "0x31b0"; + std::string supl_lac_s = configuration_->property("GNSS-SDR.SUPL_LAC", default_lac); + std::string supl_ci_s = configuration_->property("GNSS-SDR.SUPL_CI", default_ci); + try + { + supl_lac = std::stoi(supl_lac_s, nullptr, 0); + } + catch (const std::invalid_argument &ia) + { + std::cerr << "Invalid argument for SUPL LAC: " << ia.what() << '\n'; + supl_lac = -1; + } + try + { + supl_ci = std::stoi(supl_ci_s, nullptr, 0); + } + catch (const std::invalid_argument &ia) + { + std::cerr << "Invalid argument for SUPL CI: " << ia.what() << '\n'; + supl_ci = -1; + } + + if (supl_lac < 0 or supl_lac > 65535) + { + supl_lac = 0x59e2; + } + + if (supl_ci < 0 or supl_ci > 268435455) // 2^16 for GSM and CDMA, 2^28 for UMTS and LTE networks + { + supl_ci = 0x31b0; + } + + bool SUPL_read_gps_assistance_xml = configuration_->property("GNSS-SDR.SUPL_read_gps_assistance_xml", false); + if (SUPL_read_gps_assistance_xml == true) + { + // Read assistance from file + if (read_assistance_from_XML()) + { + std::cout << "GNSS assistance data loaded from local XML file(s)." << std::endl; + std::cout << "No SUPL request has been performed." << std::endl; + } + } + else + { + // Request ephemeris from SUPL server + int error; + supl_client_ephemeris_.request = 1; + std::cout << "SUPL: Try to read GPS ephemeris data from SUPL server..." << std::endl; + error = supl_client_ephemeris_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci); + if (error == 0) + { + std::map::const_iterator gps_eph_iter; + for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.cbegin(); + gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); + gps_eph_iter++) + { + std::cout << "SUPL: Received ephemeris data for satellite " << Gnss_Satellite("GPS", gps_eph_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gps_eph_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + // Save ephemeris to XML file + std::string eph_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_xml", eph_default_xml_filename); + if (supl_client_ephemeris_.save_ephemeris_map_xml(eph_xml_filename, supl_client_ephemeris_.gps_ephemeris_map) == true) + { + std::cout << "SUPL: XML ephemeris data file created" << std::endl; + } + else + { + std::cout << "SUPL: Failed to create XML ephemeris data file" << std::endl; + } + } + else + { + std::cout << "ERROR: SUPL client request for ephemeris data returned " << error << std::endl; + std::cout << "Please check your network connectivity and SUPL server configuration" << std::endl; + std::cout << "Trying to read AGNSS data from local XML file(s)..." << std::endl; + if (read_assistance_from_XML() == false) + { + std::cout << "ERROR: Could not read XML files: Disabling SUPL assistance." << std::endl; + } + } + + // Request almanac, IONO and UTC Model data + supl_client_ephemeris_.request = 0; + std::cout << "SUPL: Try to read Almanac, Iono, Utc Model, Ref Time and Ref Location data from SUPL server..." << std::endl; + error = supl_client_ephemeris_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci); + if (error == 0) + { + std::map::const_iterator gps_alm_iter; + for (gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.cbegin(); + gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.cend(); + gps_alm_iter++) + { + std::cout << "SUPL: Received almanac data for satellite " << Gnss_Satellite("GPS", gps_alm_iter->second.i_satellite_PRN) << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gps_alm_iter->second); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + supl_client_ephemeris_.save_gps_almanac_xml("gps_almanac_map.xml", supl_client_ephemeris_.gps_almanac_map); + if (supl_client_ephemeris_.gps_iono.valid == true) + { + std::cout << "SUPL: Received GPS Ionosphere model parameters" << std::endl; + std::shared_ptr tmp_obj = std::make_shared(supl_client_ephemeris_.gps_iono); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + if (supl_client_ephemeris_.gps_utc.valid == true) + { + std::cout << "SUPL: Received GPS UTC model parameters" << std::endl; + std::shared_ptr tmp_obj = std::make_shared(supl_client_ephemeris_.gps_utc); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + } + // Save iono and UTC model data to xml file + std::string iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_iono_xml", iono_default_xml_filename); + if (supl_client_ephemeris_.save_iono_xml(iono_xml_filename, supl_client_ephemeris_.gps_iono) == true) + { + std::cout << "SUPL: Iono data file created" << std::endl; + } + else + { + std::cout << "SUPL: Failed to create Iono data file" << std::endl; + } + std::string utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_utc_model_xml", utc_default_xml_filename); + if (supl_client_ephemeris_.save_utc_xml(utc_xml_filename, supl_client_ephemeris_.gps_utc) == true) + { + std::cout << "SUPL: UTC model data file created" << std::endl; + } + else + { + std::cout << "SUPL: Failed to create UTC model data file" << std::endl; + } + } + else + { + std::cout << "ERROR: SUPL client for almanac data returned " << error << std::endl; + std::cout << "Please check your network connectivity and SUPL server configuration" << std::endl; + } + + // Request acquisition assistance + supl_client_acquisition_.request = 2; + std::cout << "SUPL: Try to read acquisition assistance data from SUPL server..." << std::endl; + error = supl_client_acquisition_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci); + if (error == 0) + { + std::map::const_iterator gps_acq_iter; + for (gps_acq_iter = supl_client_acquisition_.gps_acq_map.cbegin(); + gps_acq_iter != supl_client_acquisition_.gps_acq_map.cend(); + gps_acq_iter++) + { + std::cout << "SUPL: Received acquisition assistance data for satellite " << Gnss_Satellite("GPS", gps_acq_iter->second.i_satellite_PRN) << std::endl; + global_gps_acq_assist_map.write(gps_acq_iter->second.i_satellite_PRN, gps_acq_iter->second); + } + if (supl_client_acquisition_.gps_ref_loc.valid == true) + { + std::cout << "SUPL: Received Ref Location data (Acquisition Assistance)" << std::endl; + agnss_ref_location_ = supl_client_acquisition_.gps_ref_loc; + std::shared_ptr tmp_obj = std::make_shared(agnss_ref_location_); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + supl_client_acquisition_.save_ref_location_xml("agnss_ref_location.xml", agnss_ref_location_); + } + if (supl_client_acquisition_.gps_time.valid == true) + { + std::cout << "SUPL: Received Ref Time data (Acquisition Assistance)" << std::endl; + agnss_ref_time_ = supl_client_acquisition_.gps_time; + std::shared_ptr tmp_obj = std::make_shared(agnss_ref_time_); + flowgraph_->send_telemetry_msg(pmt::make_any(tmp_obj)); + supl_client_acquisition_.save_ref_time_xml("agnss_ref_time.xml", agnss_ref_time_); + } + } + else + { + std::cout << "ERROR: SUPL client for acquisition assistance returned " << error << std::endl; + std::cout << "Please check your network connectivity and SUPL server configuration" << std::endl; + std::cout << "Disabling SUPL acquisition assistance." << std::endl; + } + } + } + + if ((enable_gps_supl_assistance == false) and (enable_agnss_xml == true)) + { + // read assistance from file + if (read_assistance_from_XML()) + { + std::cout << "GNSS assistance data loaded from local XML file(s)." << std::endl; + } + } + + // If AGNSS is enabled, make use of it + if ((agnss_ref_location_.valid == true) and ((enable_gps_supl_assistance == true) or (enable_agnss_xml == true))) + { + // Get the list of visible satellites + arma::vec ref_LLH = arma::zeros(3, 1); + ref_LLH(0) = agnss_ref_location_.lat; + ref_LLH(1) = agnss_ref_location_.lon; + time_t ref_rx_utc_time = 0; + if (agnss_ref_time_.valid == true) + { + ref_rx_utc_time = agnss_ref_time_.d_tv_sec; + } + + std::vector> visible_sats = get_visible_sats(ref_rx_utc_time, ref_LLH); + // Set the receiver in Standby mode + flowgraph_->apply_action(0, 10); + // Give priority to visible satellites in the search list + flowgraph_->priorize_satellites(visible_sats); + // Hot Start + flowgraph_->apply_action(0, 12); + } } @@ -480,7 +780,6 @@ void ControlThread::read_control_messages() // Apply the corresponding control actions -// TODO: May be it is better to move the apply_action state machine to the control_thread void ControlThread::process_control_messages() { for (unsigned int i = 0; i < control_messages_->size(); i++) @@ -492,6 +791,10 @@ void ControlThread::process_control_messages() } else { + if (control_messages_->at(i)->who == 300) // some TC commands require also actions from control_thread + { + apply_action(control_messages_->at(i)->what); + } flowgraph_->apply_action(control_messages_->at(i)->who, control_messages_->at(i)->what); } processed_control_messages_++; @@ -503,20 +806,196 @@ void ControlThread::process_control_messages() void ControlThread::apply_action(unsigned int what) { + std::shared_ptr pvt_ptr; + std::vector> visible_satellites; switch (what) { case 0: - DLOG(INFO) << "Received action STOP"; + LOG(INFO) << "Received action STOP"; stop_ = true; applied_actions_++; break; + case 1: + LOG(INFO) << "Received action RESTART"; + stop_ = true; + restart_ = true; + applied_actions_++; + break; + case 11: + LOG(INFO) << "Receiver action COLDSTART"; + // delete all ephemeris and almanac information from maps (also the PVT map queue) + pvt_ptr = flowgraph_->get_pvt(); + pvt_ptr->clear_ephemeris(); + // todo: reorder the satellite queues to the receiver default startup order. + // This is required to allow repeatability. Otherwise the satellite search order will depend on the last tracked satellites + break; + case 12: + LOG(INFO) << "Receiver action HOTSTART"; + visible_satellites = get_visible_sats(cmd_interface_.get_utc_time(), cmd_interface_.get_LLH()); + // reorder the satellite queue to acquire first those visible satellites + flowgraph_->priorize_satellites(visible_satellites); + // start again the satellite acquisitions (done in chained apply_action to flowgraph) + break; + case 13: + LOG(INFO) << "Receiver action WARMSTART"; + // delete all ephemeris and almanac information from maps (also the PVT map queue) + pvt_ptr = flowgraph_->get_pvt(); + pvt_ptr->clear_ephemeris(); + // load the ephemeris and the almanac from XML files (receiver assistance) + read_assistance_from_XML(); + // call here the function that computes the set of visible satellites and its elevation + // for the date and time specified by the warm start command and the assisted position + get_visible_sats(cmd_interface_.get_utc_time(), cmd_interface_.get_LLH()); + // reorder the satellite queue to acquire first those visible satellites + flowgraph_->priorize_satellites(visible_satellites); + // start again the satellite acquisitions (done in chained apply_action to flowgraph) + break; default: - DLOG(INFO) << "Unrecognized action."; + LOG(INFO) << "Unrecognized action."; break; } } +std::vector> ControlThread::get_visible_sats(time_t rx_utc_time, const arma::vec &LLH) +{ + // 1. Compute rx ECEF position from LLH WGS84 + arma::vec LLH_rad = arma::vec{degtorad(LLH(0)), degtorad(LLH(1)), LLH(2)}; + arma::mat C_tmp = arma::zeros(3, 3); + arma::vec r_eb_e = arma::zeros(3, 1); + arma::vec v_eb_e = arma::zeros(3, 1); + Geo_to_ECEF(LLH_rad, arma::vec{0, 0, 0}, C_tmp, r_eb_e, v_eb_e, C_tmp); + + // 2. Compute rx GPS time from UTC time + gtime_t utc_gtime; + utc_gtime.time = rx_utc_time; + utc_gtime.sec = 0; + gtime_t gps_gtime = utc2gpst(utc_gtime); + + // 3. loop through all the available ephemeris or almanac and compute satellite positions and elevations + // store visible satellites in a vector of pairs to associate an elevation to the each satellite + std::vector> available_satellites; + std::vector visible_gps; + std::vector visible_gal; + std::shared_ptr pvt_ptr = flowgraph_->get_pvt(); + struct tm tstruct; + char buf[80]; + tstruct = *gmtime(&rx_utc_time); + strftime(buf, sizeof(buf), "%d/%m/%Y %H:%M:%S ", &tstruct); + std::string str_time = std::string(buf); + std::cout << "Get visible satellites at " << str_time + << "UTC, assuming RX position " << LLH(0) << " [deg], " << LLH(1) << " [deg], " << LLH(2) << " [m]" << std::endl; + + std::map gps_eph_map = pvt_ptr->get_gps_ephemeris(); + for (std::map::iterator it = gps_eph_map.begin(); it != gps_eph_map.end(); ++it) + { + eph_t rtklib_eph = eph_to_rtklib(it->second); + double r_sat[3]; + double clock_bias_s; + double sat_pos_variance_m2; + eph2pos(gps_gtime, &rtklib_eph, &r_sat[0], &clock_bias_s, + &sat_pos_variance_m2); + double Az, El, dist_m; + arma::vec r_sat_eb_e = arma::vec{r_sat[0], r_sat[1], r_sat[2]}; + arma::vec dx = r_sat_eb_e - r_eb_e; + topocent(&Az, &El, &dist_m, r_eb_e, dx); + // push sat + if (El > 0) + { + std::cout << "Using GPS Ephemeris: Sat " << it->second.i_satellite_PRN << " Az: " << Az << " El: " << El << std::endl; + available_satellites.push_back(std::pair(floor(El), + (Gnss_Satellite(std::string("GPS"), it->second.i_satellite_PRN)))); + visible_gps.push_back(it->second.i_satellite_PRN); + } + } + + std::map gal_eph_map = pvt_ptr->get_galileo_ephemeris(); + for (std::map::iterator it = gal_eph_map.begin(); it != gal_eph_map.end(); ++it) + { + eph_t rtklib_eph = eph_to_rtklib(it->second); + double r_sat[3]; + double clock_bias_s; + double sat_pos_variance_m2; + eph2pos(gps_gtime, &rtklib_eph, &r_sat[0], &clock_bias_s, + &sat_pos_variance_m2); + double Az, El, dist_m; + arma::vec r_sat_eb_e = arma::vec{r_sat[0], r_sat[1], r_sat[2]}; + arma::vec dx = r_sat_eb_e - r_eb_e; + topocent(&Az, &El, &dist_m, r_eb_e, dx); + // push sat + if (El > 0) + { + std::cout << "Using Galileo Ephemeris: Sat " << it->second.i_satellite_PRN << " Az: " << Az << " El: " << El << std::endl; + available_satellites.push_back(std::pair(floor(El), + (Gnss_Satellite(std::string("Galileo"), it->second.i_satellite_PRN)))); + visible_gal.push_back(it->second.i_satellite_PRN); + } + } + + std::map gps_alm_map = pvt_ptr->get_gps_almanac(); + for (std::map::iterator it = gps_alm_map.begin(); it != gps_alm_map.end(); ++it) + { + alm_t rtklib_alm = alm_to_rtklib(it->second); + double r_sat[3]; + double clock_bias_s; + gtime_t aux_gtime; + aux_gtime.time = fmod(utc2gpst(gps_gtime).time + 345600, 604800); + alm2pos(aux_gtime, &rtklib_alm, &r_sat[0], &clock_bias_s); + double Az, El, dist_m; + arma::vec r_sat_eb_e = arma::vec{r_sat[0], r_sat[1], r_sat[2]}; + arma::vec dx = r_sat_eb_e - r_eb_e; + topocent(&Az, &El, &dist_m, r_eb_e, dx); + // push sat + std::vector::iterator it2; + if (El > 0) + { + it2 = std::find(visible_gps.begin(), visible_gps.end(), it->second.i_satellite_PRN); + if (it2 == visible_gps.end()) + { + std::cout << "Using GPS Almanac: Sat " << it->second.i_satellite_PRN << " Az: " << Az << " El: " << El << std::endl; + available_satellites.push_back(std::pair(floor(El), + (Gnss_Satellite(std::string("GPS"), it->second.i_satellite_PRN)))); + } + } + } + + std::map gal_alm_map = pvt_ptr->get_galileo_almanac(); + for (std::map::iterator it = gal_alm_map.begin(); it != gal_alm_map.end(); ++it) + { + alm_t rtklib_alm = alm_to_rtklib(it->second); + double r_sat[3]; + double clock_bias_s; + gtime_t gal_gtime; + gal_gtime.time = fmod(utc2gpst(gps_gtime).time + 345600, 604800); + alm2pos(gal_gtime, &rtklib_alm, &r_sat[0], &clock_bias_s); + double Az, El, dist_m; + arma::vec r_sat_eb_e = arma::vec{r_sat[0], r_sat[1], r_sat[2]}; + arma::vec dx = r_sat_eb_e - r_eb_e; + topocent(&Az, &El, &dist_m, r_eb_e, dx); + // push sat + std::vector::iterator it2; + if (El > 0) + { + it2 = std::find(visible_gal.begin(), visible_gal.end(), it->second.i_satellite_PRN); + if (it2 == visible_gal.end()) + { + std::cout << "Using Galileo Almanac: Sat " << it->second.i_satellite_PRN << " Az: " << Az << " El: " << El << std::endl; + available_satellites.push_back(std::pair(floor(El), + (Gnss_Satellite(std::string("Galileo"), it->second.i_satellite_PRN)))); + } + } + } + + // sort the visible satellites in ascending order of elevation + std::sort(available_satellites.begin(), available_satellites.end(), [](const std::pair &a, const std::pair &b) { // use lambda. Cleaner and easier to read + return a.first < b.first; + }); + // provide list starting from satellites with higher elevation + std::reverse(available_satellites.begin(), available_satellites.end()); + return available_satellites; +} + + void ControlThread::gps_acq_assist_data_collector() { // ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE #################### diff --git a/src/core/receiver/control_thread.h b/src/core/receiver/control_thread.h index c49ddba53..bf78028c1 100644 --- a/src/core/receiver/control_thread.h +++ b/src/core/receiver/control_thread.h @@ -35,15 +35,19 @@ #ifndef GNSS_SDR_CONTROL_THREAD_H_ #define GNSS_SDR_CONTROL_THREAD_H_ +#include "gnss_satellite.h" #include "control_message_factory.h" #include "gnss_sdr_supl_client.h" +#include "tcp_cmd_interface.h" +#include "gnss_flowgraph.h" +#include "configuration_interface.h" +#include "agnss_ref_location.h" +#include "agnss_ref_time.h" #include #include #include #include - -class GNSSFlowgraph; -class ConfigurationInterface; +#include /*! @@ -82,7 +86,7 @@ public: * * - Read control messages and process them; } */ - void run(); + int run(); /*! * \brief Sets the control_queue @@ -113,6 +117,10 @@ public: } private: + //Telecommand TCP interface + TcpCmdInterface cmd_interface_; + void telecommand_listener(); + boost::thread cmd_interface_thread_; //SUPL assistance classes gnss_sdr_supl_client supl_client_acquisition_; gnss_sdr_supl_client supl_client_ephemeris_; @@ -138,6 +146,12 @@ private: */ void gps_acq_assist_data_collector(); + /* + * Compute elevations for the specified time and position for all the available satellites in ephemeris and almanac queues + * returns a vector filled with the available satellites ordered from high elevation to low elevation angle. + */ + std::vector> get_visible_sats(time_t rx_utc_time, const arma::vec& LLH); + /* * Read initial GNSS assistance from SUPL server or local XML files */ @@ -150,6 +164,7 @@ private: std::shared_ptr control_message_factory_; std::shared_ptr>> control_messages_; bool stop_; + bool restart_; bool delete_configuration_; unsigned int processed_control_messages_; unsigned int applied_actions_; @@ -167,6 +182,18 @@ private: const std::string iono_default_xml_filename = "./gps_iono.xml"; const std::string ref_time_default_xml_filename = "./gps_ref_time.xml"; const std::string ref_location_default_xml_filename = "./gps_ref_location.xml"; + const std::string eph_gal_default_xml_filename = "./gal_ephemeris.xml"; + const std::string eph_cnav_default_xml_filename = "./gps_cnav_ephemeris.xml"; + const std::string gal_iono_default_xml_filename = "./gal_iono.xml"; + const std::string gal_utc_default_xml_filename = "./gal_utc_model.xml"; + const std::string cnav_utc_default_xml_filename = "./gps_cnav_utc_model.xml"; + const std::string eph_glo_gnav_default_xml_filename = "./glo_gnav_ephemeris.xml"; + const std::string glo_utc_default_xml_filename = "./glo_utc_model.xml"; + const std::string gal_almanac_default_xml_filename = "./gal_almanac.xml"; + const std::string gps_almanac_default_xml_filename = "./gps_almanac.xml"; + + Agnss_Ref_Location agnss_ref_location_; + Agnss_Ref_Time agnss_ref_time_; }; #endif /*GNSS_SDR_CONTROL_THREAD_H_*/ diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index f4bb4209e..7ef051d26 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -4,6 +4,7 @@ * \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com * Luis Esteve, 2012. luis(at)epsilon-formacion.com * Javier Arribas, 2011. jarribas(at)cttc.es + * Marc Majoral, 2018. mmajoral(at)cttc.es * * This class encapsulates the complexity behind the instantiation * of GNSS blocks. @@ -103,6 +104,7 @@ #include "sbas_l1_telemetry_decoder.h" #include "hybrid_observables.h" #include "rtklib_pvt.h" +#include "gps_l1_ca_kf_tracking.h" #if RAW_UDP #include "custom_udp_signal_source.h" @@ -110,7 +112,15 @@ #if ENABLE_FPGA #include "gps_l1_ca_pcps_acquisition_fpga.h" +#include "gps_l2_m_pcps_acquisition_fpga.h" +#include "galileo_e1_pcps_ambiguous_acquisition_fpga.h" +#include "galileo_e5a_pcps_acquisition_fpga.h" +#include "gps_l5i_pcps_acquisition_fpga.h" #include "gps_l1_ca_dll_pll_tracking_fpga.h" +#include "gps_l2_m_dll_pll_tracking_fpga.h" +#include "galileo_e1_dll_pll_veml_tracking_fpga.h" +#include "galileo_e5a_dll_pll_tracking_fpga.h" +#include "gps_l5_dll_pll_tracking_fpga.h" #endif #if OPENCL_BLOCKS @@ -163,7 +173,11 @@ using google::LogMessage; GNSSBlockFactory::GNSSBlockFactory() {} + + GNSSBlockFactory::~GNSSBlockFactory() {} + + std::unique_ptr GNSSBlockFactory::GetSignalSource( std::shared_ptr configuration, gr::msg_queue::sptr queue, int ID) { @@ -1389,18 +1403,42 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("GPS_L2_M_PCPS_Acquisition_Fpga") == 0) + { + std::unique_ptr block_(new GpsL2MPcpsAcquisitionFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0) { std::unique_ptr block_(new GpsL5iPcpsAcquisition(configuration.get(), role, in_streams, out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("GPS_L5i_PCPS_Acquisition_Fpga") == 0) + { + std::unique_ptr block_(new GpsL5iPcpsAcquisitionFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0) { std::unique_ptr block_(new GalileoE1PcpsAmbiguousAcquisition(configuration.get(), role, in_streams, out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga") == 0) + { + std::unique_ptr block_(new GalileoE1PcpsAmbiguousAcquisitionFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("Galileo_E1_PCPS_8ms_Ambiguous_Acquisition") == 0) { std::unique_ptr block_(new GalileoE1Pcps8msAmbiguousAcquisition(configuration.get(), role, in_streams, @@ -1431,6 +1469,14 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("Galileo_E5a_Pcps_Acquisition_Fpga") == 0) + { + std::unique_ptr block_(new GalileoE5aPcpsAcquisitionFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition") == 0) { std::unique_ptr block_(new GalileoE1PcpsQuickSyncAmbiguousAcquisition(configuration.get(), role, in_streams, @@ -1456,6 +1502,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } + else if (implementation.compare("GPS_L1_CA_KF_Tracking") == 0) + { + std::unique_ptr block_(new GpsL1CaKfTracking(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } else if (implementation.compare("GPS_L1_CA_DLL_PLL_C_Aid_Tracking") == 0) { std::unique_ptr block_(new GpsL1CaDllPllCAidTracking(configuration.get(), role, in_streams, @@ -1482,12 +1534,28 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking_Fpga") == 0) + { + std::unique_ptr block_(new GpsL2MDllPllTrackingFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if ((implementation.compare("GPS_L5i_DLL_PLL_Tracking") == 0) or (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0)) { std::unique_ptr block_(new GpsL5DllPllTracking(configuration.get(), role, in_streams, out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if ((implementation.compare("GPS_L5i_DLL_PLL_Tracking_Fpga") == 0) or (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) + { + std::unique_ptr block_(new GpsL5DllPllTrackingFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif #if CUDA_GPU_ACCEL else if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_GPU") == 0) { @@ -1502,6 +1570,14 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) + { + std::unique_ptr block_(new GalileoE1DllPllVemlTrackingFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("Galileo_E1_TCP_CONNECTOR_Tracking") == 0) { std::unique_ptr block_(new GalileoE1TcpConnectorTracking(configuration.get(), role, in_streams, @@ -1514,6 +1590,14 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) + { + std::unique_ptr block_(new GalileoE5aDllPllTrackingFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("GLONASS_L1_CA_DLL_PLL_Tracking") == 0) { std::unique_ptr block_(new GlonassL1CaDllPllTracking(configuration.get(), role, in_streams, @@ -1682,18 +1766,42 @@ std::unique_ptr GNSSBlockFactory::GetAcqBlock( out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("GPS_L2_M_PCPS_Acquisition_Fpga") == 0) + { + std::unique_ptr block_(new GpsL2MPcpsAcquisitionFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0) { std::unique_ptr block_(new GpsL5iPcpsAcquisition(configuration.get(), role, in_streams, out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("GPS_L5i_PCPS_Acquisition_Fpga") == 0) + { + std::unique_ptr block_(new GpsL5iPcpsAcquisitionFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0) { std::unique_ptr block_(new GalileoE1PcpsAmbiguousAcquisition(configuration.get(), role, in_streams, out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga") == 0) + { + std::unique_ptr block_(new GalileoE1PcpsAmbiguousAcquisitionFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("Galileo_E1_PCPS_8ms_Ambiguous_Acquisition") == 0) { std::unique_ptr block_(new GalileoE1Pcps8msAmbiguousAcquisition(configuration.get(), role, in_streams, @@ -1731,6 +1839,14 @@ std::unique_ptr GNSSBlockFactory::GetAcqBlock( out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("Galileo_E5a_Pcps_Acquisition_Fpga") == 0) + { + std::unique_ptr block_(new GalileoE5aPcpsAcquisitionFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0) { std::unique_ptr block_(new GlonassL1CaPcpsAcquisition(configuration.get(), role, in_streams, @@ -1767,6 +1883,12 @@ std::unique_ptr GNSSBlockFactory::GetTrkBlock( out_streams)); block = std::move(block_); } + else if (implementation.compare("GPS_L1_CA_KF_Tracking") == 0) + { + std::unique_ptr block_(new GpsL1CaKfTracking(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } else if (implementation.compare("GPS_L1_CA_DLL_PLL_C_Aid_Tracking") == 0) { std::unique_ptr block_(new GpsL1CaDllPllCAidTracking(configuration.get(), role, in_streams, @@ -1793,6 +1915,14 @@ std::unique_ptr GNSSBlockFactory::GetTrkBlock( out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") == 0) + { + std::unique_ptr block_(new GalileoE1DllPllVemlTrackingFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("Galileo_E1_TCP_CONNECTOR_Tracking") == 0) { std::unique_ptr block_(new GalileoE1TcpConnectorTracking(configuration.get(), role, in_streams, @@ -1805,18 +1935,42 @@ std::unique_ptr GNSSBlockFactory::GetTrkBlock( out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_Fpga") == 0) + { + std::unique_ptr block_(new GalileoE5aDllPllTrackingFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0) { std::unique_ptr block_(new GpsL2MDllPllTracking(configuration.get(), role, in_streams, out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking_Fpga") == 0) + { + std::unique_ptr block_(new GpsL2MDllPllTrackingFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif else if ((implementation.compare("GPS_L5i_DLL_PLL_Tracking") == 0) or (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0)) { std::unique_ptr block_(new GpsL5DllPllTracking(configuration.get(), role, in_streams, out_streams)); block = std::move(block_); } +#if ENABLE_FPGA + else if ((implementation.compare("GPS_L5i_DLL_PLL_Tracking_Fpga") == 0) or (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) + { + std::unique_ptr block_(new GpsL5DllPllTrackingFpga(configuration.get(), role, in_streams, + out_streams)); + block = std::move(block_); + } +#endif #if CUDA_GPU_ACCEL else if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking_GPU") == 0) { diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index b5b978d9f..e00fe7847 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -5,6 +5,7 @@ * Luis Esteve, 2012. luis(at)epsilon-formacion.com * Carles Fernandez-Prades, 2014. cfernandez(at)cttc.es * Álvaro Cebrián Juan, 2018. acebrianjuan(at)gmail.com + * Javier Arribas, 2018. javiarribas(at)gmail.com * * ------------------------------------------------------------------------- * @@ -277,7 +278,8 @@ void GNSSFlowgraph::connect() std::cout << "Set GNSS-SDR.internal_fs_sps in configuration file" << std::endl; throw(std::invalid_argument("Set GNSS-SDR.internal_fs_sps in configuration")); } - ch_out_sample_counter = gnss_sdr_make_sample_counter(fs, sig_conditioner_.at(0)->get_right_block()->output_signature()->sizeof_stream_item(0)); + int observable_interval_ms = static_cast(configuration_->property("GNSS-SDR.observable_interval_ms", 20)); + ch_out_sample_counter = gnss_sdr_make_sample_counter(fs, observable_interval_ms, sig_conditioner_.at(0)->get_right_block()->output_signature()->sizeof_stream_item(0)); top_block_->connect(sig_conditioner_.at(0)->get_right_block(), 0, ch_out_sample_counter, 0); top_block_->connect(ch_out_sample_counter, 0, observables_->get_left_block(), channels_count_); //extra port for the sample counter pulse } @@ -291,21 +293,23 @@ void GNSSFlowgraph::connect() } else { - //create a software-defined 1kHz gnss_synchro pulse for the observables block + //create a hardware-defined gnss_synchro pulse for the observables block try { - //null source - null_source_ = gr::blocks::null_source::make(sizeof(Gnss_Synchro)); - //throttle 1kHz - throttle_ = gr::blocks::throttle::make(sizeof(Gnss_Synchro), 1000); // 1000 samples per second (1kHz) - time_counter_ = gnss_sdr_make_time_counter(); - top_block_->connect(null_source_, 0, throttle_, 0); - top_block_->connect(throttle_, 0, time_counter_, 0); - top_block_->connect(time_counter_, 0, observables_->get_left_block(), channels_count_); + double fs = static_cast(configuration_->property("GNSS-SDR.internal_fs_sps", 0)); + if (fs == 0.0) + { + LOG(WARNING) << "Set GNSS-SDR.internal_fs_sps in configuration file"; + std::cout << "Set GNSS-SDR.internal_fs_sps in configuration file" << std::endl; + throw(std::invalid_argument("Set GNSS-SDR.internal_fs_sps in configuration")); + } + int observable_interval_ms = static_cast(configuration_->property("GNSS-SDR.observable_interval_ms", 20)); + ch_out_fpga_sample_counter = gnss_sdr_make_fpga_sample_counter(fs, observable_interval_ms); + top_block_->connect(ch_out_fpga_sample_counter, 0, observables_->get_left_block(), channels_count_); //extra port for the sample counter pulse } catch (const std::exception& e) { - LOG(WARNING) << "Can't connect sample counter"; + LOG(WARNING) << "Can't connect FPGA sample counter"; LOG(ERROR) << e.what(); top_block_->disconnect_all(); return; @@ -323,7 +327,9 @@ void GNSSFlowgraph::connect() std::cout << "Set GNSS-SDR.internal_fs_sps in configuration file" << std::endl; throw(std::invalid_argument("Set GNSS-SDR.internal_fs_sps in configuration")); } - ch_out_sample_counter = gnss_sdr_make_sample_counter(fs, sig_conditioner_.at(0)->get_right_block()->output_signature()->sizeof_stream_item(0)); + + int observable_interval_ms = static_cast(configuration_->property("GNSS-SDR.observable_interval_ms", 20)); + ch_out_sample_counter = gnss_sdr_make_sample_counter(fs, observable_interval_ms, sig_conditioner_.at(0)->get_right_block()->output_signature()->sizeof_stream_item(0)); top_block_->connect(sig_conditioner_.at(0)->get_right_block(), 0, ch_out_sample_counter, 0); top_block_->connect(ch_out_sample_counter, 0, observables_->get_left_block(), channels_count_); //extra port for the sample counter pulse } @@ -418,7 +424,7 @@ void GNSSFlowgraph::connect() } if (sat == 0) { - channels_.at(i)->set_signal(search_next_signal(gnss_signal, true)); + channels_.at(i)->set_signal(search_next_signal(gnss_signal, false)); } else { @@ -629,13 +635,11 @@ void GNSSFlowgraph::disconnect() { try { - top_block_->disconnect(null_source_, 0, throttle_, 0); - top_block_->disconnect(throttle_, 0, time_counter_, 0); - top_block_->disconnect(time_counter_, 0, observables_->get_left_block(), channels_count_); + top_block_->disconnect(ch_out_fpga_sample_counter, 0, observables_->get_left_block(), channels_count_); } catch (const std::exception& e) { - LOG(WARNING) << "Can't connect sample counter"; + LOG(WARNING) << "Can't connect FPGA sample counter"; LOG(ERROR) << e.what(); top_block_->disconnect_all(); return; @@ -798,8 +802,8 @@ void GNSSFlowgraph::wait() bool GNSSFlowgraph::send_telemetry_msg(pmt::pmt_t msg) { - //push ephemeris to PVT telemetry msg in port using a channel out port - // it uses the first channel as a message produces (it is already connected to PVT) + // Push ephemeris to PVT telemetry msg in port using a channel out port + // it uses the first channel as a message producer (it is already connected to PVT) channels_.at(0)->get_right_block()->message_port_pub(pmt::mp("telemetry"), msg); return true; } @@ -808,56 +812,83 @@ bool GNSSFlowgraph::send_telemetry_msg(pmt::pmt_t msg) /* * Applies an action to the flow graph * - * \param[in] who Who generated the action - * \param[in] what What is the action 0: acquisition failed + * \param[in] who Who generated the action: + * -> 0-199 are the channels IDs + * -> 200 is the control_thread dispatched by the control_thread apply_action + * -> 300 is the telecommand system (TC) for receiver control + * -> 400 - 599 is the TC channel control for channels 0-199 + * \param[in] what What is the action: + * --- actions from channels --- + * -> 0 acquisition failed + * -> 1 acquisition succesfull + * -> 2 tracking lost + * --- actions from TC receiver control --- + * -> 10 TC request standby mode + * -> 11 TC request coldstart + * -> 12 TC request hotstart + * -> 13 TC request warmstart + * --- actions from TC channel control --- + * -> 20 stop channel + * -> 21 start channel */ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) { + std::lock_guard lock(signal_list_mutex); DLOG(INFO) << "Received " << what << " from " << who << ". Number of applied actions = " << applied_actions_; unsigned int sat = 0; - try + if (who < 200) { - sat = configuration_->property("Channel" + std::to_string(who) + ".satellite", 0); + try + { + sat = configuration_->property("Channel" + std::to_string(who) + ".satellite", 0); + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } } - catch (const std::exception& e) - { - LOG(WARNING) << e.what(); - } - std::lock_guard lock(signal_list_mutex); switch (what) { case 0: DLOG(INFO) << "Channel " << who << " ACQ FAILED satellite " << channels_[who]->get_signal().get_satellite() << ", Signal " << channels_[who]->get_signal().get_signal_str(); if (sat == 0) { - switch (mapStringValues_[channels_[who]->get_signal().get_signal_str()]) + Gnss_Signal gs = channels_[who]->get_signal(); + switch (mapStringValues_[gs.get_signal_str()]) { case evGPS_1C: - available_GPS_1C_signals_.push_back(channels_[who]->get_signal()); + available_GPS_1C_signals_.remove(gs); + available_GPS_1C_signals_.push_back(gs); break; case evGPS_2S: - available_GPS_2S_signals_.push_back(channels_[who]->get_signal()); + available_GPS_2S_signals_.remove(gs); + available_GPS_2S_signals_.push_back(gs); break; case evGPS_L5: - available_GPS_L5_signals_.push_back(channels_[who]->get_signal()); + available_GPS_L5_signals_.remove(gs); + available_GPS_L5_signals_.push_back(gs); break; case evGAL_1B: - available_GAL_1B_signals_.push_back(channels_[who]->get_signal()); + available_GAL_1B_signals_.remove(gs); + available_GAL_1B_signals_.push_back(gs); break; case evGAL_5X: - available_GAL_5X_signals_.push_back(channels_[who]->get_signal()); + available_GAL_5X_signals_.remove(gs); + available_GAL_5X_signals_.push_back(gs); break; case evGLO_1G: - available_GLO_1G_signals_.push_back(channels_[who]->get_signal()); + available_GLO_1G_signals_.remove(gs); + available_GLO_1G_signals_.push_back(gs); break; case evGLO_2G: - available_GLO_2G_signals_.push_back(channels_[who]->get_signal()); + available_GLO_2G_signals_.remove(gs); + available_GLO_2G_signals_.push_back(gs); break; default: @@ -896,6 +927,43 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) case 1: LOG(INFO) << "Channel " << who << " ACQ SUCCESS satellite " << channels_[who]->get_signal().get_satellite(); + + // If the satellite is in the list of available ones, remove it. + switch (mapStringValues_[channels_[who]->get_signal().get_signal_str()]) + { + case evGPS_1C: + available_GPS_1C_signals_.remove(channels_[who]->get_signal()); + break; + + case evGPS_2S: + available_GPS_2S_signals_.remove(channels_[who]->get_signal()); + break; + + case evGPS_L5: + available_GPS_L5_signals_.remove(channels_[who]->get_signal()); + break; + + case evGAL_1B: + available_GAL_1B_signals_.remove(channels_[who]->get_signal()); + break; + + case evGAL_5X: + available_GAL_5X_signals_.remove(channels_[who]->get_signal()); + break; + + case evGLO_1G: + available_GLO_1G_signals_.remove(channels_[who]->get_signal()); + break; + + case evGLO_2G: + available_GLO_2G_signals_.remove(channels_[who]->get_signal()); + break; + + default: + LOG(ERROR) << "This should not happen :-("; + break; + } + channels_state_[who] = 2; acq_channels_count_--; for (unsigned int i = 0; i < channels_count_; i++) @@ -978,7 +1046,148 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) } } break; + case 10: // request standby mode + LOG(INFO) << "TC request standby mode"; + for (size_t n = 0; n < channels_.size(); n++) + { + if (channels_state_[n] == 1 or channels_state_[n] == 2) //channel in acquisition or in tracking + { + //recover the satellite assigned + Gnss_Signal gs = channels_[n]->get_signal(); + switch (mapStringValues_[gs.get_signal_str()]) + { + case evGPS_1C: + available_GPS_1C_signals_.remove(gs); + available_GPS_1C_signals_.push_back(gs); + break; + + case evGPS_2S: + available_GPS_2S_signals_.remove(gs); + available_GPS_2S_signals_.push_back(gs); + break; + + case evGPS_L5: + available_GPS_L5_signals_.remove(gs); + available_GPS_L5_signals_.push_back(gs); + break; + + case evGAL_1B: + available_GAL_1B_signals_.remove(gs); + available_GAL_1B_signals_.push_back(gs); + break; + + case evGAL_5X: + available_GAL_5X_signals_.remove(gs); + available_GAL_5X_signals_.push_back(gs); + break; + + case evGLO_1G: + available_GLO_1G_signals_.remove(gs); + available_GLO_1G_signals_.push_back(gs); + break; + + case evGLO_2G: + available_GLO_2G_signals_.remove(gs); + available_GLO_2G_signals_.push_back(gs); + break; + + default: + LOG(ERROR) << "This should not happen :-("; + break; + } + channels_[n]->stop_channel(); //stop the acquisition or tracking operation + channels_state_[n] = 0; + } + } + acq_channels_count_ = 0; // all channels are in standby now + break; + case 11: // request coldstart mode + LOG(INFO) << "TC request flowgraph coldstart"; + //start again the satellite acquisitions + for (unsigned int i = 0; i < channels_count_; i++) + { + unsigned int ch_index = (who + i + 1) % channels_count_; + unsigned int sat_ = 0; + try + { + sat_ = configuration_->property("Channel" + std::to_string(ch_index) + ".satellite", 0); + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } + if ((acq_channels_count_ < max_acq_channels_) && (channels_state_[ch_index] == 0)) + { + channels_state_[ch_index] = 1; + if (sat_ == 0) + { + channels_[ch_index]->set_signal(search_next_signal(channels_[ch_index]->get_signal().get_signal_str(), true)); + } + acq_channels_count_++; + DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str(); + channels_[ch_index]->start_acquisition(); + } + DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index]; + } + break; + case 12: // request hotstart mode + LOG(INFO) << "TC request flowgraph hotstart"; + for (unsigned int i = 0; i < channels_count_; i++) + { + unsigned int ch_index = (who + i + 1) % channels_count_; + unsigned int sat_ = 0; + try + { + sat_ = configuration_->property("Channel" + std::to_string(ch_index) + ".satellite", 0); + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } + if ((acq_channels_count_ < max_acq_channels_) && (channels_state_[ch_index] == 0)) + { + channels_state_[ch_index] = 1; + if (sat_ == 0) + { + channels_[ch_index]->set_signal(search_next_signal(channels_[ch_index]->get_signal().get_signal_str(), true)); + } + acq_channels_count_++; + DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str(); + channels_[ch_index]->start_acquisition(); + } + DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index]; + } + break; + case 13: // request warmstart mode + LOG(INFO) << "TC request flowgraph warmstart"; + //start again the satellite acquisitions + for (unsigned int i = 0; i < channels_count_; i++) + { + unsigned int ch_index = (who + i + 1) % channels_count_; + unsigned int sat_ = 0; + try + { + sat_ = configuration_->property("Channel" + std::to_string(ch_index) + ".satellite", 0); + } + catch (const std::exception& e) + { + LOG(WARNING) << e.what(); + } + if ((acq_channels_count_ < max_acq_channels_) && (channels_state_[ch_index] == 0)) + { + channels_state_[ch_index] = 1; + if (sat_ == 0) + { + channels_[ch_index]->set_signal(search_next_signal(channels_[ch_index]->get_signal().get_signal_str(), true)); + } + acq_channels_count_++; + DLOG(INFO) << "Channel " << ch_index << " Starting acquisition " << channels_[ch_index]->get_signal().get_satellite() << ", Signal " << channels_[ch_index]->get_signal().get_signal_str(); + channels_[ch_index]->start_acquisition(); + } + DLOG(INFO) << "Channel " << ch_index << " in state " << channels_state_[ch_index]; + } + break; default: break; } @@ -986,6 +1195,60 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what) } +void GNSSFlowgraph::priorize_satellites(std::vector> visible_satellites) +{ + size_t old_size; + Gnss_Signal gs; + for (std::vector>::iterator it = visible_satellites.begin(); it != visible_satellites.end(); ++it) + { + if (it->second.get_system() == "GPS") + { + gs = Gnss_Signal(it->second, "1C"); + old_size = available_GPS_1C_signals_.size(); + available_GPS_1C_signals_.remove(gs); + if (old_size > available_GPS_1C_signals_.size()) + { + available_GPS_1C_signals_.push_front(gs); + } + + gs = Gnss_Signal(it->second, "2S"); + old_size = available_GPS_2S_signals_.size(); + available_GPS_2S_signals_.remove(gs); + if (old_size > available_GPS_2S_signals_.size()) + { + available_GPS_2S_signals_.push_front(gs); + } + + gs = Gnss_Signal(it->second, "L5"); + old_size = available_GPS_L5_signals_.size(); + available_GPS_L5_signals_.remove(gs); + if (old_size > available_GPS_L5_signals_.size()) + { + available_GPS_L5_signals_.push_front(gs); + } + } + else if (it->second.get_system() == "Galileo") + { + gs = Gnss_Signal(it->second, "1B"); + old_size = available_GAL_1B_signals_.size(); + available_GAL_1B_signals_.remove(gs); + if (old_size > available_GAL_1B_signals_.size()) + { + available_GAL_1B_signals_.push_front(gs); + } + + gs = Gnss_Signal(it->second, "5X"); + old_size = available_GAL_5X_signals_.size(); + available_GAL_5X_signals_.remove(gs); + if (old_size > available_GAL_5X_signals_.size()) + { + available_GAL_5X_signals_.push_front(gs); + } + } + } +} + + void GNSSFlowgraph::set_configuration(std::shared_ptr configuration) { if (running_) @@ -1117,11 +1380,10 @@ void GNSSFlowgraph::init() */ enable_monitor_ = configuration_->property("Monitor.enable_monitor", false); - std::vector udp_addr_vec; - std::string address_string = configuration_->property("Monitor.client_addresses", std::string("127.0.0.1")); - //todo: split the string in substrings using the separator and fill the address vector. - udp_addr_vec.push_back(address_string); + std::vector udp_addr_vec = split_string(address_string, '_'); + std::sort(udp_addr_vec.begin(), udp_addr_vec.end()); + udp_addr_vec.erase(std::unique(udp_addr_vec.begin(), udp_addr_vec.end()), udp_addr_vec.end()); if (enable_monitor_) { @@ -1143,7 +1405,7 @@ void GNSSFlowgraph::set_signals_list() 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}; - std::set available_sbas_prn = {120, 124, 126}; + std::set available_sbas_prn = {123, 131, 135, 136, 138}; std::set available_galileo_prn = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, @@ -1297,8 +1559,8 @@ void GNSSFlowgraph::set_signals_list() if (configuration_->property("Channels_1G.count", 0) > 0) { // Loop to create the list of GLONASS L1 C/A signals - for (available_gnss_prn_iter = available_glonass_prn.begin(); - available_gnss_prn_iter != available_glonass_prn.end(); + for (available_gnss_prn_iter = available_glonass_prn.cbegin(); + available_gnss_prn_iter != available_glonass_prn.cend(); available_gnss_prn_iter++) { available_GLO_1G_signals_.push_back(Gnss_Signal( @@ -1310,8 +1572,8 @@ void GNSSFlowgraph::set_signals_list() if (configuration_->property("Channels_2G.count", 0) > 0) { // Loop to create the list of GLONASS L2 C/A signals - for (available_gnss_prn_iter = available_glonass_prn.begin(); - available_gnss_prn_iter != available_glonass_prn.end(); + for (available_gnss_prn_iter = available_glonass_prn.cbegin(); + available_gnss_prn_iter != available_glonass_prn.cend(); available_gnss_prn_iter++) { available_GLO_2G_signals_.push_back(Gnss_Signal( @@ -1324,6 +1586,7 @@ void GNSSFlowgraph::set_signals_list() void GNSSFlowgraph::set_channels_state() { + std::lock_guard lock(signal_list_mutex); max_acq_channels_ = configuration_->property("Channels.in_acquisition", channels_count_); if (max_acq_channels_ > channels_count_) { @@ -1343,7 +1606,6 @@ void GNSSFlowgraph::set_channels_state() } DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i]; } - std::lock_guard lock(signal_list_mutex); acq_channels_count_ = max_acq_channels_; DLOG(INFO) << acq_channels_count_ << " channels in acquisition state"; } @@ -1357,9 +1619,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool { case evGPS_1C: result = available_GPS_1C_signals_.front(); - if (pop) + available_GPS_1C_signals_.pop_front(); + if (!pop) { - available_GPS_1C_signals_.pop_front(); + available_GPS_1C_signals_.push_back(result); } if (tracked) { @@ -1387,9 +1650,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool case evGPS_2S: result = available_GPS_2S_signals_.front(); - if (pop) + available_GPS_2S_signals_.pop_front(); + if (!pop) { - available_GPS_2S_signals_.pop_front(); + available_GPS_2S_signals_.push_back(result); } if (tracked) { @@ -1417,9 +1681,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool case evGPS_L5: result = available_GPS_L5_signals_.front(); - if (pop) + available_GPS_L5_signals_.pop_front(); + if (!pop) { - available_GPS_L5_signals_.pop_front(); + available_GPS_L5_signals_.push_back(result); } if (tracked) { @@ -1447,9 +1712,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool case evGAL_1B: result = available_GAL_1B_signals_.front(); - if (pop) + available_GAL_1B_signals_.pop_front(); + if (!pop) { - available_GAL_1B_signals_.pop_front(); + available_GAL_1B_signals_.push_back(result); } if (tracked) { @@ -1471,9 +1737,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool case evGAL_5X: result = available_GAL_5X_signals_.front(); - if (pop) + available_GAL_5X_signals_.pop_front(); + if (!pop) { - available_GAL_5X_signals_.pop_front(); + available_GAL_5X_signals_.push_back(result); } if (tracked) { @@ -1495,9 +1762,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool case evGLO_1G: result = available_GLO_1G_signals_.front(); - if (pop) + available_GLO_1G_signals_.pop_front(); + if (!pop) { - available_GLO_1G_signals_.pop_front(); + available_GLO_1G_signals_.push_back(result); } if (tracked) { @@ -1519,9 +1787,10 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool case evGLO_2G: result = available_GLO_2G_signals_.front(); - if (pop) + available_GLO_2G_signals_.pop_front(); + if (!pop) { - available_GLO_2G_signals_.pop_front(); + available_GLO_2G_signals_.push_back(result); } if (tracked) { @@ -1552,3 +1821,17 @@ Gnss_Signal GNSSFlowgraph::search_next_signal(std::string searched_signal, bool } return result; } + +std::vector GNSSFlowgraph::split_string(const std::string& s, char delim) +{ + std::vector v; + std::stringstream ss(s); + std::string item; + + while (std::getline(ss, item, delim)) + { + *(std::back_inserter(v)++) = item; + } + + return v; +} diff --git a/src/core/receiver/gnss_flowgraph.h b/src/core/receiver/gnss_flowgraph.h index 00a6ced4e..d5e25543a 100644 --- a/src/core/receiver/gnss_flowgraph.h +++ b/src/core/receiver/gnss_flowgraph.h @@ -41,10 +41,13 @@ #include "gnss_signal.h" #include "gnss_sdr_sample_counter.h" #include "gnss_synchro_monitor.h" +#include "gnss_block_interface.h" +#include "pvt_interface.h" +#include "channel_interface.h" +#include "configuration_interface.h" +#include "gnss_block_factory.h" #include #include -#include -#include #include #include #include @@ -54,13 +57,9 @@ #include #if ENABLE_FPGA -#include "gnss_sdr_time_counter.h" +#include "gnss_sdr_fpga_sample_counter.h" #endif -class GNSSBlockInterface; -class ChannelInterface; -class ConfigurationInterface; -class GNSSBlockFactory; /*! \brief This class represents a GNSS flow graph. * @@ -131,6 +130,19 @@ public: */ bool send_telemetry_msg(pmt::pmt_t msg); + /*! + * \brief Returns a smart pointer to the PVT object + */ + std::shared_ptr get_pvt() + { + return std::dynamic_pointer_cast(pvt_); + } + + /*! + * \brief Priorize visible satellites in the specified vector + */ + void priorize_satellites(std::vector> visible_satellites); + private: void init(); // Populates the SV PRN list available for acquisition and tracking void set_signals_list(); @@ -157,10 +169,8 @@ private: std::vector> channels_; gnss_sdr_sample_counter_sptr ch_out_sample_counter; #if ENABLE_FPGA - gnss_sdr_time_counter_sptr time_counter_; + gnss_sdr_fpga_sample_counter_sptr ch_out_fpga_sample_counter; #endif - gr::blocks::null_source::sptr null_source_; - gr::blocks::throttle::sptr throttle_; gr::top_block_sptr top_block_; gr::msg_queue::sptr queue_; @@ -190,6 +200,7 @@ private: bool enable_monitor_; gr::basic_block_sptr GnssSynchroMonitor_; + std::vector split_string(const std::string &s, char delim); }; #endif /*GNSS_SDR_GNSS_FLOWGRAPH_H_*/ diff --git a/src/core/receiver/tcp_cmd_interface.cc b/src/core/receiver/tcp_cmd_interface.cc new file mode 100644 index 000000000..ecb175e5f --- /dev/null +++ b/src/core/receiver/tcp_cmd_interface.cc @@ -0,0 +1,400 @@ +/*! + * \file tcp_cmd_interface.cc + * + * \brief Class that implements a TCP telecontrol command line interface + * for GNSS-SDR + * \author Javier Arribas jarribas (at) cttc.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "tcp_cmd_interface.h" +#include "control_message_factory.h" +#include +#include + + +TcpCmdInterface::TcpCmdInterface() +{ + register_functions(); + keep_running_ = true; + control_queue_ = nullptr; + rx_latitude_ = 0; + rx_longitude_ = 0; + rx_altitude_ = 0; + receiver_utc_time_ = 0; +} + + +TcpCmdInterface::~TcpCmdInterface() +{ +} + + +void TcpCmdInterface::register_functions() +{ + functions["status"] = std::bind(&TcpCmdInterface::status, this, std::placeholders::_1); + functions["standby"] = std::bind(&TcpCmdInterface::standby, this, std::placeholders::_1); + functions["reset"] = std::bind(&TcpCmdInterface::reset, this, std::placeholders::_1); + functions["hotstart"] = std::bind(&TcpCmdInterface::hotstart, this, std::placeholders::_1); + functions["warmstart"] = std::bind(&TcpCmdInterface::warmstart, this, std::placeholders::_1); + functions["coldstart"] = std::bind(&TcpCmdInterface::coldstart, this, std::placeholders::_1); + functions["set_ch_satellite"] = std::bind(&TcpCmdInterface::set_ch_satellite, this, std::placeholders::_1); +} + + +void TcpCmdInterface::set_pvt(std::shared_ptr PVT_sptr) +{ + PVT_sptr_ = PVT_sptr; +} + + +time_t TcpCmdInterface::get_utc_time() +{ + return receiver_utc_time_; +} + + +arma::vec TcpCmdInterface::get_LLH() +{ + return arma::vec{rx_latitude_, rx_longitude_, rx_altitude_}; +} + + +std::string TcpCmdInterface::reset(const std::vector &commandLine __attribute__((unused))) +{ + std::string response; + std::unique_ptr cmf(new ControlMessageFactory()); + if (control_queue_ != nullptr) + { + control_queue_->handle(cmf->GetQueueMessage(200, 1)); //send the restart message (who=200,what=1) + response = "OK\n"; + } + else + { + response = "ERROR\n"; + } + + return response; +} + + +std::string TcpCmdInterface::standby(const std::vector &commandLine __attribute__((unused))) +{ + std::string response; + std::unique_ptr cmf(new ControlMessageFactory()); + if (control_queue_ != nullptr) + { + control_queue_->handle(cmf->GetQueueMessage(300, 10)); //send the standby message (who=300,what=10) + response = "OK\n"; + } + else + { + response = "ERROR\n"; + } + return response; +} + + +std::string TcpCmdInterface::status(const std::vector &commandLine __attribute__((unused))) +{ + std::stringstream str_stream; + //todo: implement the receiver status report + + // str_stream << "-------------------------------------------------------\n"; + // str_stream << "ch | sys | sig | mode | Tlm | Eph | Doppler | CN0 |\n"; + // str_stream << " | | | | | | [Hz] | [dB - Hz] |\n"; + // str_stream << "-------------------------------------------------------\n"; + // int n_ch = 10; + // for (int n = 0; n < n_ch; n++) + // { + // str_stream << n << "GPS | L1CA | TRK | YES | YES | 23412.4 | 44.3 |\n"; + // } + // str_stream << "--------------------------------------------------------\n"; + + double longitude_deg, latitude_deg, height_m, ground_speed_kmh, course_over_ground_deg; + time_t UTC_time; + if (PVT_sptr_->get_latest_PVT(&longitude_deg, + &latitude_deg, + &height_m, + &ground_speed_kmh, + &course_over_ground_deg, + &UTC_time) == true) + { + struct tm tstruct; + char buf1[80]; + tstruct = *gmtime(&UTC_time); + strftime(buf1, sizeof(buf1), "%d/%m/%Y %H:%M:%S", &tstruct); + std::string str_time = std::string(buf1); + str_stream << "- Receiver UTC Time: " << str_time << std::endl; + str_stream << std::setprecision(9); + str_stream << "- Receiver Position WGS84 [Lat, Long, H]: " + << latitude_deg << ", " + << longitude_deg << ", "; + str_stream << std::setprecision(3); + str_stream << height_m << std::endl; + str_stream << std::setprecision(1); + str_stream << "- Receiver Speed over Ground [km/h]: " << ground_speed_kmh << std::endl; + str_stream << "- Receiver Course over ground [deg]: " << course_over_ground_deg << std::endl; + } + else + { + str_stream << "No PVT information available.\n"; + } + + return str_stream.str(); +} + + +std::string TcpCmdInterface::hotstart(const std::vector &commandLine) +{ + std::string response; + if (commandLine.size() > 5) + { + // Read commandline time parameter + struct tm tm; + if (strptime(commandLine.at(1).c_str(), "%d/%m/%Y %H:%M:%S", &tm) == nullptr) + { + response = "ERROR: time parameter malformed\n"; + return response; + } + receiver_utc_time_ = timegm(&tm); + + // Read latitude, longitude, and height + rx_latitude_ = std::stod(commandLine.at(3).c_str()); + rx_longitude_ = std::stod(commandLine.at(4).c_str()); + rx_altitude_ = std::stod(commandLine.at(5).c_str()); + + if (std::isnan(rx_latitude_) || std::isnan(rx_longitude_) || std::isnan(rx_altitude_)) + { + response = "ERROR: position malformed\n"; + } + else + { + std::unique_ptr cmf(new ControlMessageFactory()); + if (control_queue_ != nullptr) + { + control_queue_->handle(cmf->GetQueueMessage(300, 12)); //send the standby message (who=300,what=12) + response = "OK\n"; + } + else + { + response = "ERROR\n"; + } + } + } + else + { + response = "ERROR: time parameter not found, please use hotstart %d/%m/%Y %H:%M:%S Lat Long H\n"; + } + return response; +} + + +std::string TcpCmdInterface::warmstart(const std::vector &commandLine) +{ + std::string response; + if (commandLine.size() > 5) + { + std::string tmp_str; + // Read commandline time parameter + struct tm tm; + tmp_str = commandLine.at(1) + commandLine.at(2); + if (strptime(commandLine.at(1).c_str(), "%d/%m/%Y %H:%M:%S", &tm) == nullptr) + { + response = "ERROR: time parameter malformed\n"; + return response; + } + receiver_utc_time_ = timegm(&tm); + + // Read latitude, longitude, and height + rx_latitude_ = std::stod(commandLine.at(3).c_str()); + rx_longitude_ = std::stod(commandLine.at(4).c_str()); + rx_altitude_ = std::stod(commandLine.at(5).c_str()); + if (std::isnan(rx_latitude_) || std::isnan(rx_longitude_) || std::isnan(rx_altitude_)) + { + response = "ERROR: position malformed\n"; + } + else + { + std::unique_ptr cmf(new ControlMessageFactory()); + if (control_queue_ != nullptr) + { + control_queue_->handle(cmf->GetQueueMessage(300, 13)); // send the warmstart message (who=300,what=13) + response = "OK\n"; + } + else + { + response = "ERROR\n"; + } + } + } + else + { + response = "ERROR: time parameter not found, please use warmstart %d/%m/%Y %H:%M:%S Lat Long H\n"; + } + return response; +} + + +std::string TcpCmdInterface::coldstart(const std::vector &commandLine __attribute__((unused))) +{ + std::string response; + std::unique_ptr cmf(new ControlMessageFactory()); + if (control_queue_ != nullptr) + { + control_queue_->handle(cmf->GetQueueMessage(300, 11)); // send the coldstart message (who=300,what=11) + response = "OK\n"; + } + else + { + response = "ERROR\n"; + } + return response; +} + + +std::string TcpCmdInterface::set_ch_satellite(const std::vector &commandLine __attribute__((unused))) +{ + std::string response; + //todo: implement the set satellite command + response = "Not implemented\n"; + return response; +} + + +void TcpCmdInterface::set_msg_queue(gr::msg_queue::sptr control_queue) +{ + control_queue_ = control_queue; +} + + +void TcpCmdInterface::run_cmd_server(int tcp_port) +{ + // Get the port from the parameters + uint16_t port = tcp_port; + + // Error to not throw exception + boost::system::error_code not_throw; + + // Socket and acceptor + boost::asio::io_service service; + try + { + boost::asio::ip::tcp::acceptor acceptor(service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)); + + while (keep_running_) + { + try + { + std::cout << "TcpCmdInterface: Telecommand TCP interface listening on port " << tcp_port << std::endl; + + boost::asio::ip::tcp::socket socket(service); + acceptor.accept(socket, not_throw); + if (not_throw) + { + std::cout << "TcpCmdInterface: Error when binding the port in the socket" << std::endl; + continue; + } + + // Read a message + boost::system::error_code error = boost::asio::error::eof; + do + { + std::string response; + boost::asio::streambuf b; + boost::asio::read_until(socket, b, '\n', error); + std::istream is(&b); + std::string line; + std::getline(is, line); + std::istringstream iss(line); + std::vector cmd_vector(std::istream_iterator{iss}, + std::istream_iterator()); + + if (cmd_vector.size() > 0) + { + try + { + if (cmd_vector.at(0).compare("exit") == 0) + { + error = boost::asio::error::eof; + // send cmd response + socket.write_some(boost::asio::buffer("OK\n"), not_throw); + } + else + { + response = functions[cmd_vector.at(0)](cmd_vector); + } + } + catch (const std::bad_function_call &ex) + { + response = "ERROR: command not found \n "; + } + catch (const std::exception &ex) + { + response = "ERROR: command execution error: " + std::string(ex.what()) + "\n"; + } + } + else + { + response = "ERROR: empty command\n"; + } + + // send cmd response + socket.write_some(boost::asio::buffer(response), not_throw); + if (not_throw) + { + std::cout << "Error sending(" << not_throw.value() << "): " << not_throw.message() << std::endl; + break; + } + } + while (error != boost::asio::error::eof); + + if (error == boost::asio::error::eof) + { + std::cout << "TcpCmdInterface: EOF detected\n"; + } + else + { + std::cout << "TcpCmdInterface unexpected error: " << error << std::endl; + } + + // Close socket + socket.close(); + } + catch (const boost::exception &e) + { + std::cout << "TcpCmdInterface: Boost exception " << std::endl; + } + catch (const std::exception &ex) + { + std::cout << "TcpCmdInterface: Exception " << ex.what() << std::endl; + } + } + } + catch (const boost::exception &e) + { + std::cout << "TCP Command Interface exception: address already in use" << std::endl; + } +} diff --git a/src/core/receiver/tcp_cmd_interface.h b/src/core/receiver/tcp_cmd_interface.h new file mode 100644 index 000000000..2323e357d --- /dev/null +++ b/src/core/receiver/tcp_cmd_interface.h @@ -0,0 +1,92 @@ +/*! + * \file tcp_cmd_interface.h + * + * \brief Class that implements a TCP telecontrol command line interface + * for GNSS-SDR + * \author Javier Arribas jarribas (at) cttc.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ +#ifndef GNSS_SDR_TCPCMDINTERFACE_H_ +#define GNSS_SDR_TCPCMDINTERFACE_H_ + +#include "pvt_interface.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class TcpCmdInterface +{ +public: + TcpCmdInterface(); + virtual ~TcpCmdInterface(); + void run_cmd_server(int tcp_port); + void set_msg_queue(gr::msg_queue::sptr control_queue); + /*! + * \brief gets the UTC time parsed from the last TC command issued + */ + time_t get_utc_time(); + /*! + * \brief gets the Latitude, Longitude and Altitude vector from the last TC command issued + */ + arma::vec get_LLH(); + + void set_pvt(std::shared_ptr PVT_sptr); + +private: + std::unordered_map &)>> + functions; + std::string status(const std::vector &commandLine); + std::string reset(const std::vector &commandLine); + std::string standby(const std::vector &commandLine); + std::string hotstart(const std::vector &commandLine); + std::string warmstart(const std::vector &commandLine); + std::string coldstart(const std::vector &commandLine); + std::string set_ch_satellite(const std::vector &commandLine); + + void register_functions(); + + gr::msg_queue::sptr control_queue_; + bool keep_running_; + + time_t receiver_utc_time_; + + double rx_latitude_; + double rx_longitude_; + double rx_altitude_; + + std::shared_ptr PVT_sptr_; +}; + +#endif /* GNSS_SDR_TCPCMDINTERFACE_H_ */ diff --git a/src/core/system_parameters/CMakeLists.txt b/src/core/system_parameters/CMakeLists.txt index 2d7c10f23..39f3231fb 100644 --- a/src/core/system_parameters/CMakeLists.txt +++ b/src/core/system_parameters/CMakeLists.txt @@ -16,50 +16,99 @@ # along with GNSS-SDR. If not, see . # + set(SYSTEM_PARAMETERS_SOURCES - gnss_satellite.cc - gnss_signal.cc - gps_navigation_message.cc - gps_ephemeris.cc - gps_iono.cc - gps_almanac.cc - gps_utc_model.cc - gps_acq_assist.cc - gps_ref_time.cc - gps_ref_location.cc - galileo_utc_model.cc - galileo_ephemeris.cc - galileo_almanac.cc - galileo_iono.cc - galileo_navigation_message.cc - sbas_ephemeris.cc - galileo_fnav_message.cc - gps_cnav_ephemeris.cc - gps_cnav_navigation_message.cc - gps_cnav_iono.cc - gps_cnav_utc_model.cc - rtcm.cc - glonass_gnav_ephemeris.cc - glonass_gnav_almanac.cc - glonass_gnav_utc_model.cc - glonass_gnav_navigation_message.cc + gnss_satellite.cc + gnss_signal.cc + gps_navigation_message.cc + gps_ephemeris.cc + gps_iono.cc + gps_almanac.cc + gps_utc_model.cc + gps_acq_assist.cc + agnss_ref_time.cc + agnss_ref_location.cc + galileo_utc_model.cc + galileo_ephemeris.cc + galileo_almanac.cc + galileo_almanac_helper.cc + galileo_iono.cc + galileo_navigation_message.cc + sbas_ephemeris.cc + galileo_fnav_message.cc + gps_cnav_ephemeris.cc + gps_cnav_navigation_message.cc + gps_cnav_iono.cc + gps_cnav_utc_model.cc + rtcm.cc + glonass_gnav_ephemeris.cc + glonass_gnav_almanac.cc + glonass_gnav_utc_model.cc + glonass_gnav_navigation_message.cc ) +set(SYSTEM_PARAMETERS_HEADERS + gnss_satellite.h + gnss_signal.h + gps_navigation_message.h + gps_ephemeris.h + gps_iono.h + gps_almanac.h + gps_utc_model.h + gps_acq_assist.h + agnss_ref_time.h + agnss_ref_location.h + galileo_utc_model.h + galileo_ephemeris.h + galileo_almanac.h + galileo_almanac_helper.h + galileo_iono.h + galileo_navigation_message.h + sbas_ephemeris.h + galileo_fnav_message.h + gps_cnav_ephemeris.h + gps_cnav_navigation_message.h + gps_cnav_iono.h + gps_cnav_utc_model.h + rtcm.h + glonass_gnav_ephemeris.h + glonass_gnav_almanac.h + glonass_gnav_utc_model.h + glonass_gnav_navigation_message.h + display.h + Galileo_E1.h + Galileo_E5a.h + GLONASS_L1_L2_CA.h + gnss_frequencies.h + gnss_obs_codes.h + gnss_synchro.h + GPS_CNAV.h + GPS_L1_CA.h + GPS_L2C.h + GPS_L5.h + MATH_CONSTANTS.h +) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib - ${GLOG_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib + ${GLOG_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} ) -link_directories(${Boost_LIBRARY_DIR}) -file(GLOB SYSTEM_PARAMETERS_HEADERS "*.h") list(SORT SYSTEM_PARAMETERS_HEADERS) -add_library(gnss_system_parameters ${SYSTEM_PARAMETERS_SOURCES} ${SYSTEM_PARAMETERS_HEADERS}) +list(SORT SYSTEM_PARAMETERS_SOURCES) + +add_library(gnss_system_parameters + ${SYSTEM_PARAMETERS_SOURCES} + ${SYSTEM_PARAMETERS_HEADERS} +) + source_group(Headers FILES ${SYSTEM_PARAMETERS_HEADERS}) + add_dependencies(gnss_system_parameters rtklib_lib glog-${glog_RELEASE}) + target_link_libraries(gnss_system_parameters rtklib_lib ${Boost_LIBRARIES}) diff --git a/src/core/system_parameters/GLONASS_L1_L2_CA.h b/src/core/system_parameters/GLONASS_L1_L2_CA.h index be2564d57..27a7425d8 100644 --- a/src/core/system_parameters/GLONASS_L1_L2_CA.h +++ b/src/core/system_parameters/GLONASS_L1_L2_CA.h @@ -35,6 +35,7 @@ #include "gnss_frequencies.h" #include "MATH_CONSTANTS.h" +#include #include #include #include // std::pair @@ -96,7 +97,7 @@ const double GLONASS_L1_CA_CODE_PERIOD = 0.001; //!< GLONASS L1 C/A code const double GLONASS_L1_CA_CHIP_PERIOD = 1.9569e-06; //!< GLONASS L1 C/A chip period [seconds] const double GLONASS_L1_CA_SYMBOL_RATE_BPS = 1000; -const int GLONASS_CA_NBR_SATS = 24; // STRING DATA WITHOUT PREAMBLE +const int32_t GLONASS_CA_NBR_SATS = 24; // STRING DATA WITHOUT PREAMBLE /*! * \brief Record of leap seconds definition for GLOT to GPST conversion and vice versa @@ -125,7 +126,7 @@ const double GLONASS_LEAP_SECONDS[19][7] = { {}}; //!< GLONASS SV's orbital slots PRN = (orbital_slot - 1) -const std::map GLONASS_PRN = { +const std::map GLONASS_PRN = { { 0, 8, @@ -227,7 +228,7 @@ const std::map GLONASS_PRN = { const double GLONASS_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here) // OBSERVABLE HISTORY DEEP FOR INTERPOLATION -const int GLONASS_L1_CA_HISTORY_DEEP = 100; +const int32_t GLONASS_L1_CA_HISTORY_DEEP = 100; // NAVIGATION MESSAGE DEMODULATION AND DECODING #define GLONASS_GNAV_PREAMBLE \ @@ -235,96 +236,96 @@ const int GLONASS_L1_CA_HISTORY_DEEP = 100; 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0 \ } const double GLONASS_GNAV_PREAMBLE_DURATION_S = 0.300; -const int GLONASS_GNAV_PREAMBLE_LENGTH_BITS = 30; -const int GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS = 300; -const int GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS = 2000; -const int GLONASS_GNAV_TELEMETRY_RATE_BITS_SECOND = 50; //!< NAV message bit rate [bits/s] -const int GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_BIT = 10; -const int GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_PREAMBLE_BIT = 10; -const int GLONASS_GNAV_TELEMETRY_RATE_SYMBOLS_SECOND = GLONASS_GNAV_TELEMETRY_RATE_BITS_SECOND * GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_BIT; //!< NAV message bit rate [symbols/s] -const int GLONASS_GNAV_STRING_SYMBOLS = 2000; //!< Number of bits per string in the GNAV message (85 data bits + 30 time mark bits) [bits] -const int GLONASS_GNAV_STRING_BITS = 85; //!< Number of bits per string in the GNAV message (85 data bits + 30 time mark bits) [bits] -const int GLONASS_GNAV_HAMMING_CODE_BITS = 8; //!< Number of bits in hamming code sequence of GNAV message -const int GLONASS_GNAV_DATA_SYMBOLS = 1700; // STRING DATA WITHOUT PREAMBLE +const int32_t GLONASS_GNAV_PREAMBLE_LENGTH_BITS = 30; +const int32_t GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS = 300; +const int32_t GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS = 2000; +const int32_t GLONASS_GNAV_TELEMETRY_RATE_BITS_SECOND = 50; //!< NAV message bit rate [bits/s] +const int32_t GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_BIT = 10; +const int32_t GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_PREAMBLE_BIT = 10; +const int32_t GLONASS_GNAV_TELEMETRY_RATE_SYMBOLS_SECOND = GLONASS_GNAV_TELEMETRY_RATE_BITS_SECOND * GLONASS_GNAV_TELEMETRY_SYMBOLS_PER_BIT; //!< NAV message bit rate [symbols/s] +const int32_t GLONASS_GNAV_STRING_SYMBOLS = 2000; //!< Number of bits per string in the GNAV message (85 data bits + 30 time mark bits) [bits] +const int32_t GLONASS_GNAV_STRING_BITS = 85; //!< Number of bits per string in the GNAV message (85 data bits + 30 time mark bits) [bits] +const int32_t GLONASS_GNAV_HAMMING_CODE_BITS = 8; //!< Number of bits in hamming code sequence of GNAV message +const int32_t GLONASS_GNAV_DATA_SYMBOLS = 1700; // STRING DATA WITHOUT PREAMBLE -const std::vector GLONASS_GNAV_CRC_I_INDEX{9, 10, 12, 13, 15, 17, 19, 20, 22, 24, 26, 28, 30, 32, 34, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84}; -const std::vector GLONASS_GNAV_CRC_J_INDEX{9, 11, 12, 14, 15, 18, 19, 21, 22, 25, 26, 29, 30, 33, 34, 36, 37, 40, 41, 44, 45, 48, 49, 52, 53, 56, 57, 60, 61, 64, 65, 67, 68, 71, 72, 75, 76, 79, 80, 83, 84}; -const std::vector GLONASS_GNAV_CRC_K_INDEX{10, 11, 12, 16, 17, 18, 19, 23, 24, 25, 26, 31, 32, 33, 34, 38, 39, 40, 41, 46, 47, 48, 49, 54, 55, 56, 57, 62, 63, 64, 65, 69, 70, 71, 72, 77, 78, 79, 80, 85}; -const std::vector GLONASS_GNAV_CRC_L_INDEX{13, 14, 15, 16, 17, 18, 19, 27, 28, 29, 30, 31, 32, 33, 34, 42, 43, 44, 45, 46, 47, 48, 49, 58, 59, 60, 61, 62, 63, 64, 65, 73, 74, 75, 76, 77, 78, 79, 80}; -const std::vector GLONASS_GNAV_CRC_M_INDEX{20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 81, 82, 83, 84, 85}; -const std::vector GLONASS_GNAV_CRC_N_INDEX{35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65}; -const std::vector GLONASS_GNAV_CRC_P_INDEX{66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85}; -const std::vector GLONASS_GNAV_CRC_Q_INDEX{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85}; +const std::vector GLONASS_GNAV_CRC_I_INDEX{9, 10, 12, 13, 15, 17, 19, 20, 22, 24, 26, 28, 30, 32, 34, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84}; +const std::vector GLONASS_GNAV_CRC_J_INDEX{9, 11, 12, 14, 15, 18, 19, 21, 22, 25, 26, 29, 30, 33, 34, 36, 37, 40, 41, 44, 45, 48, 49, 52, 53, 56, 57, 60, 61, 64, 65, 67, 68, 71, 72, 75, 76, 79, 80, 83, 84}; +const std::vector GLONASS_GNAV_CRC_K_INDEX{10, 11, 12, 16, 17, 18, 19, 23, 24, 25, 26, 31, 32, 33, 34, 38, 39, 40, 41, 46, 47, 48, 49, 54, 55, 56, 57, 62, 63, 64, 65, 69, 70, 71, 72, 77, 78, 79, 80, 85}; +const std::vector GLONASS_GNAV_CRC_L_INDEX{13, 14, 15, 16, 17, 18, 19, 27, 28, 29, 30, 31, 32, 33, 34, 42, 43, 44, 45, 46, 47, 48, 49, 58, 59, 60, 61, 62, 63, 64, 65, 73, 74, 75, 76, 77, 78, 79, 80}; +const std::vector GLONASS_GNAV_CRC_M_INDEX{20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 81, 82, 83, 84, 85}; +const std::vector GLONASS_GNAV_CRC_N_INDEX{35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65}; +const std::vector GLONASS_GNAV_CRC_P_INDEX{66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85}; +const std::vector GLONASS_GNAV_CRC_Q_INDEX{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85}; // GLONASS GNAV NAVIGATION MESSAGE STRUCTURE // NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200E Appendix II) // FRAME 1-4 // COMMON FIELDS -const std::vector> STRING_ID({{2, 4}}); -const std::vector> KX({{78, 8}}); +const std::vector> STRING_ID({{2, 4}}); +const std::vector> KX({{78, 8}}); //STRING 1 -const std::vector> P1({{8, 2}}); -const std::vector> T_K_HR({{10, 5}}); -const std::vector> T_K_MIN({{15, 6}}); -const std::vector> T_K_SEC({{21, 1}}); -const std::vector> X_N_DOT({{22, 24}}); -const std::vector> X_N_DOT_DOT({{46, 5}}); -const std::vector> X_N({{51, 27}}); +const std::vector> P1({{8, 2}}); +const std::vector> T_K_HR({{10, 5}}); +const std::vector> T_K_MIN({{15, 6}}); +const std::vector> T_K_SEC({{21, 1}}); +const std::vector> X_N_DOT({{22, 24}}); +const std::vector> X_N_DOT_DOT({{46, 5}}); +const std::vector> X_N({{51, 27}}); //STRING 2 -const std::vector> B_N({{6, 3}}); -const std::vector> P2({{9, 1}}); -const std::vector> T_B({{10, 7}}); -const std::vector> Y_N_DOT({{22, 24}}); -const std::vector> Y_N_DOT_DOT({{46, 5}}); -const std::vector> Y_N({{51, 27}}); +const std::vector> B_N({{6, 3}}); +const std::vector> P2({{9, 1}}); +const std::vector> T_B({{10, 7}}); +const std::vector> Y_N_DOT({{22, 24}}); +const std::vector> Y_N_DOT_DOT({{46, 5}}); +const std::vector> Y_N({{51, 27}}); //STRING 3 -const std::vector> P3({{6, 1}}); -const std::vector> GAMMA_N({{7, 11}}); -const std::vector> P({{19, 2}}); -const std::vector> EPH_L_N({{21, 1}}); -const std::vector> Z_N_DOT({{22, 24}}); -const std::vector> Z_N_DOT_DOT({{46, 5}}); -const std::vector> Z_N({{51, 27}}); +const std::vector> P3({{6, 1}}); +const std::vector> GAMMA_N({{7, 11}}); +const std::vector> P({{19, 2}}); +const std::vector> EPH_L_N({{21, 1}}); +const std::vector> Z_N_DOT({{22, 24}}); +const std::vector> Z_N_DOT_DOT({{46, 5}}); +const std::vector> Z_N({{51, 27}}); // STRING 4 -const std::vector> TAU_N({{6, 22}}); -const std::vector> DELTA_TAU_N({{28, 5}}); -const std::vector> E_N({{33, 5}}); -const std::vector> P4({{52, 1}}); -const std::vector> F_T({{53, 4}}); -const std::vector> N_T({{60, 11}}); -const std::vector> N({{71, 5}}); -const std::vector> M({{76, 2}}); +const std::vector> TAU_N({{6, 22}}); +const std::vector> DELTA_TAU_N({{28, 5}}); +const std::vector> E_N({{33, 5}}); +const std::vector> P4({{52, 1}}); +const std::vector> F_T({{53, 4}}); +const std::vector> N_T({{60, 11}}); +const std::vector> N({{71, 5}}); +const std::vector> M({{76, 2}}); // STRING 5 -const std::vector> N_A({{6, 11}}); -const std::vector> TAU_C({{17, 32}}); -const std::vector> N_4({{50, 5}}); -const std::vector> TAU_GPS({{55, 22}}); -const std::vector> ALM_L_N({{77, 1}}); +const std::vector> N_A({{6, 11}}); +const std::vector> TAU_C({{17, 32}}); +const std::vector> N_4({{50, 5}}); +const std::vector> TAU_GPS({{55, 22}}); +const std::vector> ALM_L_N({{77, 1}}); // STRING 6, 8, 10, 12, 14 -const std::vector> C_N({{6, 1}}); -const std::vector> M_N_A({{7, 2}}); -const std::vector> n_A({{9, 5}}); -const std::vector> TAU_N_A({{14, 10}}); -const std::vector> LAMBDA_N_A({{24, 21}}); -const std::vector> DELTA_I_N_A({{45, 18}}); -const std::vector> EPSILON_N_A({{63, 15}}); +const std::vector> C_N({{6, 1}}); +const std::vector> M_N_A({{7, 2}}); +const std::vector> n_A({{9, 5}}); +const std::vector> TAU_N_A({{14, 10}}); +const std::vector> LAMBDA_N_A({{24, 21}}); +const std::vector> DELTA_I_N_A({{45, 18}}); +const std::vector> EPSILON_N_A({{63, 15}}); //STRING 7, 9, 11, 13, 15 -const std::vector> OMEGA_N_A({{6, 16}}); -const std::vector> T_LAMBDA_N_A({{22, 21}}); -const std::vector> DELTA_T_N_A({{43, 22}}); -const std::vector> DELTA_T_DOT_N_A({{65, 7}}); -const std::vector> H_N_A({{72, 5}}); +const std::vector> OMEGA_N_A({{6, 16}}); +const std::vector> T_LAMBDA_N_A({{22, 21}}); +const std::vector> DELTA_T_N_A({{43, 22}}); +const std::vector> DELTA_T_DOT_N_A({{65, 7}}); +const std::vector> H_N_A({{72, 5}}); // STRING 14 FRAME 5 -const std::vector> B1({{6, 11}}); -const std::vector> B2({{17, 10}}); +const std::vector> B1({{6, 11}}); +const std::vector> B2({{17, 10}}); #endif /* GNSS_SDR_GLONASS_L1_L2_CA_H_ */ diff --git a/src/core/system_parameters/GPS_CNAV.h b/src/core/system_parameters/GPS_CNAV.h index 343ab3f5c..2fbad6e2d 100644 --- a/src/core/system_parameters/GPS_CNAV.h +++ b/src/core/system_parameters/GPS_CNAV.h @@ -48,135 +48,135 @@ #define GPS_CNAV_PREAMBLE_STR "10001011" #define GPS_CNAV_INV_PREAMBLE_STR "01110100" -const int GPS_CNAV_DATA_PAGE_BITS = 300; +const int32_t GPS_CNAV_DATA_PAGE_BITS = 300; // common to all messages -const std::vector > CNAV_PRN({{9, 6}}); -const std::vector > CNAV_MSG_TYPE({{15, 6}}); -const std::vector > CNAV_TOW({{21, 17}}); //GPS Time Of Week in seconds +const std::vector > CNAV_PRN({{9, 6}}); +const std::vector > CNAV_MSG_TYPE({{15, 6}}); +const std::vector > CNAV_TOW({{21, 17}}); // GPS Time Of Week in seconds const double CNAV_TOW_LSB = 6.0; -const std::vector > CNAV_ALERT_FLAG({{38, 1}}); +const std::vector > CNAV_ALERT_FLAG({{38, 1}}); // MESSAGE TYPE 10 (Ephemeris 1) -const std::vector > CNAV_WN({{39, 13}}); -const std::vector > CNAV_HEALTH({{52, 3}}); -const std::vector > CNAV_TOP1({{55, 11}}); +const std::vector > CNAV_WN({{39, 13}}); +const std::vector > CNAV_HEALTH({{52, 3}}); +const std::vector > CNAV_TOP1({{55, 11}}); const double CNAV_TOP1_LSB = 300.0; -const std::vector > CNAV_URA({{66, 5}}); +const std::vector > CNAV_URA({{66, 5}}); -const std::vector > CNAV_TOE1({{71, 11}}); +const std::vector > CNAV_TOE1({{71, 11}}); const double CNAV_TOE1_LSB = 300.0; -const std::vector > CNAV_DELTA_A({{82, 26}}); //Relative to AREF = 26,559,710 meters +const std::vector > CNAV_DELTA_A({{82, 26}}); // Relative to AREF = 26,559,710 meters const double CNAV_DELTA_A_LSB = TWO_N9; -const std::vector > CNAV_A_DOT({{108, 25}}); +const std::vector > CNAV_A_DOT({{108, 25}}); const double CNAV_A_DOT_LSB = TWO_N21; -const std::vector > CNAV_DELTA_N0({{133, 17}}); -const double CNAV_DELTA_N0_LSB = TWO_N44 * PI; //semi-circles to radians -const std::vector > CNAV_DELTA_N0_DOT({{150, 23}}); +const std::vector > CNAV_DELTA_N0({{133, 17}}); +const double CNAV_DELTA_N0_LSB = TWO_N44 * PI; // semi-circles to radians +const std::vector > CNAV_DELTA_N0_DOT({{150, 23}}); const double CNAV_DELTA_N0_DOT_LSB = TWO_N57 * PI; //semi-circles to radians -const std::vector > CNAV_M0({{173, 33}}); -const double CNAV_M0_LSB = TWO_N32 * PI; //semi-circles to radians -const std::vector > CNAV_E_ECCENTRICITY({{206, 33}}); +const std::vector > CNAV_M0({{173, 33}}); +const double CNAV_M0_LSB = TWO_N32 * PI; // semi-circles to radians +const std::vector > CNAV_E_ECCENTRICITY({{206, 33}}); const double CNAV_E_ECCENTRICITY_LSB = TWO_N34; -const std::vector > CNAV_OMEGA({{239, 33}}); -const double CNAV_OMEGA_LSB = TWO_N32 * PI; //semi-circles to radians -const std::vector > CNAV_INTEGRITY_FLAG({{272, 1}}); -const std::vector > CNAV_L2_PHASING_FLAG({{273, 1}}); +const std::vector > CNAV_OMEGA({{239, 33}}); +const double CNAV_OMEGA_LSB = TWO_N32 * PI; // semi-circles to radians +const std::vector > CNAV_INTEGRITY_FLAG({{272, 1}}); +const std::vector > CNAV_L2_PHASING_FLAG({{273, 1}}); // MESSAGE TYPE 11 (Ephemeris 2) -const std::vector > CNAV_TOE2({{39, 11}}); +const std::vector > CNAV_TOE2({{39, 11}}); const double CNAV_TOE2_LSB = 300.0; -const std::vector > CNAV_OMEGA0({{50, 33}}); -const double CNAV_OMEGA0_LSB = TWO_N32 * PI; //semi-circles to radians -const std::vector > CNAV_I0({{83, 33}}); -const double CNAV_I0_LSB = TWO_N32 * PI; //semi-circles to radians -const std::vector > CNAV_DELTA_OMEGA_DOT({{116, 17}}); //Relative to REF = -2.6 x 10-9 semi-circles/second. -const double CNAV_DELTA_OMEGA_DOT_LSB = TWO_N44 * PI; //semi-circles to radians -const std::vector > CNAV_I0_DOT({{133, 15}}); -const double CNAV_I0_DOT_LSB = TWO_N44 * PI; //semi-circles to radians -const std::vector > CNAV_CIS({{148, 16}}); +const std::vector > CNAV_OMEGA0({{50, 33}}); +const double CNAV_OMEGA0_LSB = TWO_N32 * PI; // semi-circles to radians +const std::vector > CNAV_I0({{83, 33}}); +const double CNAV_I0_LSB = TWO_N32 * PI; // semi-circles to radians +const std::vector > CNAV_DELTA_OMEGA_DOT({{116, 17}}); // Relative to REF = -2.6 x 10-9 semi-circles/second. +const double CNAV_DELTA_OMEGA_DOT_LSB = TWO_N44 * PI; // semi-circles to radians +const std::vector > CNAV_I0_DOT({{133, 15}}); +const double CNAV_I0_DOT_LSB = TWO_N44 * PI; // semi-circles to radians +const std::vector > CNAV_CIS({{148, 16}}); const double CNAV_CIS_LSB = TWO_N30; -const std::vector > CNAV_CIC({{164, 16}}); +const std::vector > CNAV_CIC({{164, 16}}); const double CNAV_CIC_LSB = TWO_N30; -const std::vector > CNAV_CRS({{180, 24}}); +const std::vector > CNAV_CRS({{180, 24}}); const double CNAV_CRS_LSB = TWO_N8; -const std::vector > CNAV_CRC({{204, 24}}); +const std::vector > CNAV_CRC({{204, 24}}); const double CNAV_CRC_LSB = TWO_N8; -const std::vector > CNAV_CUS({{228, 21}}); +const std::vector > CNAV_CUS({{228, 21}}); const double CNAV_CUS_LSB = TWO_N30; -const std::vector > CNAV_CUC({{249, 21}}); +const std::vector > CNAV_CUC({{249, 21}}); const double CNAV_CUC_LSB = TWO_N30; // MESSAGE TYPE 30 (CLOCK, IONO, GRUP DELAY) -const std::vector > CNAV_TOP2({{39, 11}}); +const std::vector > CNAV_TOP2({{39, 11}}); const double CNAV_TOP2_LSB = 300.0; -const std::vector > CNAV_URA_NED0({{50, 5}}); -const std::vector > CNAV_URA_NED1({{55, 3}}); -const std::vector > CNAV_URA_NED2({{58, 3}}); -const std::vector > CNAV_TOC({{61, 11}}); +const std::vector > CNAV_URA_NED0({{50, 5}}); +const std::vector > CNAV_URA_NED1({{55, 3}}); +const std::vector > CNAV_URA_NED2({{58, 3}}); +const std::vector > CNAV_TOC({{61, 11}}); const double CNAV_TOC_LSB = 300.0; -const std::vector > CNAV_AF0({{72,26}}); +const std::vector > CNAV_AF0({{72, 26}}); const double CNAV_AF0_LSB = TWO_N35; -const std::vector > CNAV_AF1({{98,20}}); +const std::vector > CNAV_AF1({{98, 20}}); const double CNAV_AF1_LSB = TWO_N48; -const std::vector > CNAV_AF2({{118,10}}); +const std::vector > CNAV_AF2({{118, 10}}); const double CNAV_AF2_LSB = TWO_N60; -const std::vector > CNAV_TGD({{128,13}}); +const std::vector > CNAV_TGD({{128, 13}}); const double CNAV_TGD_LSB = TWO_N35; -const std::vector > CNAV_ISCL1({{141, 13}}); +const std::vector > CNAV_ISCL1({{141, 13}}); const double CNAV_ISCL1_LSB = TWO_N35; -const std::vector > CNAV_ISCL2({{154, 13}}); +const std::vector > CNAV_ISCL2({{154, 13}}); const double CNAV_ISCL2_LSB = TWO_N35; -const std::vector > CNAV_ISCL5I({{167, 13}}); +const std::vector > CNAV_ISCL5I({{167, 13}}); const double CNAV_ISCL5I_LSB = TWO_N35; -const std::vector > CNAV_ISCL5Q({{180, 13}}); +const std::vector > CNAV_ISCL5Q({{180, 13}}); const double CNAV_ISCL5Q_LSB = TWO_N35; -//Ionospheric parameters -const std::vector > CNAV_ALPHA0({{193, 8}}); +// Ionospheric parameters +const std::vector > CNAV_ALPHA0({{193, 8}}); const double CNAV_ALPHA0_LSB = TWO_N30; -const std::vector > CNAV_ALPHA1({{201, 8}}); +const std::vector > CNAV_ALPHA1({{201, 8}}); const double CNAV_ALPHA1_LSB = TWO_N27; -const std::vector > CNAV_ALPHA2({{209, 8}}); +const std::vector > CNAV_ALPHA2({{209, 8}}); const double CNAV_ALPHA2_LSB = TWO_N24; -const std::vector > CNAV_ALPHA3({{217, 8}}); +const std::vector > CNAV_ALPHA3({{217, 8}}); const double CNAV_ALPHA3_LSB = TWO_N24; -const std::vector > CNAV_BETA0({{225, 8}}); +const std::vector > CNAV_BETA0({{225, 8}}); const double CNAV_BETA0_LSB = TWO_P11; -const std::vector > CNAV_BETA1({{233, 8}}); +const std::vector > CNAV_BETA1({{233, 8}}); const double CNAV_BETA1_LSB = TWO_P14; -const std::vector > CNAV_BETA2({{241, 8}}); +const std::vector > CNAV_BETA2({{241, 8}}); const double CNAV_BETA2_LSB = TWO_P16; -const std::vector > CNAV_BETA3({{249, 8}}); +const std::vector > CNAV_BETA3({{249, 8}}); const double CNAV_BETA3_LSB = TWO_P16; -const std::vector > CNAV_WNOP({{257, 8}}); +const std::vector > CNAV_WNOP({{257, 8}}); // MESSAGE TYPE 33 (CLOCK and UTC) -const std::vector > CNAV_A0({{128, 16}}); +const std::vector > CNAV_A0({{128, 16}}); const double CNAV_A0_LSB = TWO_N35; -const std::vector > CNAV_A1({{144, 13}}); +const std::vector > CNAV_A1({{144, 13}}); const double CNAV_A1_LSB = TWO_N51; -const std::vector > CNAV_A2({{157, 7}}); +const std::vector > CNAV_A2({{157, 7}}); const double CNAV_A2_LSB = TWO_N68; -const std::vector > CNAV_DELTA_TLS({{164, 8}}); +const std::vector > CNAV_DELTA_TLS({{164, 8}}); const double CNAV_DELTA_TLS_LSB = 1; -const std::vector > CNAV_TOT({{172, 16}}); +const std::vector > CNAV_TOT({{172, 16}}); const double CNAV_TOT_LSB = TWO_P4; -const std::vector > CNAV_WN_OT({{188, 13}}); +const std::vector > CNAV_WN_OT({{188, 13}}); const double CNAV_WN_OT_LSB = 1; -const std::vector > CNAV_WN_LSF({{201, 13}}); +const std::vector > CNAV_WN_LSF({{201, 13}}); const double CNAV_WN_LSF_LSB = 1; -const std::vector > CNAV_DN({{214, 4}}); +const std::vector > CNAV_DN({{214, 4}}); const double CNAV_DN_LSB = 1; -const std::vector > CNAV_DELTA_TLSF({{218, 8}}); +const std::vector > CNAV_DELTA_TLSF({{218, 8}}); const double CNAV_DELTA_TLSF_LSB = 1; diff --git a/src/core/system_parameters/GPS_L1_CA.h b/src/core/system_parameters/GPS_L1_CA.h index be6192795..e3a3871f7 100644 --- a/src/core/system_parameters/GPS_L1_CA.h +++ b/src/core/system_parameters/GPS_L1_CA.h @@ -34,6 +34,7 @@ #include "gnss_frequencies.h" #include "MATH_CONSTANTS.h" +#include #include #include // std::pair @@ -53,7 +54,7 @@ const double GPS_L1_FREQ_HZ = FREQ1; //!< L1 [Hz] const double GPS_L1_CA_CODE_RATE_HZ = 1.023e6; //!< GPS L1 C/A code rate [chips/s] const double GPS_L1_CA_CODE_LENGTH_CHIPS = 1023.0; //!< GPS L1 C/A code length [chips] const double GPS_L1_CA_CODE_PERIOD = 0.001; //!< GPS L1 C/A code period [seconds] -const unsigned int GPS_L1_CA_CODE_PERIOD_MS = 1; //!< GPS L1 C/A code period [ms] +const uint32_t GPS_L1_CA_CODE_PERIOD_MS = 1U; //!< GPS L1 C/A code period [ms] const double GPS_L1_CA_CHIP_PERIOD = 9.7752e-07; //!< GPS L1 C/A chip period [seconds] /*! @@ -68,10 +69,10 @@ const double MAX_TOA_DELAY_MS = 20; //#define NAVIGATION_SOLUTION_RATE_MS 1000 // this cannot go here //const double GPS_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here) -const double GPS_STARTOFFSET_ms = 69.0; +const double GPS_STARTOFFSET_ms = 60.0; // OBSERVABLE HISTORY DEEP FOR INTERPOLATION -const int GPS_L1_CA_HISTORY_DEEP = 100; +const int32_t GPS_L1_CA_HISTORY_DEEP = 100; // NAVIGATION MESSAGE DEMODULATION AND DECODING @@ -79,172 +80,172 @@ const int GPS_L1_CA_HISTORY_DEEP = 100; { \ 1, 0, 0, 0, 1, 0, 1, 1 \ } -const int GPS_CA_PREAMBLE_LENGTH_BITS = 8; -const int GPS_CA_PREAMBLE_LENGTH_SYMBOLS = 160; +const int32_t GPS_CA_PREAMBLE_LENGTH_BITS = 8; +const int32_t GPS_CA_PREAMBLE_LENGTH_SYMBOLS = 160; const double GPS_CA_PREAMBLE_DURATION_S = 0.160; -const int GPS_CA_PREAMBLE_DURATION_MS = 160; -const int GPS_CA_TELEMETRY_RATE_BITS_SECOND = 50; //!< NAV message bit rate [bits/s] -const int GPS_CA_TELEMETRY_SYMBOLS_PER_BIT = 20; -const int GPS_CA_TELEMETRY_RATE_SYMBOLS_SECOND = GPS_CA_TELEMETRY_RATE_BITS_SECOND * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; //!< NAV message bit rate [symbols/s] -const int GPS_WORD_LENGTH = 4; //!< CRC + GPS WORD (-2 -1 0 ... 29) Bits = 4 bytes -const int GPS_SUBFRAME_LENGTH = 40; //!< GPS_WORD_LENGTH x 10 = 40 bytes -const int GPS_SUBFRAME_BITS = 300; //!< Number of bits per subframe in the NAV message [bits] -const int GPS_SUBFRAME_SECONDS = 6; //!< Subframe duration [seconds] -const int GPS_SUBFRAME_MS = 6000; //!< Subframe duration [seconds] -const int GPS_WORD_BITS = 30; //!< Number of bits per word in the NAV message [bits] +const int32_t GPS_CA_PREAMBLE_DURATION_MS = 160; +const int32_t GPS_CA_TELEMETRY_RATE_BITS_SECOND = 50; //!< NAV message bit rate [bits/s] +const int32_t GPS_CA_TELEMETRY_SYMBOLS_PER_BIT = 20; +const int32_t GPS_CA_TELEMETRY_RATE_SYMBOLS_SECOND = GPS_CA_TELEMETRY_RATE_BITS_SECOND * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; //!< NAV message bit rate [symbols/s] +const int32_t GPS_WORD_LENGTH = 4; //!< CRC + GPS WORD (-2 -1 0 ... 29) Bits = 4 bytes +const int32_t GPS_SUBFRAME_LENGTH = 40; //!< GPS_WORD_LENGTH x 10 = 40 bytes +const int32_t GPS_SUBFRAME_BITS = 300; //!< Number of bits per subframe in the NAV message [bits] +const int32_t GPS_SUBFRAME_SECONDS = 6; //!< Subframe duration [seconds] +const int32_t GPS_SUBFRAME_MS = 6000; //!< Subframe duration [seconds] +const int32_t GPS_WORD_BITS = 30; //!< Number of bits per word in the NAV message [bits] // GPS NAVIGATION MESSAGE STRUCTURE // NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200E Appendix II) // SUBFRAME 1-5 (TLM and HOW) -const std::vector> TOW({{31, 17}}); -const std::vector> INTEGRITY_STATUS_FLAG({{23, 1}}); -const std::vector> ALERT_FLAG({{48, 1}}); -const std::vector> ANTI_SPOOFING_FLAG({{49, 1}}); -const std::vector> SUBFRAME_ID({{50, 3}}); +const std::vector> TOW({{31, 17}}); +const std::vector> INTEGRITY_STATUS_FLAG({{23, 1}}); +const std::vector> ALERT_FLAG({{48, 1}}); +const std::vector> ANTI_SPOOFING_FLAG({{49, 1}}); +const std::vector> SUBFRAME_ID({{50, 3}}); // SUBFRAME 1 -const std::vector> GPS_WEEK({{61, 10}}); -const std::vector> CA_OR_P_ON_L2({{71, 2}}); //* -const std::vector> SV_ACCURACY({{73, 4}}); -const std::vector> SV_HEALTH({{77, 6}}); -const std::vector> L2_P_DATA_FLAG({{91, 1}}); -const std::vector> T_GD({{197, 8}}); +const std::vector> GPS_WEEK({{61, 10}}); +const std::vector> CA_OR_P_ON_L2({{71, 2}}); //* +const std::vector> SV_ACCURACY({{73, 4}}); +const std::vector> SV_HEALTH({{77, 6}}); +const std::vector> L2_P_DATA_FLAG({{91, 1}}); +const std::vector> T_GD({{197, 8}}); const double T_GD_LSB = TWO_N31; -const std::vector> IODC({{83, 2}, {211, 8}}); -const std::vector> T_OC({{219, 16}}); +const std::vector> IODC({{83, 2}, {211, 8}}); +const std::vector> T_OC({{219, 16}}); const double T_OC_LSB = TWO_P4; -const std::vector> A_F2({{241, 8}}); +const std::vector> A_F2({{241, 8}}); const double A_F2_LSB = TWO_N55; -const std::vector> A_F1({{249, 16}}); +const std::vector> A_F1({{249, 16}}); const double A_F1_LSB = TWO_N43; -const std::vector> A_F0({{271, 22}}); +const std::vector> A_F0({{271, 22}}); const double A_F0_LSB = TWO_N31; // SUBFRAME 2 -const std::vector> IODE_SF2({{61, 8}}); -const std::vector> C_RS({{69, 16}}); +const std::vector> IODE_SF2({{61, 8}}); +const std::vector> C_RS({{69, 16}}); const double C_RS_LSB = TWO_N5; -const std::vector> DELTA_N({{91, 16}}); +const std::vector> DELTA_N({{91, 16}}); const double DELTA_N_LSB = PI_TWO_N43; -const std::vector> M_0({{107, 8}, {121, 24}}); +const std::vector> M_0({{107, 8}, {121, 24}}); const double M_0_LSB = PI_TWO_N31; -const std::vector> C_UC({{151, 16}}); +const std::vector> C_UC({{151, 16}}); const double C_UC_LSB = TWO_N29; -const std::vector> E({{167, 8}, {181, 24}}); +const std::vector> E({{167, 8}, {181, 24}}); const double E_LSB = TWO_N33; -const std::vector> C_US({{211, 16}}); +const std::vector> C_US({{211, 16}}); const double C_US_LSB = TWO_N29; -const std::vector> SQRT_A({{227, 8}, {241, 24}}); +const std::vector> SQRT_A({{227, 8}, {241, 24}}); const double SQRT_A_LSB = TWO_N19; -const std::vector> T_OE({{271, 16}}); +const std::vector> T_OE({{271, 16}}); const double T_OE_LSB = TWO_P4; -const std::vector> FIT_INTERVAL_FLAG({{271, 1}}); -const std::vector> AODO({{272, 5}}); -const int AODO_LSB = 900; +const std::vector> FIT_INTERVAL_FLAG({{271, 1}}); +const std::vector> AODO({{272, 5}}); +const int32_t AODO_LSB = 900; // SUBFRAME 3 -const std::vector> C_IC({{61, 16}}); +const std::vector> C_IC({{61, 16}}); const double C_IC_LSB = TWO_N29; -const std::vector> OMEGA_0({{77, 8}, {91, 24}}); +const std::vector> OMEGA_0({{77, 8}, {91, 24}}); const double OMEGA_0_LSB = PI_TWO_N31; -const std::vector> C_IS({{121, 16}}); +const std::vector> C_IS({{121, 16}}); const double C_IS_LSB = TWO_N29; -const std::vector> I_0({{137, 8}, {151, 24}}); +const std::vector> I_0({{137, 8}, {151, 24}}); const double I_0_LSB = PI_TWO_N31; -const std::vector> C_RC({{181, 16}}); +const std::vector> C_RC({{181, 16}}); const double C_RC_LSB = TWO_N5; -const std::vector> OMEGA({{197, 8}, {211, 24}}); +const std::vector> OMEGA({{197, 8}, {211, 24}}); const double OMEGA_LSB = PI_TWO_N31; -const std::vector> OMEGA_DOT({{241, 24}}); +const std::vector> OMEGA_DOT({{241, 24}}); const double OMEGA_DOT_LSB = PI_TWO_N43; -const std::vector> IODE_SF3({{271, 8}}); -const std::vector> I_DOT({{279, 14}}); +const std::vector> IODE_SF3({{271, 8}}); +const std::vector> I_DOT({{279, 14}}); const double I_DOT_LSB = PI_TWO_N43; // SUBFRAME 4-5 -const std::vector> SV_DATA_ID({{61, 2}}); -const std::vector> SV_PAGE({{63, 6}}); +const std::vector> SV_DATA_ID({{61, 2}}); +const std::vector> SV_PAGE({{63, 6}}); // SUBFRAME 4 //! \todo read all pages of subframe 4 // Page 18 - Ionospheric and UTC data -const std::vector> ALPHA_0({{69, 8}}); +const std::vector> ALPHA_0({{69, 8}}); const double ALPHA_0_LSB = TWO_N30; -const std::vector> ALPHA_1({{77, 8}}); +const std::vector> ALPHA_1({{77, 8}}); const double ALPHA_1_LSB = TWO_N27; -const std::vector> ALPHA_2({{91, 8}}); +const std::vector> ALPHA_2({{91, 8}}); const double ALPHA_2_LSB = TWO_N24; -const std::vector> ALPHA_3({{99, 8}}); +const std::vector> ALPHA_3({{99, 8}}); const double ALPHA_3_LSB = TWO_N24; -const std::vector> BETA_0({{107, 8}}); +const std::vector> BETA_0({{107, 8}}); const double BETA_0_LSB = TWO_P11; -const std::vector> BETA_1({{121, 8}}); +const std::vector> BETA_1({{121, 8}}); const double BETA_1_LSB = TWO_P14; -const std::vector> BETA_2({{129, 8}}); +const std::vector> BETA_2({{129, 8}}); const double BETA_2_LSB = TWO_P16; -const std::vector> BETA_3({{137, 8}}); +const std::vector> BETA_3({{137, 8}}); const double BETA_3_LSB = TWO_P16; -const std::vector> A_1({{151, 24}}); +const std::vector> A_1({{151, 24}}); const double A_1_LSB = TWO_N50; -const std::vector> A_0({{181, 24}, {211, 8}}); +const std::vector> A_0({{181, 24}, {211, 8}}); const double A_0_LSB = TWO_N30; -const std::vector> T_OT({{219, 8}}); +const std::vector> T_OT({{219, 8}}); const double T_OT_LSB = TWO_P12; -const std::vector> WN_T({{227, 8}}); +const std::vector> WN_T({{227, 8}}); const double WN_T_LSB = 1; -const std::vector> DELTAT_LS({{241, 8}}); +const std::vector> DELTAT_LS({{241, 8}}); const double DELTAT_LS_LSB = 1; -const std::vector> WN_LSF({{249, 8}}); +const std::vector> WN_LSF({{249, 8}}); const double WN_LSF_LSB = 1; -const std::vector> DN({{257, 8}}); +const std::vector> DN({{257, 8}}); const double DN_LSB = 1; -const std::vector> DELTAT_LSF({{271, 8}}); +const std::vector> DELTAT_LSF({{271, 8}}); const double DELTAT_LSF_LSB = 1; // Page 25 - Antispoofing, SV config and SV health (PRN 25 -32) -const std::vector> HEALTH_SV25({{229, 6}}); -const std::vector> HEALTH_SV26({{241, 6}}); -const std::vector> HEALTH_SV27({{247, 6}}); -const std::vector> HEALTH_SV28({{253, 6}}); -const std::vector> HEALTH_SV29({{259, 6}}); -const std::vector> HEALTH_SV30({{271, 6}}); -const std::vector> HEALTH_SV31({{277, 6}}); -const std::vector> HEALTH_SV32({{283, 6}}); +const std::vector> HEALTH_SV25({{229, 6}}); +const std::vector> HEALTH_SV26({{241, 6}}); +const std::vector> HEALTH_SV27({{247, 6}}); +const std::vector> HEALTH_SV28({{253, 6}}); +const std::vector> HEALTH_SV29({{259, 6}}); +const std::vector> HEALTH_SV30({{271, 6}}); +const std::vector> HEALTH_SV31({{277, 6}}); +const std::vector> HEALTH_SV32({{283, 6}}); // SUBFRAME 5 //! \todo read all pages of subframe 5 // page 25 - Health (PRN 1 - 24) -const std::vector> T_OA({{69, 8}}); +const std::vector> T_OA({{69, 8}}); const double T_OA_LSB = TWO_P12; -const std::vector> WN_A({{77, 8}}); -const std::vector> HEALTH_SV1({{91, 6}}); -const std::vector> HEALTH_SV2({{97, 6}}); -const std::vector> HEALTH_SV3({{103, 6}}); -const std::vector> HEALTH_SV4({{109, 6}}); -const std::vector> HEALTH_SV5({{121, 6}}); -const std::vector> HEALTH_SV6({{127, 6}}); -const std::vector> HEALTH_SV7({{133, 6}}); -const std::vector> HEALTH_SV8({{139, 6}}); -const std::vector> HEALTH_SV9({{151, 6}}); -const std::vector> HEALTH_SV10({{157, 6}}); -const std::vector> HEALTH_SV11({{163, 6}}); -const std::vector> HEALTH_SV12({{169, 6}}); -const std::vector> HEALTH_SV13({{181, 6}}); -const std::vector> HEALTH_SV14({{187, 6}}); -const std::vector> HEALTH_SV15({{193, 6}}); -const std::vector> HEALTH_SV16({{199, 6}}); -const std::vector> HEALTH_SV17({{211, 6}}); -const std::vector> HEALTH_SV18({{217, 6}}); -const std::vector> HEALTH_SV19({{223, 6}}); -const std::vector> HEALTH_SV20({{229, 6}}); -const std::vector> HEALTH_SV21({{241, 6}}); -const std::vector> HEALTH_SV22({{247, 6}}); -const std::vector> HEALTH_SV23({{253, 6}}); -const std::vector> HEALTH_SV24({{259, 6}}); +const std::vector> WN_A({{77, 8}}); +const std::vector> HEALTH_SV1({{91, 6}}); +const std::vector> HEALTH_SV2({{97, 6}}); +const std::vector> HEALTH_SV3({{103, 6}}); +const std::vector> HEALTH_SV4({{109, 6}}); +const std::vector> HEALTH_SV5({{121, 6}}); +const std::vector> HEALTH_SV6({{127, 6}}); +const std::vector> HEALTH_SV7({{133, 6}}); +const std::vector> HEALTH_SV8({{139, 6}}); +const std::vector> HEALTH_SV9({{151, 6}}); +const std::vector> HEALTH_SV10({{157, 6}}); +const std::vector> HEALTH_SV11({{163, 6}}); +const std::vector> HEALTH_SV12({{169, 6}}); +const std::vector> HEALTH_SV13({{181, 6}}); +const std::vector> HEALTH_SV14({{187, 6}}); +const std::vector> HEALTH_SV15({{193, 6}}); +const std::vector> HEALTH_SV16({{199, 6}}); +const std::vector> HEALTH_SV17({{211, 6}}); +const std::vector> HEALTH_SV18({{217, 6}}); +const std::vector> HEALTH_SV19({{223, 6}}); +const std::vector> HEALTH_SV20({{229, 6}}); +const std::vector> HEALTH_SV21({{241, 6}}); +const std::vector> HEALTH_SV22({{247, 6}}); +const std::vector> HEALTH_SV23({{253, 6}}); +const std::vector> HEALTH_SV24({{259, 6}}); #endif /* GNSS_SDR_GPS_L1_CA_H_ */ diff --git a/src/core/system_parameters/GPS_L2C.h b/src/core/system_parameters/GPS_L2C.h index 67a467192..b156dfe4a 100644 --- a/src/core/system_parameters/GPS_L2C.h +++ b/src/core/system_parameters/GPS_L2C.h @@ -50,19 +50,18 @@ const double GPS_L2_OMEGA_EARTH_DOT = 7.2921151467e-5; //!< Earth rotation rate const double GPS_L2_GM = 3.986005e14; //!< Universal gravitational constant times the mass of the Earth, [m^3/s^2] const double GPS_L2_F = -4.442807633e-10; //!< Constant, [s/(m)^(1/2)] - // carrier and code frequencies const double GPS_L2_FREQ_HZ = FREQ2; //!< L2 [Hz] -const double GPS_L2_M_CODE_RATE_HZ = 0.5115e6; //!< GPS L2 M code rate [chips/s] -const int GPS_L2_M_CODE_LENGTH_CHIPS = 10230; //!< GPS L2 M code length [chips] -const double GPS_L2_M_PERIOD = 0.02; //!< GPS L2 M code period [seconds] +const double GPS_L2_M_CODE_RATE_HZ = 0.5115e6; //!< GPS L2 M code rate [chips/s] +const int32_t GPS_L2_M_CODE_LENGTH_CHIPS = 10230; //!< GPS L2 M code length [chips] +const double GPS_L2_M_PERIOD = 0.02; //!< GPS L2 M code period [seconds] -const double GPS_L2_L_CODE_RATE_HZ = 0.5115e6; //!< GPS L2 L code rate [chips/s] -const int GPS_L2_L_CODE_LENGTH_CHIPS = 767250; //!< GPS L2 L code length [chips] -const double GPS_L2_L_PERIOD = 1.5; //!< GPS L2 L code period [seconds] +const double GPS_L2_L_CODE_RATE_HZ = 0.5115e6; //!< GPS L2 L code rate [chips/s] +const int32_t GPS_L2_L_CODE_LENGTH_CHIPS = 767250; //!< GPS L2 L code length [chips] +const double GPS_L2_L_PERIOD = 1.5; //!< GPS L2 L code period [seconds] -const int GPS_L2C_HISTORY_DEEP = 5; +const int32_t GPS_L2C_HISTORY_DEEP = 5; const int32_t GPS_L2C_M_INIT_REG[115] = {0742417664, 0756014035, 0002747144, 0066265724, // 1:4 @@ -79,9 +78,9 @@ const int32_t GPS_L2C_M_INIT_REG[115] = 0047457275, 0266333164, 0713167356, 0060546335, 0355173035, 0617201036, 0157465571, 0767360553, 0023127030, 0431343777, 0747317317, 0045706125, - 0002744276, 0060036467, 0217744147, 0603340174, //57:60 - 0326616775, 0063240065, 0111460621, //61:63 - 0604055104, 0157065232, 0013305707, 0603552017, //159:162 + 0002744276, 0060036467, 0217744147, 0603340174, // 57:60 + 0326616775, 0063240065, 0111460621, // 61:63 + 0604055104, 0157065232, 0013305707, 0603552017, // 159:162 0230461355, 0603653437, 0652346475, 0743107103, 0401521277, 0167335110, 0014013575, 0362051132, 0617753265, 0216363634, 0755561123, 0365304033, @@ -95,10 +94,10 @@ const int32_t GPS_L2C_M_INIT_REG[115] = 0706202440, 0705056276, 0020373522, 0746013617, 0132720621, 0434015513, 0566721727, 0140633660}; -const int GPS_L2_CNAV_DATA_PAGE_BITS = 300; //!< GPS L2 CNAV page length, including preamble and CRC [bits] -const int GPS_L2_SYMBOLS_PER_BIT = 2; -const int GPS_L2_SAMPLES_PER_SYMBOL = 1; -const int GPS_L2_CNAV_DATA_PAGE_SYMBOLS = 600; -const int GPS_L2_CNAV_DATA_PAGE_DURATION_S = 12; +const int32_t GPS_L2_CNAV_DATA_PAGE_BITS = 300; //!< GPS L2 CNAV page length, including preamble and CRC [bits] +const int32_t GPS_L2_SYMBOLS_PER_BIT = 2; +const int32_t GPS_L2_SAMPLES_PER_SYMBOL = 1; +const int32_t GPS_L2_CNAV_DATA_PAGE_SYMBOLS = 600; +const int32_t GPS_L2_CNAV_DATA_PAGE_DURATION_S = 12; #endif /* GNSS_SDR_GPS_L2C_H_ */ diff --git a/src/core/system_parameters/GPS_L5.h b/src/core/system_parameters/GPS_L5.h index 5a919820d..fe270f204 100644 --- a/src/core/system_parameters/GPS_L5.h +++ b/src/core/system_parameters/GPS_L5.h @@ -48,20 +48,21 @@ const double GPS_L5_OMEGA_EARTH_DOT = 7.2921151467e-5; //!< Earth rotation rate const double GPS_L5_GM = 3.986005e14; //!< Universal gravitational constant times the mass of the Earth, [m^3/s^2] const double GPS_L5_F = -4.442807633e-10; //!< Constant, [s/(m)^(1/2)] - // carrier and code frequencies const double GPS_L5_FREQ_HZ = FREQ5; //!< L5 [Hz] -const double GPS_L5i_CODE_RATE_HZ = 10.23e6; //!< GPS L5i code rate [chips/s] -const int GPS_L5i_CODE_LENGTH_CHIPS = 10230; //!< GPS L5i code length [chips] -const double GPS_L5i_PERIOD = 0.001; //!< GPS L5 code period [seconds] -const double GPS_L5i_SYMBOL_PERIOD = 0.01; //!< GPS L5 symbol period [seconds] +const double GPS_L5i_CODE_RATE_HZ = 10.23e6; //!< GPS L5i code rate [chips/s] +const int32_t GPS_L5i_CODE_LENGTH_CHIPS = 10230; //!< GPS L5i code length [chips] +const double GPS_L5i_PERIOD = 0.001; //!< GPS L5 code period [seconds] +const int32_t GPS_L5i_PERIOD_MS = 1; //!< GPS L5 code period [ms] +const double GPS_L5i_SYMBOL_PERIOD = 0.01; //!< GPS L5 symbol period [seconds] +const int32_t GPS_L5i_SYMBOL_PERIOD_MS = 10; //!< GPS L5 symbol period [ms] -const double GPS_L5q_CODE_RATE_HZ = 10.23e6; //!< GPS L5i code rate [chips/s] -const int GPS_L5q_CODE_LENGTH_CHIPS = 10230; //!< GPS L5i code length [chips] -const double GPS_L5q_PERIOD = 0.001; //!< GPS L5 code period [seconds] +const double GPS_L5q_CODE_RATE_HZ = 10.23e6; //!< GPS L5i code rate [chips/s] +const int32_t GPS_L5q_CODE_LENGTH_CHIPS = 10230; //!< GPS L5i code length [chips] +const double GPS_L5q_PERIOD = 0.001; //!< GPS L5 code period [seconds] -const int GPS_L5_HISTORY_DEEP = 5; +const int32_t GPS_L5_HISTORY_DEEP = 5; const int32_t GPS_L5i_INIT_REG[210] = {266, 365, 804, 1138, @@ -177,16 +178,16 @@ const int32_t GPS_L5q_INIT_REG[210] = 2765, 37, 1943, 7977, 2512, 4451, 4071}; -const int GPS_L5_CNAV_DATA_PAGE_BITS = 300; //!< GPS L5 CNAV page length, including preamble and CRC [bits] -const int GPS_L5_SYMBOLS_PER_BIT = 2; -const int GPS_L5_SAMPLES_PER_SYMBOL = 10; -const int GPS_L5_CNAV_DATA_PAGE_SYMBOLS = 600; -const int GPS_L5_CNAV_DATA_PAGE_DURATION_S = 6; -const int GPS_L5i_NH_CODE_LENGTH = 10; -const int GPS_L5i_NH_CODE[10] = {0, 0, 0, 0, 1, 1, 0, 1, 0, 1}; +const int32_t GPS_L5_CNAV_DATA_PAGE_BITS = 300; //!< GPS L5 CNAV page length, including preamble and CRC [bits] +const int32_t GPS_L5_SYMBOLS_PER_BIT = 2; +const int32_t GPS_L5_SAMPLES_PER_SYMBOL = 10; +const int32_t GPS_L5_CNAV_DATA_PAGE_SYMBOLS = 600; +const int32_t GPS_L5_CNAV_DATA_PAGE_DURATION_S = 6; +const int32_t GPS_L5i_NH_CODE_LENGTH = 10; +const int32_t GPS_L5i_NH_CODE[10] = {0, 0, 0, 0, 1, 1, 0, 1, 0, 1}; const std::string GPS_L5i_NH_CODE_STR = "0000110101"; -const int GPS_L5q_NH_CODE_LENGTH = 20; -const int GPS_L5q_NH_CODE[20] = {0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0}; +const int32_t GPS_L5q_NH_CODE_LENGTH = 20; +const int32_t GPS_L5q_NH_CODE[20] = {0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0}; const std::string GPS_L5q_NH_CODE_STR = "00000100110101001110"; #endif /* GNSS_SDR_GPS_L5_H_ */ diff --git a/src/core/system_parameters/Galileo_E1.h b/src/core/system_parameters/Galileo_E1.h index 951612e02..e25501e08 100644 --- a/src/core/system_parameters/Galileo_E1.h +++ b/src/core/system_parameters/Galileo_E1.h @@ -35,6 +35,7 @@ #include "gnss_frequencies.h" #include "MATH_CONSTANTS.h" +#include #include #include #include // std::pair @@ -53,249 +54,249 @@ const double GALILEO_F = -4.442807309e-10; //!< Constant, [s/(m)^( const double Galileo_E1_FREQ_HZ = FREQ1; //!< Galileo E1 carrier frequency [Hz] const double Galileo_E1_CODE_CHIP_RATE_HZ = 1.023e6; //!< Galileo E1 code rate [chips/s] const double Galileo_E1_CODE_PERIOD = 0.004; //!< Galileo E1 code period [s] -const int Galileo_E1_CODE_PERIOD_MS = 4; //!< Galileo E1 code period [ms] +const int32_t Galileo_E1_CODE_PERIOD_MS = 4; //!< Galileo E1 code period [ms] const double Galileo_E1_SUB_CARRIER_A_RATE_HZ = 1.023e6; //!< Galileo E1 sub-carrier 'a' rate [Hz] const double Galileo_E1_SUB_CARRIER_B_RATE_HZ = 6.138e6; //!< Galileo E1 sub-carrier 'b' rate [Hz] const double Galileo_E1_B_CODE_LENGTH_CHIPS = 4092.0; //!< Galileo E1-B code length [chips] const double Galileo_E1_B_SYMBOL_RATE_BPS = 250.0; //!< Galileo E1-B symbol rate [bits/second] -const int Galileo_E1_C_SECONDARY_CODE_LENGTH = 25; //!< Galileo E1-C secondary code length [chips] -const int Galileo_E1_NUMBER_OF_CODES = 50; +const int32_t Galileo_E1_B_SAMPLES_PER_SYMBOL = 1; //!< (Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS) / Galileo_E1_B_SYMBOL_RATE_BPS +const int32_t Galileo_E1_C_SECONDARY_CODE_LENGTH = 25; //!< Galileo E1-C secondary code length [chips] +const int32_t Galileo_E1_NUMBER_OF_CODES = 50; const double GALILEO_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here) // OBSERVABLE HISTORY DEEP FOR INTERPOLATION -const int GALILEO_E1_HISTORY_DEEP = 100; +const int32_t GALILEO_E1_HISTORY_DEEP = 100; // Galileo INAV Telemetry structure -#define GALILEO_INAV_PREAMBLE \ - { \ - 0, 1, 0, 1, 1, 0, 0, 0, 0, 0 \ - } +const std::string GALILEO_INAV_PREAMBLE = {"0101100000"}; -const int GALILEO_INAV_PREAMBLE_LENGTH_BITS = 10; +const int32_t GALILEO_INAV_PREAMBLE_LENGTH_BITS = 10; const double GALILEO_INAV_PAGE_PART_WITH_PREABLE_SECONDS = 2.0 + GALILEO_INAV_PREAMBLE_LENGTH_BITS * Galileo_E1_CODE_PERIOD; -const int GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS = 250; -const int GALILEO_INAV_PAGE_PART_SYMBOLS = 250; //!< Each Galileo INAV pages are composed of two parts (even and odd) each of 250 symbols, including preamble. See Galileo ICD 4.3.2 -const int GALILEO_INAV_PAGE_SYMBOLS = 500; //!< The complete Galileo INAV page length -const int GALILEO_INAV_PAGE_PART_SECONDS = 1; // a page part last 1 sec -const int GALILEO_INAV_PAGE_SECONDS = 2; // a full page last 2 sec -const int GALILEO_INAV_INTERLEAVER_ROWS = 8; -const int GALILEO_INAV_INTERLEAVER_COLS = 30; -const int GALILEO_TELEMETRY_RATE_BITS_SECOND = 250; //bps -const int GALILEO_PAGE_TYPE_BITS = 6; -const int GALILEO_DATA_JK_BITS = 128; -const int GALILEO_DATA_FRAME_BITS = 196; -const int GALILEO_DATA_FRAME_BYTES = 25; +const int32_t GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS = 250; +const int32_t GALILEO_INAV_PAGE_PART_SYMBOLS = 250; //!< Each Galileo INAV pages are composed of two parts (even and odd) each of 250 symbols, including preamble. See Galileo ICD 4.3.2 +const int32_t GALILEO_INAV_PAGE_SYMBOLS = 500; //!< The complete Galileo INAV page length +const int32_t GALILEO_INAV_PAGE_PART_SECONDS = 1; // a page part last 1 sec +const int32_t GALILEO_INAV_PAGE_PART_MS = 1000; // a page part last 1 sec +const int32_t GALILEO_INAV_PAGE_SECONDS = 2; // a full page last 2 sec +const int32_t GALILEO_INAV_INTERLEAVER_ROWS = 8; +const int32_t GALILEO_INAV_INTERLEAVER_COLS = 30; +const int32_t GALILEO_TELEMETRY_RATE_BITS_SECOND = 250; //bps +const int32_t GALILEO_PAGE_TYPE_BITS = 6; +const int32_t GALILEO_DATA_JK_BITS = 128; +const int32_t GALILEO_DATA_FRAME_BITS = 196; +const int32_t GALILEO_DATA_FRAME_BYTES = 25; const double GALILEO_E1_CODE_PERIOD = 0.004; +const int32_t GALILEO_E1_CODE_PERIOD_MS = 4; -const std::vector> type({{1, 6}}); -const std::vector> PAGE_TYPE_bit({{1, 6}}); +const std::vector> type({{1, 6}}); +const std::vector> PAGE_TYPE_bit({{1, 6}}); ; /*Page 1 - Word type 1: Ephemeris (1/4)*/ -const std::vector> IOD_nav_1_bit({{7, 10}}); -const std::vector> T0E_1_bit({{17, 14}}); +const std::vector> IOD_nav_1_bit({{7, 10}}); +const std::vector> T0E_1_bit({{17, 14}}); const double t0e_1_LSB = 60; -const std::vector> M0_1_bit({{31, 32}}); +const std::vector> M0_1_bit({{31, 32}}); const double M0_1_LSB = PI_TWO_N31; -const std::vector> e_1_bit({{63, 32}}); +const std::vector> e_1_bit({{63, 32}}); const double e_1_LSB = TWO_N33; -const std::vector> A_1_bit({{95, 32}}); +const std::vector> A_1_bit({{95, 32}}); const double A_1_LSB_gal = TWO_N19; //last two bits are reserved /*Page 2 - Word type 2: Ephemeris (2/4)*/ -const std::vector> IOD_nav_2_bit({{7, 10}}); -const std::vector> OMEGA_0_2_bit({{17, 32}}); +const std::vector> IOD_nav_2_bit({{7, 10}}); +const std::vector> OMEGA_0_2_bit({{17, 32}}); const double OMEGA_0_2_LSB = PI_TWO_N31; -const std::vector> i_0_2_bit({{49, 32}}); +const std::vector> i_0_2_bit({{49, 32}}); const double i_0_2_LSB = PI_TWO_N31; -const std::vector> omega_2_bit({{81, 32}}); +const std::vector> omega_2_bit({{81, 32}}); const double omega_2_LSB = PI_TWO_N31; -const std::vector> iDot_2_bit({{113, 14}}); +const std::vector> iDot_2_bit({{113, 14}}); const double iDot_2_LSB = PI_TWO_N43; //last two bits are reserved /*Word type 3: Ephemeris (3/4) and SISA*/ -const std::vector> IOD_nav_3_bit({{7, 10}}); -const std::vector> OMEGA_dot_3_bit({{17, 24}}); +const std::vector> IOD_nav_3_bit({{7, 10}}); +const std::vector> OMEGA_dot_3_bit({{17, 24}}); const double OMEGA_dot_3_LSB = PI_TWO_N43; -const std::vector> delta_n_3_bit({{41, 16}}); +const std::vector> delta_n_3_bit({{41, 16}}); const double delta_n_3_LSB = PI_TWO_N43; -const std::vector> C_uc_3_bit({{57, 16}}); +const std::vector> C_uc_3_bit({{57, 16}}); const double C_uc_3_LSB = TWO_N29; -const std::vector> C_us_3_bit({{73, 16}}); +const std::vector> C_us_3_bit({{73, 16}}); const double C_us_3_LSB = TWO_N29; -const std::vector> C_rc_3_bit({{89, 16}}); +const std::vector> C_rc_3_bit({{89, 16}}); const double C_rc_3_LSB = TWO_N5; -const std::vector> C_rs_3_bit({{105, 16}}); +const std::vector> C_rs_3_bit({{105, 16}}); const double C_rs_3_LSB = TWO_N5; -const std::vector> SISA_3_bit({{121, 8}}); +const std::vector> SISA_3_bit({{121, 8}}); /*Word type 4: Ephemeris (4/4) and Clock correction parameters*/ -const std::vector> IOD_nav_4_bit({{7, 10}}); -const std::vector> SV_ID_PRN_4_bit({{17, 6}}); -const std::vector> C_ic_4_bit({{23, 16}}); +const std::vector> IOD_nav_4_bit({{7, 10}}); +const std::vector> SV_ID_PRN_4_bit({{17, 6}}); +const std::vector> C_ic_4_bit({{23, 16}}); const double C_ic_4_LSB = TWO_N29; -const std::vector> C_is_4_bit({{39, 16}}); +const std::vector> C_is_4_bit({{39, 16}}); const double C_is_4_LSB = TWO_N29; -const std::vector> t0c_4_bit({{55, 14}}); // +const std::vector> t0c_4_bit({{55, 14}}); // const double t0c_4_LSB = 60; -const std::vector> af0_4_bit({{69, 31}}); // +const std::vector> af0_4_bit({{69, 31}}); // const double af0_4_LSB = TWO_N34; -const std::vector> af1_4_bit({{100, 21}}); // +const std::vector> af1_4_bit({{100, 21}}); // const double af1_4_LSB = TWO_N46; -const std::vector> af2_4_bit({{121, 6}}); +const std::vector> af2_4_bit({{121, 6}}); const double af2_4_LSB = TWO_N59; -const std::vector> spare_4_bit({{127, 2}}); +const std::vector> spare_4_bit({{127, 2}}); //last two bits are reserved /*Word type 5: Ionospheric correction, BGD, signal health and data validity status and GST*/ /*Ionospheric correction*/ /*Az*/ -const std::vector> ai0_5_bit({{7, 11}}); // +const std::vector> ai0_5_bit({{7, 11}}); // const double ai0_5_LSB = TWO_N2; -const std::vector> ai1_5_bit({{18, 11}}); // +const std::vector> ai1_5_bit({{18, 11}}); // const double ai1_5_LSB = TWO_N8; -const std::vector> ai2_5_bit({{29, 14}}); // +const std::vector> ai2_5_bit({{29, 14}}); // const double ai2_5_LSB = TWO_N15; /*Ionospheric disturbance flag*/ -const std::vector> Region1_5_bit({{43, 1}}); // -const std::vector> Region2_5_bit({{44, 1}}); // -const std::vector> Region3_5_bit({{45, 1}}); // -const std::vector> Region4_5_bit({{46, 1}}); // -const std::vector> Region5_5_bit({{47, 1}}); // -const std::vector> BGD_E1E5a_5_bit({{48, 10}}); // +const std::vector> Region1_5_bit({{43, 1}}); // +const std::vector> Region2_5_bit({{44, 1}}); // +const std::vector> Region3_5_bit({{45, 1}}); // +const std::vector> Region4_5_bit({{46, 1}}); // +const std::vector> Region5_5_bit({{47, 1}}); // +const std::vector> BGD_E1E5a_5_bit({{48, 10}}); // const double BGD_E1E5a_5_LSB = TWO_N32; -const std::vector> BGD_E1E5b_5_bit({{58, 10}}); // +const std::vector> BGD_E1E5b_5_bit({{58, 10}}); // const double BGD_E1E5b_5_LSB = TWO_N32; -const std::vector> E5b_HS_5_bit({{68, 2}}); // -const std::vector> E1B_HS_5_bit({{70, 2}}); // -const std::vector> E5b_DVS_5_bit({{72, 1}}); // -const std::vector> E1B_DVS_5_bit({{73, 1}}); // +const std::vector> E5b_HS_5_bit({{68, 2}}); // +const std::vector> E1B_HS_5_bit({{70, 2}}); // +const std::vector> E5b_DVS_5_bit({{72, 1}}); // +const std::vector> E1B_DVS_5_bit({{73, 1}}); // /*GST*/ -const std::vector> WN_5_bit({{74, 12}}); -const std::vector> TOW_5_bit({{86, 20}}); -const std::vector> spare_5_bit({{106, 23}}); +const std::vector> WN_5_bit({{74, 12}}); +const std::vector> TOW_5_bit({{86, 20}}); +const std::vector> spare_5_bit({{106, 23}}); /* Page 6 */ -const std::vector> A0_6_bit({{7, 32}}); +const std::vector> A0_6_bit({{7, 32}}); const double A0_6_LSB = TWO_N30; -const std::vector> A1_6_bit({{39, 24}}); +const std::vector> A1_6_bit({{39, 24}}); const double A1_6_LSB = TWO_N50; -const std::vector> Delta_tLS_6_bit({{63, 8}}); -const std::vector> t0t_6_bit({{71, 8}}); +const std::vector> Delta_tLS_6_bit({{63, 8}}); +const std::vector> t0t_6_bit({{71, 8}}); const double t0t_6_LSB = 3600; -const std::vector> WNot_6_bit({{79, 8}}); -const std::vector> WN_LSF_6_bit({{87, 8}}); -const std::vector> DN_6_bit({{95, 3}}); -const std::vector> Delta_tLSF_6_bit({{98, 8}}); -const std::vector> TOW_6_bit({{106, 20}}); +const std::vector> WNot_6_bit({{79, 8}}); +const std::vector> WN_LSF_6_bit({{87, 8}}); +const std::vector> DN_6_bit({{95, 3}}); +const std::vector> Delta_tLSF_6_bit({{98, 8}}); +const std::vector> TOW_6_bit({{106, 20}}); /* Page 7 */ -const std::vector> IOD_a_7_bit({{7, 4}}); -const std::vector> WN_a_7_bit({{11, 2}}); -const std::vector> t0a_7_bit({{13, 10}}); +const std::vector> IOD_a_7_bit({{7, 4}}); +const std::vector> WN_a_7_bit({{11, 2}}); +const std::vector> t0a_7_bit({{13, 10}}); const double t0a_7_LSB = 600; -const std::vector> SVID1_7_bit({{23, 6}}); -const std::vector> DELTA_A_7_bit({{29, 13}}); +const std::vector> SVID1_7_bit({{23, 6}}); +const std::vector> DELTA_A_7_bit({{29, 13}}); const double DELTA_A_7_LSB = TWO_N9; -const std::vector> e_7_bit({{42, 11}}); +const std::vector> e_7_bit({{42, 11}}); const double e_7_LSB = TWO_N16; -const std::vector> omega_7_bit({{53, 16}}); +const std::vector> omega_7_bit({{53, 16}}); const double omega_7_LSB = TWO_N15; -const std::vector> delta_i_7_bit({{69, 11}}); +const std::vector> delta_i_7_bit({{69, 11}}); const double delta_i_7_LSB = TWO_N14; -const std::vector> Omega0_7_bit({{80, 16}}); +const std::vector> Omega0_7_bit({{80, 16}}); const double Omega0_7_LSB = TWO_N15; -const std::vector> Omega_dot_7_bit({{96, 11}}); +const std::vector> Omega_dot_7_bit({{96, 11}}); const double Omega_dot_7_LSB = TWO_N33; -const std::vector> M0_7_bit({{107, 16}}); +const std::vector> M0_7_bit({{107, 16}}); const double M0_7_LSB = TWO_N15; /* Page 8 */ -const std::vector> IOD_a_8_bit({{7, 4}}); -const std::vector> af0_8_bit({{11, 16}}); +const std::vector> IOD_a_8_bit({{7, 4}}); +const std::vector> af0_8_bit({{11, 16}}); const double af0_8_LSB = TWO_N19; -const std::vector> af1_8_bit({{27, 13}}); +const std::vector> af1_8_bit({{27, 13}}); const double af1_8_LSB = TWO_N38; -const std::vector> E5b_HS_8_bit({{40, 2}}); -const std::vector> E1B_HS_8_bit({{42, 2}}); -const std::vector> SVID2_8_bit({{44, 6}}); -const std::vector> DELTA_A_8_bit({{50, 13}}); +const std::vector> E5b_HS_8_bit({{40, 2}}); +const std::vector> E1B_HS_8_bit({{42, 2}}); +const std::vector> SVID2_8_bit({{44, 6}}); +const std::vector> DELTA_A_8_bit({{50, 13}}); const double DELTA_A_8_LSB = TWO_N9; -const std::vector> e_8_bit({{63, 11}}); +const std::vector> e_8_bit({{63, 11}}); const double e_8_LSB = TWO_N16; -const std::vector> omega_8_bit({{74, 16}}); +const std::vector> omega_8_bit({{74, 16}}); const double omega_8_LSB = TWO_N15; -const std::vector> delta_i_8_bit({{90, 11}}); +const std::vector> delta_i_8_bit({{90, 11}}); const double delta_i_8_LSB = TWO_N14; -const std::vector> Omega0_8_bit({{101, 16}}); +const std::vector> Omega0_8_bit({{101, 16}}); const double Omega0_8_LSB = TWO_N15; -const std::vector> Omega_dot_8_bit({{117, 11}}); +const std::vector> Omega_dot_8_bit({{117, 11}}); const double Omega_dot_8_LSB = TWO_N33; /* Page 9 */ -const std::vector> IOD_a_9_bit({{7, 4}}); -const std::vector> WN_a_9_bit({{11, 2}}); -const std::vector> t0a_9_bit({{13, 10}}); +const std::vector> IOD_a_9_bit({{7, 4}}); +const std::vector> WN_a_9_bit({{11, 2}}); +const std::vector> t0a_9_bit({{13, 10}}); const double t0a_9_LSB = 600; -const std::vector> M0_9_bit({{23, 16}}); +const std::vector> M0_9_bit({{23, 16}}); const double M0_9_LSB = TWO_N15; -const std::vector> af0_9_bit({{39, 16}}); +const std::vector> af0_9_bit({{39, 16}}); const double af0_9_LSB = TWO_N19; -const std::vector> af1_9_bit({{55, 13}}); +const std::vector> af1_9_bit({{55, 13}}); const double af1_9_LSB = TWO_N38; -const std::vector> E5b_HS_9_bit({{68, 2}}); -const std::vector> E1B_HS_9_bit({{70, 2}}); -const std::vector> SVID3_9_bit({{72, 6}}); -const std::vector> DELTA_A_9_bit({{78, 13}}); +const std::vector> E5b_HS_9_bit({{68, 2}}); +const std::vector> E1B_HS_9_bit({{70, 2}}); +const std::vector> SVID3_9_bit({{72, 6}}); +const std::vector> DELTA_A_9_bit({{78, 13}}); const double DELTA_A_9_LSB = TWO_N9; -const std::vector> e_9_bit({{91, 11}}); +const std::vector> e_9_bit({{91, 11}}); const double e_9_LSB = TWO_N16; -const std::vector> omega_9_bit({{102, 16}}); +const std::vector> omega_9_bit({{102, 16}}); const double omega_9_LSB = TWO_N15; -const std::vector> delta_i_9_bit({{118, 11}}); +const std::vector> delta_i_9_bit({{118, 11}}); const double delta_i_9_LSB = TWO_N14; /* Page 10 */ -const std::vector> IOD_a_10_bit({{7, 4}}); -const std::vector> Omega0_10_bit({{11, 16}}); +const std::vector> IOD_a_10_bit({{7, 4}}); +const std::vector> Omega0_10_bit({{11, 16}}); const double Omega0_10_LSB = TWO_N15; -const std::vector> Omega_dot_10_bit({{27, 11}}); +const std::vector> Omega_dot_10_bit({{27, 11}}); const double Omega_dot_10_LSB = TWO_N33; -const std::vector> M0_10_bit({{38, 16}}); +const std::vector> M0_10_bit({{38, 16}}); const double M0_10_LSB = TWO_N15; -const std::vector> af0_10_bit({{54, 16}}); +const std::vector> af0_10_bit({{54, 16}}); const double af0_10_LSB = TWO_N19; -const std::vector> af1_10_bit({{70, 13}}); +const std::vector> af1_10_bit({{70, 13}}); const double af1_10_LSB = TWO_N38; -const std::vector> E5b_HS_10_bit({{83, 2}}); -const std::vector> E1B_HS_10_bit({{85, 2}}); -const std::vector> A_0G_10_bit({{87, 16}}); +const std::vector> E5b_HS_10_bit({{83, 2}}); +const std::vector> E1B_HS_10_bit({{85, 2}}); +const std::vector> A_0G_10_bit({{87, 16}}); const double A_0G_10_LSB = TWO_N35; -const std::vector> A_1G_10_bit({{103, 12}}); +const std::vector> A_1G_10_bit({{103, 12}}); const double A_1G_10_LSB = TWO_N51; -const std::vector> t_0G_10_bit({{115, 8}}); +const std::vector> t_0G_10_bit({{115, 8}}); const double t_0G_10_LSB = 3600; -const std::vector> WN_0G_10_bit({{123, 6}}); +const std::vector> WN_0G_10_bit({{123, 6}}); /* Page 0 */ -const std::vector> Time_0_bit({{7, 2}}); -const std::vector> WN_0_bit({{97, 12}}); -const std::vector> TOW_0_bit({{109, 20}}); +const std::vector> Time_0_bit({{7, 2}}); +const std::vector> WN_0_bit({{97, 12}}); +const std::vector> TOW_0_bit({{109, 20}}); // Galileo E1 primary codes diff --git a/src/core/system_parameters/Galileo_E5a.h b/src/core/system_parameters/Galileo_E5a.h index 79ad94f81..ea84ab3c9 100644 --- a/src/core/system_parameters/Galileo_E5a.h +++ b/src/core/system_parameters/Galileo_E5a.h @@ -33,193 +33,194 @@ #include "gnss_frequencies.h" #include "MATH_CONSTANTS.h" +#include #include #include #include // std::pair // Carrier and code frequencies -const double Galileo_E5a_FREQ_HZ = FREQ5; //!< Galileo E5a carrier frequency [Hz] -const double Galileo_E5a_CODE_CHIP_RATE_HZ = 1.023e7; //!< Galileo E5a code rate [chips/s] -const double Galileo_E5a_I_TIERED_CODE_PERIOD = 0.020; //!< Galileo E5a-I tiered code period [s] -const double Galileo_E5a_Q_TIERED_CODE_PERIOD = 0.100; //!< Galileo E5a-Q tiered code period [s] -const int Galileo_E5a_CODE_LENGTH_CHIPS = 10230; //!< Galileo E5a primary code length [chips] -const int Galileo_E5a_I_SECONDARY_CODE_LENGTH = 20; //!< Galileo E5a-I secondary code length [chips] -const int Galileo_E5a_Q_SECONDARY_CODE_LENGTH = 100; //!< Galileo E5a-Q secondary code length [chips] -const double GALILEO_E5a_CODE_PERIOD = 0.001; //!< Galileo E1 primary code period [s] -const int GALILEO_E5a_CODE_PERIOD_MS = 1; //!< Galileo E1 primary code period [ms] -const int Galileo_E5a_SYMBOL_RATE_BPS = 50; //!< Galileo E5a symbol rate [bits/second] -const int Galileo_E5a_NUMBER_OF_CODES = 50; +const double Galileo_E5a_FREQ_HZ = FREQ5; //!< Galileo E5a carrier frequency [Hz] +const double Galileo_E5a_CODE_CHIP_RATE_HZ = 1.023e7; //!< Galileo E5a code rate [chips/s] +const double Galileo_E5a_I_TIERED_CODE_PERIOD = 0.020; //!< Galileo E5a-I tiered code period [s] +const double Galileo_E5a_Q_TIERED_CODE_PERIOD = 0.100; //!< Galileo E5a-Q tiered code period [s] +const int32_t Galileo_E5a_CODE_LENGTH_CHIPS = 10230; //!< Galileo E5a primary code length [chips] +const int32_t Galileo_E5a_I_SECONDARY_CODE_LENGTH = 20; //!< Galileo E5a-I secondary code length [chips] +const int32_t Galileo_E5a_Q_SECONDARY_CODE_LENGTH = 100; //!< Galileo E5a-Q secondary code length [chips] +const double GALILEO_E5a_CODE_PERIOD = 0.001; //!< Galileo E1 primary code period [s] +const int32_t GALILEO_E5a_CODE_PERIOD_MS = 1; //!< Galileo E1 primary code period [ms] +const int32_t Galileo_E5a_SYMBOL_RATE_BPS = 50; //!< Galileo E5a symbol rate [bits/second] +const int32_t Galileo_E5a_NUMBER_OF_CODES = 50; // OBSERVABLE HISTORY DEEP FOR INTERPOLATION AND CRC ERROR LIMIT -const int GALILEO_E5A_HISTORY_DEEP = 20; -const int GALILEO_E5A_CRC_ERROR_LIMIT = 6; +const int32_t GALILEO_E5A_HISTORY_DEEP = 20; +const int32_t GALILEO_E5A_CRC_ERROR_LIMIT = 6; // F/NAV message structure -const int GALILEO_FNAV_PREAMBLE_LENGTH_BITS = 12; +const int32_t GALILEO_FNAV_PREAMBLE_LENGTH_BITS = 12; const std::string GALILEO_FNAV_PREAMBLE = {"101101110000"}; -const int GALILEO_FNAV_CODES_PER_SYMBOL = 20; // (chip rate/ code length)/telemetry bps -const int GALILEO_FNAV_CODES_PER_PREAMBLE = 240; // bits preamble * codes/symbol -const int GALILEO_FNAV_SYMBOLS_PER_PAGE = 500; //Total symbols per page including preamble. See Galileo ICD 4.2.2 -const int GALILEO_FNAV_SECONDS_PER_PAGE = 10; -const int GALILEO_FNAV_CODES_PER_PAGE = 10000; // symbols * codes/symbol, where code stands for primary code +const int32_t GALILEO_FNAV_CODES_PER_SYMBOL = 20; // (chip rate/ code length)/telemetry bps +const int32_t GALILEO_FNAV_CODES_PER_PREAMBLE = 240; // bits preamble * codes/symbol +const int32_t GALILEO_FNAV_SYMBOLS_PER_PAGE = 500; // Total symbols per page including preamble. See Galileo ICD 4.2.2 +const int32_t GALILEO_FNAV_SECONDS_PER_PAGE = 10; +const int32_t GALILEO_FNAV_CODES_PER_PAGE = 10000; // symbols * codes/symbol, where code stands for primary code -const int GALILEO_FNAV_INTERLEAVER_ROWS = 8; -const int GALILEO_FNAV_INTERLEAVER_COLS = 61; -const int GALILEO_FNAV_PAGE_TYPE_BITS = 6; +const int32_t GALILEO_FNAV_INTERLEAVER_ROWS = 8; +const int32_t GALILEO_FNAV_INTERLEAVER_COLS = 61; +const int32_t GALILEO_FNAV_PAGE_TYPE_BITS = 6; -const int GALILEO_FNAV_DATA_FRAME_BITS = 214; -const int GALILEO_FNAV_DATA_FRAME_BYTES = 27; +const int32_t GALILEO_FNAV_DATA_FRAME_BITS = 214; +const int32_t GALILEO_FNAV_DATA_FRAME_BYTES = 27; -const std::vector> FNAV_PAGE_TYPE_bit({{1, 6}}); +const std::vector> FNAV_PAGE_TYPE_bit({{1, 6}}); /* WORD 1 iono corrections. FNAV (Galileo E5a message)*/ -const std::vector> FNAV_SV_ID_PRN_1_bit({{7, 6}}); -const std::vector> FNAV_IODnav_1_bit({{13, 10}}); -const std::vector> FNAV_t0c_1_bit({{23, 14}}); +const std::vector> FNAV_SV_ID_PRN_1_bit({{7, 6}}); +const std::vector> FNAV_IODnav_1_bit({{13, 10}}); +const std::vector> FNAV_t0c_1_bit({{23, 14}}); const double FNAV_t0c_1_LSB = 60; -const std::vector> FNAV_af0_1_bit({{37, 31}}); +const std::vector> FNAV_af0_1_bit({{37, 31}}); const double FNAV_af0_1_LSB = TWO_N34; -const std::vector> FNAV_af1_1_bit({{68, 21}}); +const std::vector> FNAV_af1_1_bit({{68, 21}}); const double FNAV_af1_1_LSB = TWO_N46; -const std::vector> FNAV_af2_1_bit({{89, 6}}); +const std::vector> FNAV_af2_1_bit({{89, 6}}); const double FNAV_af2_1_LSB = TWO_N59; -const std::vector> FNAV_SISA_1_bit({{95, 8}}); -const std::vector> FNAV_ai0_1_bit({{103, 11}}); +const std::vector> FNAV_SISA_1_bit({{95, 8}}); +const std::vector> FNAV_ai0_1_bit({{103, 11}}); const double FNAV_ai0_1_LSB = TWO_N2; -const std::vector> FNAV_ai1_1_bit({{114, 11}}); +const std::vector> FNAV_ai1_1_bit({{114, 11}}); const double FNAV_ai1_1_LSB = TWO_N8; -const std::vector> FNAV_ai2_1_bit({{125, 14}}); +const std::vector> FNAV_ai2_1_bit({{125, 14}}); const double FNAV_ai2_1_LSB = TWO_N15; -const std::vector> FNAV_region1_1_bit({{139, 1}}); -const std::vector> FNAV_region2_1_bit({{140, 1}}); -const std::vector> FNAV_region3_1_bit({{141, 1}}); -const std::vector> FNAV_region4_1_bit({{142, 1}}); -const std::vector> FNAV_region5_1_bit({{143, 1}}); -const std::vector> FNAV_BGD_1_bit({{144, 10}}); +const std::vector> FNAV_region1_1_bit({{139, 1}}); +const std::vector> FNAV_region2_1_bit({{140, 1}}); +const std::vector> FNAV_region3_1_bit({{141, 1}}); +const std::vector> FNAV_region4_1_bit({{142, 1}}); +const std::vector> FNAV_region5_1_bit({{143, 1}}); +const std::vector> FNAV_BGD_1_bit({{144, 10}}); const double FNAV_BGD_1_LSB = TWO_N32; -const std::vector> FNAV_E5ahs_1_bit({{154, 2}}); -const std::vector> FNAV_WN_1_bit({{156, 12}}); -const std::vector> FNAV_TOW_1_bit({{168, 20}}); -const std::vector> FNAV_E5advs_1_bit({{188, 1}}); +const std::vector> FNAV_E5ahs_1_bit({{154, 2}}); +const std::vector> FNAV_WN_1_bit({{156, 12}}); +const std::vector> FNAV_TOW_1_bit({{168, 20}}); +const std::vector> FNAV_E5advs_1_bit({{188, 1}}); // WORD 2 Ephemeris (1/3) -const std::vector> FNAV_IODnav_2_bit({{7, 10}}); -const std::vector> FNAV_M0_2_bit({{17, 32}}); +const std::vector> FNAV_IODnav_2_bit({{7, 10}}); +const std::vector> FNAV_M0_2_bit({{17, 32}}); const double FNAV_M0_2_LSB = PI_TWO_N31; -const std::vector> FNAV_omegadot_2_bit({{49, 24}}); +const std::vector> FNAV_omegadot_2_bit({{49, 24}}); const double FNAV_omegadot_2_LSB = PI_TWO_N43; -const std::vector> FNAV_e_2_bit({{73, 32}}); +const std::vector> FNAV_e_2_bit({{73, 32}}); const double FNAV_e_2_LSB = TWO_N33; -const std::vector> FNAV_a12_2_bit({{105, 32}}); +const std::vector> FNAV_a12_2_bit({{105, 32}}); const double FNAV_a12_2_LSB = TWO_N19; -const std::vector> FNAV_omega0_2_bit({{137, 32}}); +const std::vector> FNAV_omega0_2_bit({{137, 32}}); const double FNAV_omega0_2_LSB = PI_TWO_N31; -const std::vector> FNAV_idot_2_bit({{169, 14}}); +const std::vector> FNAV_idot_2_bit({{169, 14}}); const double FNAV_idot_2_LSB = PI_TWO_N43; -const std::vector> FNAV_WN_2_bit({{183, 12}}); -const std::vector> FNAV_TOW_2_bit({{195, 20}}); +const std::vector> FNAV_WN_2_bit({{183, 12}}); +const std::vector> FNAV_TOW_2_bit({{195, 20}}); // WORD 3 Ephemeris (2/3) -const std::vector> FNAV_IODnav_3_bit({{7, 10}}); -const std::vector> FNAV_i0_3_bit({{17, 32}}); +const std::vector> FNAV_IODnav_3_bit({{7, 10}}); +const std::vector> FNAV_i0_3_bit({{17, 32}}); const double FNAV_i0_3_LSB = PI_TWO_N31; -const std::vector> FNAV_w_3_bit({{49, 32}}); +const std::vector> FNAV_w_3_bit({{49, 32}}); const double FNAV_w_3_LSB = PI_TWO_N31; -const std::vector> FNAV_deltan_3_bit({{81, 16}}); +const std::vector> FNAV_deltan_3_bit({{81, 16}}); const double FNAV_deltan_3_LSB = PI_TWO_N43; -const std::vector> FNAV_Cuc_3_bit({{97, 16}}); +const std::vector> FNAV_Cuc_3_bit({{97, 16}}); const double FNAV_Cuc_3_LSB = TWO_N29; -const std::vector> FNAV_Cus_3_bit({{113, 16}}); +const std::vector> FNAV_Cus_3_bit({{113, 16}}); const double FNAV_Cus_3_LSB = TWO_N29; -const std::vector> FNAV_Crc_3_bit({{129, 16}}); +const std::vector> FNAV_Crc_3_bit({{129, 16}}); const double FNAV_Crc_3_LSB = TWO_N5; -const std::vector> FNAV_Crs_3_bit({{145, 16}}); +const std::vector> FNAV_Crs_3_bit({{145, 16}}); const double FNAV_Crs_3_LSB = TWO_N5; -const std::vector> FNAV_t0e_3_bit({{161, 14}}); +const std::vector> FNAV_t0e_3_bit({{161, 14}}); const double FNAV_t0e_3_LSB = 60; -const std::vector> FNAV_WN_3_bit({{175, 12}}); -const std::vector> FNAV_TOW_3_bit({{187, 20}}); +const std::vector> FNAV_WN_3_bit({{175, 12}}); +const std::vector> FNAV_TOW_3_bit({{187, 20}}); // WORD 4 Ephemeris (3/3) -const std::vector> FNAV_IODnav_4_bit({{7, 10}}); -const std::vector> FNAV_Cic_4_bit({{17, 16}}); +const std::vector> FNAV_IODnav_4_bit({{7, 10}}); +const std::vector> FNAV_Cic_4_bit({{17, 16}}); const double FNAV_Cic_4_LSB = TWO_N29; -const std::vector> FNAV_Cis_4_bit({{33, 16}}); +const std::vector> FNAV_Cis_4_bit({{33, 16}}); const double FNAV_Cis_4_LSB = TWO_N29; -const std::vector> FNAV_A0_4_bit({{49, 32}}); +const std::vector> FNAV_A0_4_bit({{49, 32}}); const double FNAV_A0_4_LSB = TWO_N30; -const std::vector> FNAV_A1_4_bit({{81, 24}}); +const std::vector> FNAV_A1_4_bit({{81, 24}}); const double FNAV_A1_4_LSB = TWO_N50; -const std::vector> FNAV_deltatls_4_bit({{105, 8}}); -const std::vector> FNAV_t0t_4_bit({{113, 8}}); +const std::vector> FNAV_deltatls_4_bit({{105, 8}}); +const std::vector> FNAV_t0t_4_bit({{113, 8}}); const double FNAV_t0t_4_LSB = 3600; -const std::vector> FNAV_WNot_4_bit({{121, 8}}); -const std::vector> FNAV_WNlsf_4_bit({{129, 8}}); -const std::vector> FNAV_DN_4_bit({{137, 3}}); -const std::vector> FNAV_deltatlsf_4_bit({{140, 8}}); -const std::vector> FNAV_t0g_4_bit({{148, 8}}); +const std::vector> FNAV_WNot_4_bit({{121, 8}}); +const std::vector> FNAV_WNlsf_4_bit({{129, 8}}); +const std::vector> FNAV_DN_4_bit({{137, 3}}); +const std::vector> FNAV_deltatlsf_4_bit({{140, 8}}); +const std::vector> FNAV_t0g_4_bit({{148, 8}}); const double FNAV_t0g_4_LSB = 3600; -const std::vector> FNAV_A0g_4_bit({{156, 16}}); +const std::vector> FNAV_A0g_4_bit({{156, 16}}); const double FNAV_A0g_4_LSB = TWO_N35; -const std::vector> FNAV_A1g_4_bit({{172, 12}}); +const std::vector> FNAV_A1g_4_bit({{172, 12}}); const double FNAV_A1g_4_LSB = TWO_N51; -const std::vector> FNAV_WN0g_4_bit({{184, 6}}); -const std::vector> FNAV_TOW_4_bit({{190, 20}}); +const std::vector> FNAV_WN0g_4_bit({{184, 6}}); +const std::vector> FNAV_TOW_4_bit({{190, 20}}); // WORD 5 Almanac SVID1 SVID2(1/2) -const std::vector> FNAV_IODa_5_bit({{7, 4}}); -const std::vector> FNAV_WNa_5_bit({{11, 2}}); -const std::vector> FNAV_t0a_5_bit({{13, 10}}); +const std::vector> FNAV_IODa_5_bit({{7, 4}}); +const std::vector> FNAV_WNa_5_bit({{11, 2}}); +const std::vector> FNAV_t0a_5_bit({{13, 10}}); const double FNAV_t0a_5_LSB = 600; -const std::vector> FNAV_SVID1_5_bit({{23, 6}}); -const std::vector> FNAV_Deltaa12_1_5_bit({{29, 13}}); +const std::vector> FNAV_SVID1_5_bit({{23, 6}}); +const std::vector> FNAV_Deltaa12_1_5_bit({{29, 13}}); const double FNAV_Deltaa12_5_LSB = TWO_N9; -const std::vector> FNAV_e_1_5_bit({{42, 11}}); +const std::vector> FNAV_e_1_5_bit({{42, 11}}); const double FNAV_e_5_LSB = TWO_N16; -const std::vector> FNAV_w_1_5_bit({{53, 16}}); +const std::vector> FNAV_w_1_5_bit({{53, 16}}); const double FNAV_w_5_LSB = TWO_N15; -const std::vector> FNAV_deltai_1_5_bit({{69, 11}}); +const std::vector> FNAV_deltai_1_5_bit({{69, 11}}); const double FNAV_deltai_5_LSB = TWO_N14; -const std::vector> FNAV_Omega0_1_5_bit({{80, 16}}); +const std::vector> FNAV_Omega0_1_5_bit({{80, 16}}); const double FNAV_Omega0_5_LSB = TWO_N15; -const std::vector> FNAV_Omegadot_1_5_bit({{96, 11}}); +const std::vector> FNAV_Omegadot_1_5_bit({{96, 11}}); const double FNAV_Omegadot_5_LSB = TWO_N33; -const std::vector> FNAV_M0_1_5_bit({{107, 16}}); +const std::vector> FNAV_M0_1_5_bit({{107, 16}}); const double FNAV_M0_5_LSB = TWO_N15; -const std::vector> FNAV_af0_1_5_bit({{123, 16}}); +const std::vector> FNAV_af0_1_5_bit({{123, 16}}); const double FNAV_af0_5_LSB = TWO_N19; -const std::vector> FNAV_af1_1_5_bit({{139, 13}}); +const std::vector> FNAV_af1_1_5_bit({{139, 13}}); const double FNAV_af1_5_LSB = TWO_N38; -const std::vector> FNAV_E5ahs_1_5_bit({{152, 2}}); -const std::vector> FNAV_SVID2_5_bit({{154, 6}}); -const std::vector> FNAV_Deltaa12_2_5_bit({{160, 13}}); -const std::vector> FNAV_e_2_5_bit({{173, 11}}); -const std::vector> FNAV_w_2_5_bit({{184, 16}}); -const std::vector> FNAV_deltai_2_5_bit({{200, 11}}); +const std::vector> FNAV_E5ahs_1_5_bit({{152, 2}}); +const std::vector> FNAV_SVID2_5_bit({{154, 6}}); +const std::vector> FNAV_Deltaa12_2_5_bit({{160, 13}}); +const std::vector> FNAV_e_2_5_bit({{173, 11}}); +const std::vector> FNAV_w_2_5_bit({{184, 16}}); +const std::vector> FNAV_deltai_2_5_bit({{200, 11}}); //const std::vector> FNAV_Omega012_2_5_bit({{210,4}}); // WORD 6 Almanac SVID2(1/2) SVID3 -const std::vector> FNAV_IODa_6_bit({{7, 4}}); +const std::vector> FNAV_IODa_6_bit({{7, 4}}); //const std::vector> FNAV_Omega022_2_6_bit({{10,12}}); -const std::vector> FNAV_Omegadot_2_6_bit({{23, 11}}); -const std::vector> FNAV_M0_2_6_bit({{34, 16}}); -const std::vector> FNAV_af0_2_6_bit({{50, 16}}); -const std::vector> FNAV_af1_2_6_bit({{66, 13}}); -const std::vector> FNAV_E5ahs_2_6_bit({{79, 2}}); -const std::vector> FNAV_SVID3_6_bit({{81, 6}}); -const std::vector> FNAV_Deltaa12_3_6_bit({{87, 13}}); -const std::vector> FNAV_e_3_6_bit({{100, 11}}); -const std::vector> FNAV_w_3_6_bit({{111, 16}}); -const std::vector> FNAV_deltai_3_6_bit({{127, 11}}); -const std::vector> FNAV_Omega0_3_6_bit({{138, 16}}); -const std::vector> FNAV_Omegadot_3_6_bit({{154, 11}}); -const std::vector> FNAV_M0_3_6_bit({{165, 16}}); -const std::vector> FNAV_af0_3_6_bit({{181, 16}}); -const std::vector> FNAV_af1_3_6_bit({{197, 13}}); -const std::vector> FNAV_E5ahs_3_6_bit({{210, 2}}); +const std::vector> FNAV_Omegadot_2_6_bit({{23, 11}}); +const std::vector> FNAV_M0_2_6_bit({{34, 16}}); +const std::vector> FNAV_af0_2_6_bit({{50, 16}}); +const std::vector> FNAV_af1_2_6_bit({{66, 13}}); +const std::vector> FNAV_E5ahs_2_6_bit({{79, 2}}); +const std::vector> FNAV_SVID3_6_bit({{81, 6}}); +const std::vector> FNAV_Deltaa12_3_6_bit({{87, 13}}); +const std::vector> FNAV_e_3_6_bit({{100, 11}}); +const std::vector> FNAV_w_3_6_bit({{111, 16}}); +const std::vector> FNAV_deltai_3_6_bit({{127, 11}}); +const std::vector> FNAV_Omega0_3_6_bit({{138, 16}}); +const std::vector> FNAV_Omegadot_3_6_bit({{154, 11}}); +const std::vector> FNAV_M0_3_6_bit({{165, 16}}); +const std::vector> FNAV_af0_3_6_bit({{181, 16}}); +const std::vector> FNAV_af1_3_6_bit({{197, 13}}); +const std::vector> FNAV_E5ahs_3_6_bit({{210, 2}}); // Galileo E5a-I primary codes const std::string Galileo_E5a_I_PRIMARY_CODE[Galileo_E5a_NUMBER_OF_CODES] = { @@ -274,6 +275,7 @@ const std::string Galileo_E5a_I_PRIMARY_CODE[Galileo_E5a_NUMBER_OF_CODES] = { "84D5B404488AFCC35CFC6EF1CF7A848EE5EE527B7D2D2081EBD8FA8432414FCCB271A43FD618EF95CAF1CEF445B50F02AFDC6B41D5C1F1FF4B6B8F2AB94F90F259383F44246B2D400C3012FD76E2980827C9B5476C4651293CBE9FAA77EFC53E369B94F51BE480EEAA389D88AE421E75EC67C76E30A6FA7EF02500372E4C9AB875EBA1C357C003938B979859B0A914D58F21B3BF1BE8C33A1AF079C5A0A4EA532F93A10F6D96D0A63F3C99E6F06CBC072CC5D71A517FFF40BC260A26E3A46688E79E733E1E2F0010846937689E2998BC769186E0B977AE0A1689245D255AE7D5F34715AD526E824838B62546D9569009A191BA5192535E23142236F4035C90D1405C8530A57B402118FDED2A5DA4B40635D2F95AC7CEAA370686F0AB23AB31DED369BEFB066909B76F2C04039E49FF0CFD323628D03C26F0BD4054C127F21355C33B49F86895D5354C3BBD2C0D38ECD169289F7D8403AA1753B393AC06C887F98315324DBD78F9BFD1AD8880D41D4EA98956EC89BBDAD08F7CFEBF26988EB5AB01D4E49AA8273CAB6AFDFA1CC1C95EDF85284E6570332A0B8242FBA495D87A01A945E61CD36E865CD4F430F04A3B3EE74CE0486B5676F7A938B18E1DB2DAE2FE1C04B3D56892C7394D0B07C5A2F7698D196711DC83FFF6ABDD4E8131E1106EBA23245FB0E2A696E440FB6B0B1CB4DD22C9720AC76F09863711647A7E369FDE5D6911A5FCF987470B8C06C4EF7063B08A8320B4371866789147E9D7C5D477A662A501627F91E95C6E2CB6814651E9DFACD67CA0B1FE62F44081E3BDDB964C1E5ADDC093AD185F0203B4C0F7E3E96811F14C79BC54F2919FCE5B653F6845CF1AC34DA9E4CF52EBA626B739246E25204F9EF2CCF4F5ADBFC53CD8F629FDB82186CB52BEB7136F105D3CFF9CCCC2610BF2C8F943DF5BD03877ED7AFA25CA81C4063E1B97452A937FCF77F1AA068FE2A26F6ECDF662ACDF18391AF7D627C2AA07CF5597B5F33AA0ED4DAC98AA73C8321EBF6918EE568ADEB1A823527AD75CD5BF7ED3EB5633A4EDC8C59DB0A91DA79C248D6894CAF9CB411F302635BEEF1A1C7916C7545B8BE7C577692245E285D32B4FD18E1478F88F8373E22A5CEC6D22EACAD2A41612F05AB2C54A1C03C0512359B0F9C5F91615EF2EA80DE97230480F489FEDA38D52FC84E2F1258CB20FF0E850639B31C2958BA6C064D0D0F4AAEFF313E43C65EFFFBB47CF09F2A122D15F76E8B704DA8F2B8C71449AA49774EBB7B2DC97CF6004D2FF6D37B9C689261189B85CFD50C20C961F22A644F51497377426556B956DB8C899045B175A8B9CB22EFDE535CF487E9D958281E0467539853054FC3475D2E142D58F9201C1DC6B2C1A12B2878F9366E2216405069B7D03852AB37EE83112EF2EE172F4E5317A41653A656A06F6633AF59062A47263A9977A50B9115456A58F9C3424FE7E0CC57DA70FEE0411C1479B4CC2E6E720B01432CFB3C503983B37FFBE38C92E50D6C5795443F73244F6D28AE6270E27D46A25621F86A2BC4259DE6C04CCAA657FE656C640833B290F00A1660329A3F09FFE60152A23925F4D8B0933AC016B5802CA863F66F8CEB5C8383B1180A515AE6C51B5F56597C3A004F8D25F8A6235C97B4DE38468B63E3B859A487AFC4320598EB6D143E5C914409D25F6DFF6E957D575C71D3ECBC6743CCCC03E5F34791744637A994F3ADF86966B4FE911C06F7BA1A6C20A2971D82B64E49721A530D9D5A2319D5BE0F47B8119C5A835CABEC735A935E23CB439970437C6F4CCDE2525EF0D7B1555CBE70280D5E760", "A5029C9EB4623226D321FF78D3C4EAB1F672A8B2B24A09CAEF21F561A851323C05A3C5E136A2DA7104ED19FBFFCAC3FC49B6D598F3060E93552EA6C700B837F7CE04721919B9C96A57B42AA1D832307C7A847091848066CB84947BE5F6B54654479E39F654819D3EF7AF4939FB9F4C9B20CA7F83DA0FDA2F171FDB72455B7ED0D43206992520CDD86B29C48BCC687573AAC4217D0B7DCF852811ADC3ECADDB2B34B4572675CCAEFDAAA01F83561E6E240878F229698185A80E6FECEE89455A72A377C24CE3FECAEC2A34B9CA98D288596D1C769CDEAB06871316CA7D1DDC5862E6282DECE33F362C64A73E57AB266715068932ECC31E62AD2ECFF7C6FBFE213384DA086ADF49E30F432EE2C715D9AC4DEF53A7B09B0D722CAC560FE8CF0059B80428458282F7E81717647D72E321A3E4BEF16FAEF76009BD98B8D9822B771EB62F1D0748E462FB7F3BEE9B12AA86D9629085AEDF8E43E1252EE59970CFF66A6F865C7651EF83F8FE10EB0E2615BF8F5C7F12FC601B0CF795C0D8B7057F54408BEFF86747C0F6F23EF212A9086EADD464A25341AB71FBA4ADED8F599C38FC15E790A5B86E64977C5AC718DD0B47C1A476AC9D7369396144F6288E84F7FFBDE02EC00EEAE8ED415C84648364ECBEC42164514D3E26BFD3187E0641C216FFC57E00DD752CDA581686916221DCD1AF07582391C5FBEF047FD1B7B956B458DE925C02A756FE197233E0304D0E034FF9A176B5B3F5FB683AB41D2691E13F97B3F4EB33238851331197C49C60233232DA0E2610430461876FF6F77FF3CCAF1BB2424B8B347588667B48480476D40BD9E487468CD5AFEB597C750A5E665B4E7C4C169ED08ADFC731FEA928052C4FB85B3064EC07B0CB988E324893B3F084291D964403F0350B7E1B06DFB73362C38318B762A972972BFB76CC5C08B5D47DBA0F3A2473D7749DE9F49F50C4C1620A9EE9FE56296124D72906497411DB87D4D8EC4E1F79BEF27232008A2299F5317FC1A6F455F1B827F1712BC01814F0B9D0CC162B25B804278B9C7BC5FC5616B317F2050234A7AF92FE35A59E22C959C7163DFA5F142022BE5CC4D5EF16D218216C57C2E29DA926436C00DCB82E68E16CA5A07158D8B8864D38A765D14E82175114A28CD97D11D564C8C7B87411589A4FBD49F9900D08939B7A73B5E6466B6F607F8AD22120A559A02BFCEF6456E7AECE8C9B7C9D2B322D2197124C05363B2CBFA58B74CD88877F22A5E5C202FC2C33531125F1518F4F0F38FA788E5E6B3307A75EC73E545391CEA200243DD6D25A5B8654A00B82BA57437BF0ACCB0ED37ED2FED221E54EC12B93AFA6E3939223596075F4C47340355D7222A8234A1F65EDDA42FFF5D19F7FACBF09AA77E7962F4CFBF61A0F26FB18E31A504B371714048874BEB286AFF71B43E4739A17E8AC25FA77121ABBE6E99754AF42F1D0021EA1E3FF088D0734BB191F91A520C96E22B4A28F9A2BD7DF81E8079EE5D0DDCBD517046F12098FAF6920E0EBA10DE8CFB391C63C60D62C1F4BB26BF8B6E421A830575731F67D306CEB5D6FF04637144790EC4AA2F435906320114CB81EB40C22B271FBB065474687AA5880F1DBAAA1744AB3E9B831A932A9208BEA9F5D526C52F5FDA56320E123CFB553E2B71A595DDED2ECBBD6E890B0421D765D2E9FD0D3995DF2A9523A65FE2040710DF16F2A83F510DCA08493DC138541E5681B51EE87D84C9AC11612EB5C06F5A63E22BD6275E35216766D79B215DBD087E9CADA0CEB09BFE435DF9B7809A76DE323B373682B8C58CB4F08D9C708EB050DEC", }; + // Galileo E5a-Q primary codes const std::string Galileo_E5a_Q_PRIMARY_CODE[Galileo_E5a_NUMBER_OF_CODES] = { "515537AD5E5F4216C16046FB0AC50DCDBE5CEE7E3CBB51B6ABB4E87A407B90E0EFD49DE1DE5ED29184E7FF0DC31F75FBB94F46FF6586B36C7771E5A68D060A965ACCF8D640C6B6E4530FDF19DD2491BCAB69ACBCFD3EC7281CCC31253A471B652E21C4CB0B43613EC542266460F0A6199B436BEFD95572DEBEE920A915FD854D17FFD0DF8C74E23B21B28493A0927709709B07C65878C43B69DC501E9D0AA21061ECF173876CAE708C764435832D9D6FCFE62DDF2543016D6325A56D9BF1007886E62E8A832BC32063CB0717D723C5E8C5F0C0EB3960577D364C93060B64EE04A539B7601CC3113E0AEC53CF21AFAD0154DC5CCECF038474E0F4004A65B1EE2801F81968B88C3D35E87CBB126C02D770CC3D32A552883D351DEF47847391484F80646728221F993921BFC14126EE3D9527DE607152724C6D2DD305D3FEA0AAAEDF6509A2FE3248494A54FDA8E3CE7E6BBCE234E4686BA5A19724BA2CB78CFE71A6AF45532EFB286C5BB47BC3C1EEF4E4A8C757786AE974F30A86CD60EBCBFDF5502AA8F643819CBA4301E731ADBA1345B61C0B444FE7B817EA86F8DD749C451AE7D24A68D914F26C918238953E8AE61CC8553213DD6856C7863F9F6BAB1B4C84B225911E7B92BFFC12AC211B2B2CD905877FE976E07057963D47C437FE47D89648053F81AC39E8FD2F3A726866F6693E503CB6F0C3F0AA9B3EE2EA3BCDB16D726E1C6D8B073AA15F64EB68D53B1F8CDAC19C7AC33361226E81F1C793BF188755A3FE1BAC38B91ABBD4F077F7A28983EAFADC346CB941D49492625893453B364D07FE06FE42B160C16FE0462AB6366FFDEE54DC9CE4DCCA21E4E4AE5E92C872D1E4EC6FF6D3063C98A5AA5EE72481A0BDF15152E2A5425AB722101474D0E1EC8401273EA1BE1DAF7403190A94305BD1C7DFBE1F35F65D5CB97E82B7A297047507FFA0012FB73360FB8719C174E78A989A96E60A9184B3F3A8188DE100AB361921D38E8142859C8F0F7D441DB1B2E9687BBD1086643987C83DEE0BE8CED4C83BCC82B62B45311CE4F13ABC55BF5EB1ECDF15F5A07F8B2C42F07FACE0E299E87727E2D534FEBF7B9C3894CC3E2E4127A294B9FA2A671273B174DBB81D247CD2846116500A072DC3962C65FFECD0C0B46DC2AF52882058259C26FDE50BEB319AEECFA1FABA34C069680B9EBAA9D96EEBD7EA30E748213E1283396A2AFC63527624641D4E1F1022A973B1898BD4CEF4D712B49371A51D60E08F42ED1EA90AC49EEFBCC53E7F9E899DD1AA4056F11462DF1A4C81620A73C831CEB897430A22252B901EC3D6F3DF58EF26422F796EA31AA4E0E9CE5B4A9C312A22305E298FEB3B3628283D405EDF726937327D90C542434BA3B60684584A9DB244839D2ACBCD7EF147A541E35687B5B8F5F07764973112D20D1ED75DC31F6A938542B42EFAAEE0F11B0583AA4925C3132356200E8D6BDB3127B975F4115A7A8A1C471836E3C5450B501A24D4A1308BB319AA827222B550F253F64B6F7D2322C6A2D3012FEC265A66A60102A3340CBDAB900DFDB36693D41DAD8DDB8875F8C3BE76AD5355DD81D67AAEBFFFE9458E522BE0312E60F63DD92F25C0D7CF82F223AEC0BD7456752CBD5151FEB5368F8857EAFAA90E8C7499B75D46EC4CA20BA8A24C90C016B5BD2CD7864828C6140E98EDB9509AD1194F56D49675D077DE92CD481B469E3A37F7DF0D5392DA4CE4CB282530F1C73482CC0926B877B00B0CE49FAD21E4C26194C7E950E0078F3854EF88755E08E9380165C584A3DBF1ECEF6A31B224FC321326B93797BFE8", @@ -327,8 +329,10 @@ const std::string Galileo_E5a_Q_PRIMARY_CODE[Galileo_E5a_NUMBER_OF_CODES] = { "71BB1B2E833793D854F8A9A81E6A6947057B9571F2BA99380DDB25D878D6B48F09ED7DBFACE92B6B82F413E038128F6128AF3BC467E9A4DF2861DAAC674B6D948A10F28F7D43657FEE26577AF438A2F4422186930702EBC6C9173E661D59CE7594DF95B861F9D12EB060FCD3BA43159C9A1BDC1EF13E04893E411267331588CF4831978469FF569C1A738C54001BB5CF4FABD289075A165EDE0A58F6CF6D215D306A7840CBECD0E87E3AD186F7A67A967373551E13D2956E5C578A7F5BD50E2D570F9B914848D46A640913EBED2E2ABFB86916BC34EEB3E8A671AD771F6D3780B6FEC143E26F53B02977255314BAE9A2CD9E5BA2B49C73226FDC724A859F8BAD3A9FACA1B0E5F2DFE7E1E45DB6D4BE2B76535A817F94594A4541C01BB62AA83A690B6D84FC13B632972C61D940F2C9D32837413AF8E42045ECA3072CD044B2183400CE63C418879D13FD281A8D0835256DDD2BC3C9750C1D44CF1037FD7264B7716398FCF1D31CFFD0B7C52C6370E4CE6FC163B40436490A757465B20B8890C3B5C0AFB971ABFD01796569E3BC73C13D1E4B1FBC1CDCE59D21B6B110272E5770C589603FE67779A49AD0EC66910A2BF4D8C8ECC18A32EF92F502126A5DC3DE618233B9914A9608B2F17E5161115D9A3BEF1D5701A9D465A1437DE24371C9179800CB5728A7F3D734A2A706BC64D356BDF591389970B6CC139AC510A98E3C75F20120450CE45373AAEA6A279BBD17221BCD32ECF82C11B4C1CEE0A44792CF56978D3D2399F7ECDE9F8D9217F8BA22770E210D0F1AA852178B872E296762873765A73DEC08873C04ED69C995C5751B97DEC23B94CA674FE3F66211317B074D8203EC530A20B6E6DD21AB55895BEE1CBD0876183D652F4A0D2EFC95749F8F192F860BEA534598FD709B396C209CEAE4D9190980733E7E98C8ABE52A53C68D86053B56BA6FCAB5C827292D729CB8BFD1FC8CAFCDE15E4527B604018F28AA16C1E913F55461AF87C9A7BE1A742002E52B3A14EC30B259DDE7BB892CEAF77D25B7670B339B334878F697C00CE6740117AE7C67DF3F8A7BEAC89D4872682C47F368F835AFD7ECF0D8471AD01468B7BBB0A974EC469A8F79ECF8D379DC13685D2A8F6F19CE102C3DE34B11422AFB42E894C8D00F606296DABA7123FCE039ED27324D60E853BA94DC638454088281335D437A954333FF1A8D08E2A4D25CB3BA0D08BF6625E25EAD3C1EBFA2666AA49550578D3763ECDCE81303B53F18B00C8900AF4E0532C5ECBC94513DD9F50BE511CFE4D3DDBB3F112AE148DB062B2EADDB901CDA6AB6BF59D37F356AB34AF97D3DAAAA417642E87C9B95AA546C682ED641214605F82A4F486C9C72576106F76D7152615EC8E77187D4485071CFC6B0AE44880442790696E057A3AE20C860691353B3F6BEC5F1C2DA07563B423BC01E0334099571158A432441256D7C409B7B6EF26442075ED17E2BE37F8EBC049CFBE0FA89CDA7A58DD32C417B34E899FBE86E2FAB8D30846DA17144A6A66AAE1C24FCFABDA5B573FD2D6337226B5E49BB031B4D2B455B6DB871076F67AC03C3A73CEC01BD0B1EC42ABD177127E62A66FE8E475B982B4490F0877466EEFC7317A703C5C07937340ED4B53E5DE5325197FA31B8C8E05AA2222064EE5D7C06D4A1EB53151F75C94A2E259688CA0716548465C5C255D81FF10BACC2C13098ED8CF7F5B15193EE14FB5D258E95EDCC93E9796FA823892C705A5771D561787C12592D269D657FBB71F021F365B7453D50C35F748FB2B7F36DF28769B81EF12A26A237FB0239C173559540", "53DA0E7B84741AA9E225483630169ACBCC03EB8CDA28B7BDA685C756D66B14488A2D0AEF7E6CB2D80F2726327257B7284B93EA1B56AB80FAE668C04FA49FCD658D896A997685E1EDB4DDF85456B37F32FC8CDE50882EF0F09BE4ED4AB9A425806A49E8347A42A50B38FA8D1DA2FD2C9438618B6701DEE159060C186D50170F24F38E07B185E3272EAEA4A0A7CA41A69C69E9D95E271287D3AB8284146A58440EA131A7F47D73CB2BCF40FE3A58E1B998C2E5EF9CEEC8EA2F8467BB7757C03A99FC8F014EE933A7080CD46625A2A7A251B7A37E4208956A8C9BD35E6F8674BC06FCAA5DD04A2558C9665C7985014D3AD95ED256FAFA358962EF5BB26AE2FCE899392DF858F99303E2417BCA7672E991FEB891F5DFCA2D461148367C5C0DE1460BF557194533DAF01A5E8E0E43D57B825AF7EEFF163DAA23B9F95C063A26B3D213459D885AA96023715CD21DFA2A2250F7610B78A77123443BD06EFB7DC85D1F16D0019D2937C3DEC4DE6389485ABB21642B6E41ADD43CE96F228C08DF6288A647EC2FE96032B6DCD651FF950B72964EE08FC2030272E3F601DB7F7E770E655389CA6CFA2F9B87CE76FB0E0CDCA4EEE5E80FC756BE46CC09F84BDB34ADA2AFC024ABDE0066ED939F8EBC236CB3F577C1BFD741F9D101A038EC86AB0A85462BAFB2E484D6722499A6310FA449D979030B2A21206D44225800BE2228FA00AE6D92C8DA652E1B003BD2734D30557B735CC2A591E090394DB791245C22B4D29E706476593B6F90C694C5B87BBB0FA2C479E292A768A9687A713336A21D1199186F852C41F586E9BBC64004D8BB6814BFE739834C99923177AAF87B926D56A7AFC0879C027332A60951C84E9314380A5A78E1196D094F15D856AA36742825D2B397156BCAD8ABE7291FB41DB4365AAE49CA82CA066D3B4366D3122ABBC00F05559DAFEBA9F98361DDAEF068D60B18265E7184C4D6BC9C3619CFF5C758090FF6398CCCEB78176D2A8A2A4B9854C4ACF5CB614DC1CA0E15E7E85442241D48FD3D6E851A5D3947FA769560928948FA26FA16EFBD2159994BD92B3D6B0C62818C91D4724413A7F40B2A2D67F4FC97B5DF6A7E3CEC03158E201D6643F402D3DD6995A42900D46C2881198CAD28A27489F5116ECEC3E38D999B2020E0C381DB3B8230811270D75950D9BB61548802DBBCB68ED8C7BCCB50D606BE400BECF873498621E66ABD2AA179B3E90E055C3719CE2FE047F815B95B065BA086B467AF4124E276F8CEAD000BCA5499D36217B250009A7B43E81CB3F8B1A3238EE436FE61F2F942796DBCBE570BB4FC783B35C3CA31BDD432B33AD75B08107253E8F910EFE0D0B5453A8A055D884892278688B3ECA612452B590AF38DBDD9A7070C5610E7A3CA6C91D24438E7F45E7A2A330F164AEDFFF1789D5E875EEF121298DB79C77278ABFEC3FE3DF843C46F40E847272EB2669BABA808C38E31F13516D5066AF4DFCDE6EDB2FF0B0A4CE9FA9B4101F6F144B02384868617CD39175852E065473D6F566CD18D7403FFD24DD33ADDB52C7CC22167E49102C46DC369A92CE2D2FCB81B4D1F14B7CD2F80A65D8FBD20FDAA23219873ACB8CF934E68D6F8FED6B41193CFAB1F44CE4BFC7C67DE1E8804B47DFD7E8AE281E19846AEB6FF94AE7E7CF6FFAB46242843811E6C5BDB78157C76DF4F92FD3653D7FA5978316EB055059C6A2B6306C957418860A88F63355E76D96F4727128D9B3EB98501AF5B093F2C314F98EA2CDB89468E1BD51138CBF25E8B911C26B97DCCA47F1A1D6C1CD415A5079A756B8A8715DD3164", }; + // Galileo E5a-I secondary code const std::string Galileo_E5a_I_SECONDARY_CODE = "10000100001011101001"; + // Galileo E5a-Q secondary codes const std::string Galileo_E5a_Q_SECONDARY_CODE[Galileo_E5a_NUMBER_OF_CODES] = { "1000001111110110111101101001110110001111011011100001010101000001000111111011100011001001101100011100", diff --git a/src/core/system_parameters/gps_ref_location.cc b/src/core/system_parameters/agnss_ref_location.cc similarity index 86% rename from src/core/system_parameters/gps_ref_location.cc rename to src/core/system_parameters/agnss_ref_location.cc index a72d42da3..c59f8fbc4 100644 --- a/src/core/system_parameters/gps_ref_location.cc +++ b/src/core/system_parameters/agnss_ref_location.cc @@ -1,6 +1,6 @@ /*! - * \file gps_ref_location.cc - * \brief Interface of a GPS REFERENCE LOCATION storage + * \file agnss_ref_location.cc + * \brief Interface of an Assisted GNSS REFERENCE LOCATION storage * * \author Javier Arribas, 2013. jarribas(at)cttc.es * @@ -29,9 +29,9 @@ * ------------------------------------------------------------------------- */ -#include "gps_ref_location.h" +#include "agnss_ref_location.h" -Gps_Ref_Location::Gps_Ref_Location() +Agnss_Ref_Location::Agnss_Ref_Location() { valid = false; lat = 0.0; diff --git a/src/core/system_parameters/gps_ref_location.h b/src/core/system_parameters/agnss_ref_location.h similarity index 86% rename from src/core/system_parameters/gps_ref_location.h rename to src/core/system_parameters/agnss_ref_location.h index f00448ce2..083305987 100644 --- a/src/core/system_parameters/gps_ref_location.h +++ b/src/core/system_parameters/agnss_ref_location.h @@ -1,6 +1,6 @@ /*! - * \file gps_ref_location.h - * \brief Interface of a GPS REFERENCE LOCATION storage + * \file agnss_ref_location.h + * \brief Interface of an Assisted GNSS REFERENCE LOCATION storage * \author Javier Arribas, 2013. jarribas(at)cttc.es * * ------------------------------------------------------------------------- @@ -29,18 +29,18 @@ */ -#ifndef GNSS_SDR_GPS_REF_LOCATION_H_ -#define GNSS_SDR_GPS_REF_LOCATION_H_ +#ifndef GNSS_SDR_AGNSS_REF_LOCATION_H_ +#define GNSS_SDR_AGNSS_REF_LOCATION_H_ #include #include /*! - * \brief Interface of a GPS REFERENCE LOCATION storage + * \brief Interface of an Assisted GNSS REFERENCE LOCATION storage * */ -class Gps_Ref_Location +class Agnss_Ref_Location { public: bool valid; @@ -50,7 +50,7 @@ public: /*! * Default constructor */ - Gps_Ref_Location(); + Agnss_Ref_Location(); template diff --git a/src/core/system_parameters/gps_ref_time.cc b/src/core/system_parameters/agnss_ref_time.cc similarity index 88% rename from src/core/system_parameters/gps_ref_time.cc rename to src/core/system_parameters/agnss_ref_time.cc index b663abab7..0d1e8c687 100644 --- a/src/core/system_parameters/gps_ref_time.cc +++ b/src/core/system_parameters/agnss_ref_time.cc @@ -1,6 +1,6 @@ /*! - * \file gps_ref_time.cc - * \brief Interface of a GPS REFERENCE TIME storage + * \file agnss_ref_time.cc + * \brief Interface of an Assisted GNSS REFERENCE TIME storage * * \author Javier Arribas, 2013. jarribas(at)cttc.es * @@ -29,9 +29,9 @@ * ------------------------------------------------------------------------- */ -#include "gps_ref_time.h" +#include "agnss_ref_time.h" -Gps_Ref_Time::Gps_Ref_Time() +Agnss_Ref_Time::Agnss_Ref_Time() { valid = false; d_TOW = 0.0; diff --git a/src/core/system_parameters/gps_ref_time.h b/src/core/system_parameters/agnss_ref_time.h similarity index 87% rename from src/core/system_parameters/gps_ref_time.h rename to src/core/system_parameters/agnss_ref_time.h index 84af6d973..574d9106a 100644 --- a/src/core/system_parameters/gps_ref_time.h +++ b/src/core/system_parameters/agnss_ref_time.h @@ -1,6 +1,6 @@ /*! - * \file gps_ref_time.h - * \brief Interface of a GPS REFERENCE TIME storage + * \file agnss_ref_time.h + * \brief Interface of an Assisted GNSS REFERENCE TIME storage * \author Javier Arribas, 2013. jarribas(at)cttc.es * * ------------------------------------------------------------------------- @@ -29,18 +29,18 @@ */ -#ifndef GNSS_SDR_GPS_REF_TIME_H_ -#define GNSS_SDR_GPS_REF_TIME_H_ +#ifndef GNSS_SDR_AGNSS_REF_TIME_H_ +#define GNSS_SDR_AGNSS_REF_TIME_H_ #include #include /*! - * \brief Interface of a GPS REFERENCE TIME storage + * \brief Interface of an Assisted GNSS REFERENCE TIME storage * */ -class Gps_Ref_Time +class Agnss_Ref_Time { public: bool valid; @@ -51,7 +51,7 @@ public: /*! * Default constructor */ - Gps_Ref_Time(); + Agnss_Ref_Time(); template diff --git a/src/core/system_parameters/galileo_almanac.cc b/src/core/system_parameters/galileo_almanac.cc index bce27a9aa..6dbc7b25e 100644 --- a/src/core/system_parameters/galileo_almanac.cc +++ b/src/core/system_parameters/galileo_almanac.cc @@ -1,7 +1,7 @@ /*! * \file galileo_almanac.cc - * \brief Implementation of a Galileo ALMANAC storage - * \author Javier Arribas, 2013. jarribas(at)cttc.es + * \brief Interface of a Galileo ALMANAC storage + * \author Carles Fernandez, 2018. cfernandez(at)cttc.cat * * ------------------------------------------------------------------------- * @@ -30,66 +30,23 @@ #include "galileo_almanac.h" + Galileo_Almanac::Galileo_Almanac() { - /*Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number*/ - IOD_a_7 = 0; - WN_a_7 = 0.0; - t0a_7 = 0.0; - SVID1_7 = 0; - DELTA_A_7 = 0.0; - e_7 = 0.0; - omega_7 = 0.0; - delta_i_7 = 0.0; - Omega0_7 = 0.0; - Omega_dot_7 = 0.0; - M0_7 = 0.0; - - /*Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2)*/ - IOD_a_8 = 0; - af0_8 = 0.0; - af1_8 = 0.0; - E5b_HS_8 = 0.0; - E1B_HS_8 = 0.0; - E5a_HS_8 = 0.0; - SVID2_8 = 0; - DELTA_A_8 = 0.0; - e_8 = 0.0; - omega_8 = 0.0; - delta_i_8 = 0.0; - Omega0_8 = 0.0; - Omega_dot_8 = 0.0; - - /*Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2)*/ - IOD_a_9 = 0; - WN_a_9 = 0.0; - t0a_9 = 0.0; - M0_9 = 0.0; - af0_9 = 0.0; - af1_9 = 0.0; - E5b_HS_9 = 0.0; - E1B_HS_9 = 0.0; - E5a_HS_9 = 0.0; - SVID3_9 = 0; - DELTA_A_9 = 0.0; - e_9 = 0.0; - omega_9 = 0.0; - delta_i_9 = 0.0; - - /*Word type 10: Almanac for SVID3 (2/2)*/ - IOD_a_10 = 0; - Omega0_10 = 0.0; - Omega_dot_10 = 0.0; - M0_10 = 0.0; - af0_10 = 0.0; - af1_10 = 0.0; - E5b_HS_10 = 0.0; - E1B_HS_10 = 0.0; - E5a_HS_10 = 0.0; - - /*GPS to Galileo GST conversion parameters*/ - A_0G_10 = 0.0; - A_1G_10 = 0.0; - t_0G_10 = 0.0; - WN_0G_10 = 0.0; + i_satellite_PRN = 0U; + i_Toa = 0; + i_WNa = 0; + i_IODa = 0; + d_Delta_i = 0.0; + d_M_0 = 0.0; + d_e_eccentricity = 0.0; + d_Delta_sqrt_A = 0.0; + d_OMEGA0 = 0.0; + d_OMEGA = 0.0; + d_OMEGA_DOT = 0.0; + d_A_f0 = 0.0; + d_A_f1 = 0.0; + E5b_HS = 0; + E1B_HS = 0; + E5a_HS = 0; } diff --git a/src/core/system_parameters/galileo_almanac.h b/src/core/system_parameters/galileo_almanac.h index 3744ed87d..022d778be 100644 --- a/src/core/system_parameters/galileo_almanac.h +++ b/src/core/system_parameters/galileo_almanac.h @@ -1,8 +1,8 @@ /*! * \file galileo_almanac.h * \brief Interface of a Galileo ALMANAC storage - * \author Javier Arribas, 2013. jarribas(at)cttc.es - * \author Mara Branzanti 2013. mara.branzanti(at)gmail.com + * \author Carles Fernandez, 2018. cfernandez(at)cttc.cat + * * ------------------------------------------------------------------------- * * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) @@ -28,80 +28,65 @@ * ------------------------------------------------------------------------- */ + #ifndef GNSS_SDR_GALILEO_ALMANAC_H_ #define GNSS_SDR_GALILEO_ALMANAC_H_ +#include +#include /*! - * \brief This class is a storage for the GALILEO ALMANAC data as described in GALILEO ICD - * - * See https://www.gsc-europa.eu/system/files/galileo_documents/Galileo_OS_SIS_ICD.pdf paragraph 5.1.10 + * \brief This class is a storage for the Galileo SV ALMANAC data */ class Galileo_Almanac { public: - /*Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number*/ - int IOD_a_7; - double WN_a_7; - double t0a_7; - int SVID1_7; - double DELTA_A_7; - double e_7; - double omega_7; - double delta_i_7; - double Omega0_7; - double Omega_dot_7; - double M0_7; + uint32_t i_satellite_PRN; //!< SV PRN NUMBER + int32_t i_Toa; + int32_t i_WNa; + int32_t i_IODa; + double d_Delta_i; //!< Inclination at reference time relative to i0 = 56º [semi-circles] + double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles] + double d_e_eccentricity; //!< Eccentricity [dimensionless] + double d_Delta_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)] + double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] + double d_OMEGA; //!< Argument of Perigee [semi-cicles] + double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s] + double d_A_f0; //!< Coefficient 0 of code phase offset model [s] + double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s] + int32_t E5b_HS; + int32_t E1B_HS; + int32_t E5a_HS; - /*Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2)*/ - int IOD_a_8; - double af0_8; - double af1_8; - double E5b_HS_8; - double E1B_HS_8; - double E5a_HS_8; - int SVID2_8; - double DELTA_A_8; - double e_8; - double omega_8; - double delta_i_8; - double Omega0_8; - double Omega_dot_8; + /*! + * Default constructor + */ + Galileo_Almanac(); - /*Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2)*/ - int IOD_a_9; - double WN_a_9; - double t0a_9; - double M0_9; - double af0_9; - double af1_9; - double E5b_HS_9; - double E1B_HS_9; - double E5a_HS_9; - int SVID3_9; - double DELTA_A_9; - double e_9; - double omega_9; - double delta_i_9; + template - /*Word type 10: Almanac for SVID3 (2/2)*/ - int IOD_a_10; - double Omega0_10; - double Omega_dot_10; - double M0_10; - double af0_10; - double af1_10; - double E5b_HS_10; - double E1B_HS_10; - double E5a_HS_10; - - /*GPS to Galileo GST conversion parameters*/ - double A_0G_10; - double A_1G_10; - double t_0G_10; - double WN_0G_10; - - Galileo_Almanac(); //!< Default constructor + void serialize(Archive& ar, const unsigned int version) + { + if (version) + { + }; + ar& BOOST_SERIALIZATION_NVP(i_satellite_PRN); + ar& BOOST_SERIALIZATION_NVP(i_Toa); + ar& BOOST_SERIALIZATION_NVP(i_WNa); + ar& BOOST_SERIALIZATION_NVP(i_IODa); + ar& BOOST_SERIALIZATION_NVP(d_Delta_i); + ar& BOOST_SERIALIZATION_NVP(d_M_0); + ar& BOOST_SERIALIZATION_NVP(d_e_eccentricity); + ar& BOOST_SERIALIZATION_NVP(d_Delta_sqrt_A); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA0); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA_DOT); + ar& BOOST_SERIALIZATION_NVP(d_A_f0); + ar& BOOST_SERIALIZATION_NVP(d_A_f1); + ar& BOOST_SERIALIZATION_NVP(E5b_HS); + ar& BOOST_SERIALIZATION_NVP(E1B_HS); + ar& BOOST_SERIALIZATION_NVP(E5a_HS); + } }; #endif diff --git a/src/core/system_parameters/galileo_almanac_helper.cc b/src/core/system_parameters/galileo_almanac_helper.cc new file mode 100644 index 000000000..2fbd3e689 --- /dev/null +++ b/src/core/system_parameters/galileo_almanac_helper.cc @@ -0,0 +1,156 @@ +/*! + * \file galileo_almanac_helper.cc + * \brief Implementation of a Galileo ALMANAC storage helper + * \author Javier Arribas, 2013. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "galileo_almanac_helper.h" + +Galileo_Almanac_Helper::Galileo_Almanac_Helper() +{ + // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number + IOD_a_7 = 0; + WN_a_7 = 0; + t0a_7 = 0; + SVID1_7 = 0; + DELTA_A_7 = 0.0; + e_7 = 0.0; + omega_7 = 0.0; + delta_i_7 = 0.0; + Omega0_7 = 0.0; + Omega_dot_7 = 0.0; + M0_7 = 0.0; + + // Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2) + IOD_a_8 = 0; + af0_8 = 0.0; + af1_8 = 0.0; + E5b_HS_8 = 0; + E1B_HS_8 = 0; + E5a_HS_8 = 0; + SVID2_8 = 0; + DELTA_A_8 = 0.0; + e_8 = 0.0; + omega_8 = 0.0; + delta_i_8 = 0.0; + Omega0_8 = 0.0; + Omega_dot_8 = 0.0; + + // Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2) + IOD_a_9 = 0; + WN_a_9 = 0; + t0a_9 = 0; + M0_9 = 0.0; + af0_9 = 0.0; + af1_9 = 0.0; + E5b_HS_9 = 0; + E1B_HS_9 = 0; + E5a_HS_9 = 0; + SVID3_9 = 0; + DELTA_A_9 = 0.0; + e_9 = 0.0; + omega_9 = 0.0; + delta_i_9 = 0.0; + + // Word type 10: Almanac for SVID3 (2/2) + IOD_a_10 = 0; + Omega0_10 = 0.0; + Omega_dot_10 = 0.0; + M0_10 = 0.0; + af0_10 = 0.0; + af1_10 = 0.0; + E5b_HS_10 = 0; + E1B_HS_10 = 0; + E5a_HS_10 = 0; +} + +Galileo_Almanac Galileo_Almanac_Helper::get_almanac(int i) +{ + Galileo_Almanac galileo_almanac; + switch (i) + { + case 1: + galileo_almanac.i_satellite_PRN = this->SVID1_7; + galileo_almanac.i_Toa = this->t0a_7; + galileo_almanac.i_WNa = this->WN_a_7; + galileo_almanac.i_IODa = this->IOD_a_7; + galileo_almanac.d_Delta_i = this->delta_i_7; + galileo_almanac.d_M_0 = this->M0_7; + galileo_almanac.d_e_eccentricity = this->e_7; + galileo_almanac.d_Delta_sqrt_A = this->DELTA_A_7; + galileo_almanac.d_OMEGA0 = this->Omega0_7; + galileo_almanac.d_OMEGA = this->omega_7; + galileo_almanac.d_OMEGA_DOT = this->Omega_dot_7; + galileo_almanac.d_A_f0 = this->af0_8; + galileo_almanac.d_A_f1 = this->af1_8; + galileo_almanac.E5b_HS = this->E5b_HS_8; + galileo_almanac.E1B_HS = this->E1B_HS_8; + galileo_almanac.E5a_HS = this->E5a_HS_8; + break; + + case 2: + galileo_almanac.i_satellite_PRN = this->SVID2_8; + galileo_almanac.i_Toa = this->t0a_9; + galileo_almanac.i_WNa = this->WN_a_9; + galileo_almanac.i_IODa = this->IOD_a_9; + galileo_almanac.d_Delta_i = this->delta_i_8; + galileo_almanac.d_M_0 = this->M0_9; + galileo_almanac.d_e_eccentricity = this->e_8; + galileo_almanac.d_Delta_sqrt_A = this->DELTA_A_8; + galileo_almanac.d_OMEGA0 = this->Omega0_8; + galileo_almanac.d_OMEGA = this->omega_8; + galileo_almanac.d_OMEGA_DOT = this->Omega_dot_8; + galileo_almanac.d_A_f0 = this->af0_9; + galileo_almanac.d_A_f1 = this->af1_9; + galileo_almanac.E1B_HS = this->E1B_HS_9; + galileo_almanac.E5a_HS = this->E5a_HS_9; + break; + + case 3: + galileo_almanac.i_satellite_PRN = this->SVID3_9; + galileo_almanac.i_Toa = this->t0a_9; + galileo_almanac.i_WNa = this->WN_a_9; + galileo_almanac.i_IODa = this->IOD_a_10; + galileo_almanac.d_Delta_i = this->delta_i_9; + galileo_almanac.d_M_0 = this->M0_10; + galileo_almanac.d_e_eccentricity = this->e_9; + galileo_almanac.d_Delta_sqrt_A = this->DELTA_A_9; + galileo_almanac.d_OMEGA0 = this->Omega0_10; + galileo_almanac.d_OMEGA = this->omega_9; + galileo_almanac.d_OMEGA_DOT = this->Omega_dot_10; + galileo_almanac.d_A_f0 = this->af0_10; + galileo_almanac.d_A_f1 = this->af1_10; + galileo_almanac.E5b_HS = this->E5b_HS_10; + galileo_almanac.E1B_HS = this->E1B_HS_10; + galileo_almanac.E5a_HS = this->E5a_HS_10; + break; + + default: + break; + } + return galileo_almanac; +} diff --git a/src/core/system_parameters/galileo_almanac_helper.h b/src/core/system_parameters/galileo_almanac_helper.h new file mode 100644 index 000000000..1b2e1b28e --- /dev/null +++ b/src/core/system_parameters/galileo_almanac_helper.h @@ -0,0 +1,104 @@ +/*! + * \file galileo_almanac_helper.h + * \brief Interface of a Galileo ALMANAC storage helper + * \author Javier Arribas, 2013. jarribas(at)cttc.es + * \author Mara Branzanti 2013. mara.branzanti(at)gmail.com + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GALILEO_ALMANAC_HELPER_H_ +#define GNSS_SDR_GALILEO_ALMANAC_HELPER_H_ + +#include "galileo_almanac.h" +#include + +/*! + * \brief This class is a storage for the GALILEO ALMANAC data as described in GALILEO ICD + * + * See https://www.gsc-europa.eu/system/files/galileo_documents/Galileo_OS_SIS_ICD.pdf paragraph 5.1.10 + */ +class Galileo_Almanac_Helper +{ +public: + // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number + int32_t IOD_a_7; + int32_t WN_a_7; + double t0a_7; + int32_t SVID1_7; + double DELTA_A_7; + double e_7; + double omega_7; + double delta_i_7; + double Omega0_7; + double Omega_dot_7; + double M0_7; + + // Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2) + int32_t IOD_a_8; + double af0_8; + double af1_8; + int32_t E5b_HS_8; + int32_t E1B_HS_8; + int32_t E5a_HS_8; + int32_t SVID2_8; + double DELTA_A_8; + double e_8; + double omega_8; + double delta_i_8; + double Omega0_8; + double Omega_dot_8; + + // Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2) + int32_t IOD_a_9; + int32_t WN_a_9; + double t0a_9; + double M0_9; + double af0_9; + double af1_9; + int32_t E5b_HS_9; + int32_t E1B_HS_9; + int32_t E5a_HS_9; + int32_t SVID3_9; + double DELTA_A_9; + double e_9; + double omega_9; + double delta_i_9; + + // Word type 10: Almanac for SVID3 (2/2) + int32_t IOD_a_10; + double Omega0_10; + double Omega_dot_10; + double M0_10; + double af0_10; + double af1_10; + int32_t E5b_HS_10; + int32_t E1B_HS_10; + int32_t E5a_HS_10; + + Galileo_Almanac_Helper(); //!< Default constructor + Galileo_Almanac get_almanac(int i); +}; + +#endif diff --git a/src/core/system_parameters/galileo_ephemeris.cc b/src/core/system_parameters/galileo_ephemeris.cc index 926257933..0c1021048 100644 --- a/src/core/system_parameters/galileo_ephemeris.cc +++ b/src/core/system_parameters/galileo_ephemeris.cc @@ -39,40 +39,43 @@ Galileo_Ephemeris::Galileo_Ephemeris() IOD_ephemeris = 0; IOD_nav_1 = 0; SV_ID_PRN_4 = 0; - M0_1 = 0; // Mean anomaly at reference time [semi-circles] - delta_n_3 = 0; // Mean motion difference from computed value [semi-circles/sec] - e_1 = 0; // Eccentricity - A_1 = 0; // Square root of the semi-major axis [meters^1/2] - OMEGA_0_2 = 0; // Longitude of ascending node of orbital plane at weekly epoch [semi-circles] - i_0_2 = 0; // Inclination angle at reference time [semi-circles] - omega_2 = 0; // Argument of perigee [semi-circles] - OMEGA_dot_3 = 0; // Rate of right ascension [semi-circles/sec] - iDot_2 = 0; // Rate of inclination angle [semi-circles/sec] - C_uc_3 = 0; // Amplitude of the cosine harmonic correction term to the argument of latitude [radians] - C_us_3 = 0; // Amplitude of the sine harmonic correction term to the argument of latitude [radians] - C_rc_3 = 0; // Amplitude of the cosine harmonic correction term to the orbit radius [meters] - C_rs_3 = 0; // Amplitude of the sine harmonic correction term to the orbit radius [meters] - C_ic_4 = 0; // Amplitude of the cosine harmonic correction term to the angle of inclination [radians] - C_is_4 = 0; // Amplitude of the sine harmonic correction term to the angle of inclination [radians] - t0e_1 = 0; // Ephemeris reference time [s] - /*Clock correction parameters*/ - t0c_4 = 0; // Clock correction data reference Time of Week [sec] - af0_4 = 0; // SV clock bias correction coefficient [s] - af1_4 = 0; // SV clock drift correction coefficient [s/s] - af2_4 = 0; // SV clock drift rate correction coefficient [s/s^2] - /*GST*/ - WN_5 = 0; - TOW_5 = 0; + M0_1 = 0.0; // Mean anomaly at reference time [semi-circles] + delta_n_3 = 0.0; // Mean motion difference from computed value [semi-circles/sec] + e_1 = 0.0; // Eccentricity + A_1 = 0.0; // Square root of the semi-major axis [meters^1/2] + OMEGA_0_2 = 0.0; // Longitude of ascending node of orbital plane at weekly epoch [semi-circles] + i_0_2 = 0.0; // Inclination angle at reference time [semi-circles] + omega_2 = 0.0; // Argument of perigee [semi-circles] + OMEGA_dot_3 = 0.0; // Rate of right ascension [semi-circles/sec] + iDot_2 = 0.0; // Rate of inclination angle [semi-circles/sec] + C_uc_3 = 0.0; // Amplitude of the cosine harmonic correction term to the argument of latitude [radians] + C_us_3 = 0.0; // Amplitude of the sine harmonic correction term to the argument of latitude [radians] + C_rc_3 = 0.0; // Amplitude of the cosine harmonic correction term to the orbit radius [meters] + C_rs_3 = 0.0; // Amplitude of the sine harmonic correction term to the orbit radius [meters] + C_ic_4 = 0.0; // Amplitude of the cosine harmonic correction term to the angle of inclination [radians] + C_is_4 = 0.0; // Amplitude of the sine harmonic correction term to the angle of inclination [radians] + t0e_1 = 0.0; // Ephemeris reference time [s] + + // Clock correction parameters + t0c_4 = 0.0; // Clock correction data reference Time of Week [sec] + af0_4 = 0.0; // SV clock bias correction coefficient [s] + af1_4 = 0.0; // SV clock drift correction coefficient [s/s] + af2_4 = 0.0; // SV clock drift rate correction coefficient [s/s^2] + + // GST + WN_5 = 0.0; + TOW_5 = 0.0; + // SV status - SISA_3 = 0; - E5a_HS = 0; - E5b_HS_5 = 0; - E1B_HS_5 = 0; + SISA_3 = 0.0; + E5a_HS = 0U; + E5b_HS_5 = 0.0; + E1B_HS_5 = 0.0; E5a_DVS = false; - E5b_DVS_5 = 0; - E1B_DVS_5 = 0; - BGD_E1E5a_5 = 0; // E1-E5a Broadcast Group Delay [s] - BGD_E1E5b_5 = 0; // E1-E5b Broadcast Group Delay [s] + E5b_DVS_5 = 0.0; + E1B_DVS_5 = 0.0; + BGD_E1E5a_5 = 0.0; // E1-E5a Broadcast Group Delay [s] + BGD_E1E5b_5 = 0.0; // E1-E5b Broadcast Group Delay [s] Galileo_satClkDrift = 0.0; Galileo_dtr = 0.0; @@ -81,12 +84,13 @@ Galileo_Ephemeris::Galileo_Ephemeris() d_satpos_X = 0.0; d_satpos_Y = 0.0; d_satpos_Z = 0.0; + // Satellite velocity d_satvel_X = 0.0; d_satvel_Y = 0.0; d_satvel_Z = 0.0; - i_satellite_PRN = 0; + i_satellite_PRN = 0U; } @@ -170,7 +174,7 @@ double Galileo_Ephemeris::sv_clock_relativistic_term(double transmitTime) // Sa E = M; // --- Iteratively compute eccentric anomaly ---------------------------- - for (int ii = 1; ii < 20; ii++) + for (int32_t ii = 1; ii < 20; ii++) { E_old = E; E = M + e_1 * sin(E); @@ -230,7 +234,7 @@ void Galileo_Ephemeris::satellitePosition(double transmitTime) E = M; // --- Iteratively compute eccentric anomaly ---------------------------- - for (int ii = 1; ii < 20; ii++) + for (int32_t ii = 1; ii < 20; ii++) { E_old = E; E = M + e_1 * sin(E); diff --git a/src/core/system_parameters/galileo_ephemeris.h b/src/core/system_parameters/galileo_ephemeris.h index 6704499b5..fd844adf2 100644 --- a/src/core/system_parameters/galileo_ephemeris.h +++ b/src/core/system_parameters/galileo_ephemeris.h @@ -35,6 +35,7 @@ #include #include +#include /*! @@ -48,9 +49,9 @@ public: /* Galileo ephemeris are 16 parameters and here are reported following the ICD order, paragraph 5.1.1. The number in the name after underscore (_1, _2, _3 and so on) refers to the page were we can find that parameter */ bool flag_all_ephemeris; - int IOD_ephemeris; - int IOD_nav_1; - int SV_ID_PRN_4; + int32_t IOD_ephemeris; + int32_t IOD_nav_1; + int32_t SV_ID_PRN_4; double M0_1; //!< Mean anomaly at reference time [semi-circles] double delta_n_3; //!< Mean motion difference from computed value [semi-circles/sec] double e_1; //!< Eccentricity @@ -83,12 +84,12 @@ public: // SV status double SISA_3; - unsigned int E5a_HS; //!< E5a Signal Health Status - double E5b_HS_5; //!< E5b Signal Health Status - double E1B_HS_5; //!< E1B Signal Health Status - bool E5a_DVS; //!< E5a Data Validity Status - double E5b_DVS_5; //!< E5b Data Validity Status - double E1B_DVS_5; //!< E1B Data Validity Status + uint32_t E5a_HS; //!< E5a Signal Health Status + double E5b_HS_5; //!< E5b Signal Health Status + double E1B_HS_5; //!< E1B Signal Health Status + bool E5a_DVS; //!< E5a Data Validity Status + double E5b_DVS_5; //!< E5b Data Validity Status + double E1B_DVS_5; //!< E1B Data Validity Status double BGD_E1E5a_5; //!< E1-E5a Broadcast Group Delay [s] double BGD_E1E5b_5; //!< E1-E5b Broadcast Group Delay [s] @@ -103,7 +104,7 @@ public: double d_satvel_Y; //!< Earth-fixed velocity coordinate y of the satellite [m] double d_satvel_Z; //!< Earth-fixed velocity coordinate z of the satellite [m] - unsigned int i_satellite_PRN; //!< SV PRN NUMBER + uint32_t i_satellite_PRN; //!< SV PRN NUMBER void satellitePosition(double transmitTime); //!< Computes the ECEF SV coordinates and ECEF velocity double Galileo_System_Time(double WN, double TOW); //!< Galileo System Time (GST), ICD paragraph 5.1.2 @@ -116,32 +117,55 @@ public: /*! * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file. */ - inline void serialize(Archive& archive, const unsigned int version) + inline void serialize(Archive& archive, const uint32_t version) { - using boost::serialization::make_nvp; if (version) { }; - archive& make_nvp("i_satellite_PRN", i_satellite_PRN); - archive& make_nvp("M0_1", M0_1); - archive& make_nvp("e_1", e_1); - archive& make_nvp("A_1", A_1); - archive& make_nvp("OMEGA_0_2", OMEGA_0_2); - archive& make_nvp("i_0_2", i_0_2); - archive& make_nvp("omega_2", omega_2); - archive& make_nvp("OMEGA_dot_3", OMEGA_dot_3); - archive& make_nvp("iDot_2", iDot_2); - archive& make_nvp("C_uc_3", C_uc_3); - archive& make_nvp("C_us_3", C_us_3); - archive& make_nvp("C_rc_3", C_rc_3); - archive& make_nvp("C_rs_3", C_rs_3); - archive& make_nvp("C_ic_4", C_ic_4); - archive& make_nvp("C_is_4", C_is_4); - archive& make_nvp("t0e_1", t0e_1); - archive& make_nvp("t0c_4", t0c_4); - archive& make_nvp("af0_4", af0_4); - archive& make_nvp("af1_4", af1_4); - archive& make_nvp("af2_4", af2_4); + + archive& BOOST_SERIALIZATION_NVP(i_satellite_PRN); + + archive& BOOST_SERIALIZATION_NVP(M0_1); + archive& BOOST_SERIALIZATION_NVP(delta_n_3); + archive& BOOST_SERIALIZATION_NVP(e_1); + archive& BOOST_SERIALIZATION_NVP(A_1); + archive& BOOST_SERIALIZATION_NVP(OMEGA_0_2); + archive& BOOST_SERIALIZATION_NVP(i_0_2); + archive& BOOST_SERIALIZATION_NVP(omega_2); + archive& BOOST_SERIALIZATION_NVP(OMEGA_dot_3); + archive& BOOST_SERIALIZATION_NVP(iDot_2); + archive& BOOST_SERIALIZATION_NVP(C_uc_3); + archive& BOOST_SERIALIZATION_NVP(C_us_3); + archive& BOOST_SERIALIZATION_NVP(C_rc_3); + archive& BOOST_SERIALIZATION_NVP(C_rs_3); + archive& BOOST_SERIALIZATION_NVP(C_ic_4); + archive& BOOST_SERIALIZATION_NVP(C_is_4); + archive& BOOST_SERIALIZATION_NVP(t0e_1); + + archive& BOOST_SERIALIZATION_NVP(t0c_4); + archive& BOOST_SERIALIZATION_NVP(af0_4); + archive& BOOST_SERIALIZATION_NVP(af1_4); + archive& BOOST_SERIALIZATION_NVP(af2_4); + + archive& BOOST_SERIALIZATION_NVP(WN_5); + archive& BOOST_SERIALIZATION_NVP(TOW_5); + archive& BOOST_SERIALIZATION_NVP(Galileo_satClkDrift); + archive& BOOST_SERIALIZATION_NVP(Galileo_dtr); + + archive& BOOST_SERIALIZATION_NVP(flag_all_ephemeris); + archive& BOOST_SERIALIZATION_NVP(IOD_ephemeris); + archive& BOOST_SERIALIZATION_NVP(IOD_nav_1); + + archive& BOOST_SERIALIZATION_NVP(SISA_3); + archive& BOOST_SERIALIZATION_NVP(E5a_HS); + archive& BOOST_SERIALIZATION_NVP(E5b_HS_5); + archive& BOOST_SERIALIZATION_NVP(E1B_HS_5); + archive& BOOST_SERIALIZATION_NVP(E5a_DVS); + archive& BOOST_SERIALIZATION_NVP(E5b_DVS_5); + archive& BOOST_SERIALIZATION_NVP(E1B_DVS_5); + + archive& BOOST_SERIALIZATION_NVP(BGD_E1E5a_5); + archive& BOOST_SERIALIZATION_NVP(BGD_E1E5b_5); } }; diff --git a/src/core/system_parameters/galileo_fnav_message.cc b/src/core/system_parameters/galileo_fnav_message.cc index b0c17fa7d..33cd59056 100644 --- a/src/core/system_parameters/galileo_fnav_message.cc +++ b/src/core/system_parameters/galileo_fnav_message.cc @@ -66,131 +66,120 @@ void Galileo_Fnav_Message::reset() IOD_ephemeris = 0; page_type = 0; - /* WORD 1 SVID, Clock correction, SISA, Ionospheric correction, BGD, GST, Signal - * health and Data validity status*/ + // WORD 1 SVID, Clock correction, SISA, Ionospheric correction, BGD, GST, Signal + // health and Data validity status FNAV_SV_ID_PRN_1 = 0; FNAV_IODnav_1 = -1; - FNAV_t0c_1 = 0; - FNAV_af0_1 = 0; - FNAV_af1_1 = 0; - FNAV_af2_1 = 0; - FNAV_SISA_1 = 0; - FNAV_ai0_1 = 0; - FNAV_ai1_1 = 0; - FNAV_ai2_1 = 0; - FNAV_region1_1 = 0; - FNAV_region2_1 = 0; - FNAV_region3_1 = 0; - FNAV_region4_1 = 0; - FNAV_region5_1 = 0; - FNAV_BGD_1 = 0; - FNAV_E5ahs_1 = 0; - FNAV_WN_1 = 0; - FNAV_TOW_1 = 0; - FNAV_E5advs_1 = 0; + FNAV_t0c_1 = 0.0; + FNAV_af0_1 = 0.0; + FNAV_af1_1 = 0.0; + FNAV_af2_1 = 0.0; + FNAV_SISA_1 = 0.0; + FNAV_ai0_1 = 0.0; + FNAV_ai1_1 = 0.0; + FNAV_ai2_1 = 0.0; + FNAV_region1_1 = false; + FNAV_region2_1 = false; + FNAV_region3_1 = false; + FNAV_region4_1 = false; + FNAV_region5_1 = false; + FNAV_BGD_1 = 0.0; + FNAV_E5ahs_1 = 0.0; + FNAV_WN_1 = 0.0; + FNAV_TOW_1 = 0.0; + FNAV_E5advs_1 = false; // WORD 2 Ephemeris (1/3) and GST FNAV_IODnav_2 = -2; - FNAV_M0_2 = 0; - FNAV_omegadot_2 = 0; - FNAV_e_2 = 0; - FNAV_a12_2 = 0; - FNAV_omega0_2 = 0; - FNAV_idot_2 = 0; - FNAV_WN_2 = 0; - FNAV_TOW_2 = 0; + FNAV_M0_2 = 0.0; + FNAV_omegadot_2 = 0.0; + FNAV_e_2 = 0.0; + FNAV_a12_2 = 0.0; + FNAV_omega0_2 = 0.0; + FNAV_idot_2 = 0.0; + FNAV_WN_2 = 0.0; + FNAV_TOW_2 = 0.0; // WORD 3 Ephemeris (2/3) and GST FNAV_IODnav_3 = -3; - FNAV_i0_3 = 0; - FNAV_w_3 = 0; - FNAV_deltan_3 = 0; - FNAV_Cuc_3 = 0; - FNAV_Cus_3 = 0; - FNAV_Crc_3 = 0; - FNAV_Crs_3 = 0; - FNAV_t0e_3 = 0; - FNAV_WN_3 = 0; - FNAV_TOW_3 = 0; + FNAV_i0_3 = 0.0; + FNAV_w_3 = 0.0; + FNAV_deltan_3 = 0.0; + FNAV_Cuc_3 = 0.0; + FNAV_Cus_3 = 0.0; + FNAV_Crc_3 = 0.0; + FNAV_Crs_3 = 0.0; + FNAV_t0e_3 = 0.0; + FNAV_WN_3 = 0.0; + FNAV_TOW_3 = 0.0; - /* WORD 4 Ephemeris (3/3), GST-UTC conversion, GST-GPS conversion and TOW. - Note that the clock is repeated in this page type*/ + // WORD 4 Ephemeris (3/3), GST-UTC conversion, GST-GPS conversion and TOW. + // Note that the clock is repeated in this page type FNAV_IODnav_4 = -4; - FNAV_Cic_4 = 0; - FNAV_Cis_4 = 0; - FNAV_A0_4 = 0; - FNAV_A1_4 = 0; - FNAV_deltatls_4 = 0; - FNAV_t0t_4 = 0; - FNAV_WNot_4 = 0; - FNAV_WNlsf_4 = 0; - FNAV_DN_4 = 0; - FNAV_deltatlsf_4 = 0; - FNAV_t0g_4 = 0; - FNAV_A0g_4 = 0; - FNAV_A1g_4 = 0; - FNAV_WN0g_4 = 0; - FNAV_TOW_4 = 0; + FNAV_Cic_4 = 0.0; + FNAV_Cis_4 = 0.0; + FNAV_A0_4 = 0.0; + FNAV_A1_4 = 0.0; + FNAV_deltatls_4 = 0.0; + FNAV_t0t_4 = 0.0; + FNAV_WNot_4 = 0.0; + FNAV_WNlsf_4 = 0.0; + FNAV_DN_4 = 0.0; + FNAV_deltatlsf_4 = 0.0; + FNAV_t0g_4 = 0.0; + FNAV_A0g_4 = 0.0; + FNAV_A1g_4 = 0.0; + FNAV_WN0g_4 = 0.0; + FNAV_TOW_4 = 0.0; // WORD 5 Almanac (SVID1 and SVID2(1/2)), Week Number and almanac reference time FNAV_IODa_5 = 0; - FNAV_WNa_5 = 0; - FNAV_t0a_5 = 0; + FNAV_WNa_5 = 0.0; + FNAV_t0a_5 = 0.0; FNAV_SVID1_5 = 0; - FNAV_Deltaa12_1_5 = 0; - FNAV_e_1_5 = 0; - FNAV_w_1_5 = 0; - FNAV_deltai_1_5 = 0; - FNAV_Omega0_1_5 = 0; - FNAV_Omegadot_1_5 = 0; - FNAV_M0_1_5 = 0; - FNAV_af0_1_5 = 0; - FNAV_af1_1_5 = 0; - FNAV_E5ahs_1_5 = 0; + FNAV_Deltaa12_1_5 = 0.0; + FNAV_e_1_5 = 0.0; + FNAV_w_1_5 = 0.0; + FNAV_deltai_1_5 = 0.0; + FNAV_Omega0_1_5 = 0.0; + FNAV_Omegadot_1_5 = 0.0; + FNAV_M0_1_5 = 0.0; + FNAV_af0_1_5 = 0.0; + FNAV_af1_1_5 = 0.0; + FNAV_E5ahs_1_5 = 0U; FNAV_SVID2_5 = 0; FNAV_Deltaa12_2_5 = 0; - FNAV_e_2_5 = 0; - FNAV_w_2_5 = 0; - FNAV_deltai_2_5 = 0; + FNAV_e_2_5 = 0.0; + FNAV_w_2_5 = 0.0; + FNAV_deltai_2_5 = 0.0; // WORD 6 Almanac (SVID2(2/2) and SVID3) FNAV_IODa_6 = 0; - FNAV_Omega0_2_6 = 0; - FNAV_Omegadot_2_6 = 0; - FNAV_M0_2_6 = 0; - FNAV_af0_2_6 = 0; - FNAV_af1_2_6 = 0; - FNAV_E5ahs_2_6 = 0; + FNAV_Omega0_2_6 = 0.0; + FNAV_Omegadot_2_6 = 0.0; + FNAV_M0_2_6 = 0.0; + FNAV_af0_2_6 = 0.0; + FNAV_af1_2_6 = 0.0; + FNAV_E5ahs_2_6 = 0.0; FNAV_SVID3_6 = 0; - FNAV_Deltaa12_3_6 = 0; - FNAV_e_3_6 = 0; - FNAV_w_3_6 = 0; - FNAV_deltai_3_6 = 0; - FNAV_Omega0_3_6 = 0; - FNAV_Omegadot_3_6 = 0; - FNAV_M0_3_6 = 0; - FNAV_af0_3_6 = 0; - FNAV_af1_3_6 = 0; - FNAV_E5ahs_3_6 = 0; + FNAV_Deltaa12_3_6 = 0.0; + FNAV_e_3_6 = 0.0; + FNAV_w_3_6 = 0.0; + FNAV_deltai_3_6 = 0.0; + FNAV_Omega0_3_6 = 0.0; + FNAV_Omegadot_3_6 = 0.0; + FNAV_M0_3_6 = 0.0; + FNAV_af0_3_6 = 0.0; + FNAV_af1_3_6 = 0.0; + FNAV_E5ahs_3_6 = 0.0; } + Galileo_Fnav_Message::Galileo_Fnav_Message() { reset(); } -//int Galileo_Fnav_Message::toInt(std::string bitString) -//{ -// int tempInt; -// int num=0; -// int sLength = bitString.length(); -// for(int i=0; i bits, boost::uint32_t checksum) +bool Galileo_Fnav_Message::_CRC_test(std::bitset bits, uint32_t checksum) { CRC_Galileo_FNAV_type CRC_Galileo; - boost::uint32_t crc_computed; + uint32_t crc_computed; // Galileo FNAV 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. // ToDo: Use boost::dynamic_bitset for all the bitset operations in this class - boost::dynamic_bitset frame_bits(std::string(bits.to_string())); + boost::dynamic_bitset frame_bits(std::string(bits.to_string())); - std::vector bytes; + std::vector bytes; boost::to_block_range(frame_bits, std::back_inserter(bytes)); std::reverse(bytes.begin(), bytes.end()); @@ -249,8 +238,8 @@ void Galileo_Fnav_Message::decode_page(std::string data) switch (page_type) { case 1: // SVID, Clock correction, SISA, Ionospheric correction, BGD, GST, Signal health and Data validity status - FNAV_SV_ID_PRN_1 = static_cast(read_navigation_unsigned(data_bits, FNAV_SV_ID_PRN_1_bit)); - FNAV_IODnav_1 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODnav_1_bit)); + FNAV_SV_ID_PRN_1 = static_cast(read_navigation_unsigned(data_bits, FNAV_SV_ID_PRN_1_bit)); + FNAV_IODnav_1 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODnav_1_bit)); FNAV_t0c_1 = static_cast(read_navigation_unsigned(data_bits, FNAV_t0c_1_bit)); FNAV_t0c_1 *= FNAV_t0c_1_LSB; FNAV_af0_1 = static_cast(read_navigation_signed(data_bits, FNAV_af0_1_bit)); @@ -273,17 +262,16 @@ void Galileo_Fnav_Message::decode_page(std::string data) FNAV_region5_1 = static_cast(read_navigation_unsigned(data_bits, FNAV_region5_1_bit)); FNAV_BGD_1 = static_cast(read_navigation_signed(data_bits, FNAV_BGD_1_bit)); FNAV_BGD_1 *= FNAV_BGD_1_LSB; - FNAV_E5ahs_1 = static_cast(read_navigation_unsigned(data_bits, FNAV_E5ahs_1_bit)); + FNAV_E5ahs_1 = static_cast(read_navigation_unsigned(data_bits, FNAV_E5ahs_1_bit)); FNAV_WN_1 = static_cast(read_navigation_unsigned(data_bits, FNAV_WN_1_bit)); FNAV_TOW_1 = static_cast(read_navigation_unsigned(data_bits, FNAV_TOW_1_bit)); FNAV_E5advs_1 = static_cast(read_navigation_unsigned(data_bits, FNAV_E5advs_1_bit)); - flag_TOW_1 = true; flag_TOW_set = true; - flag_iono_and_GST = true; //set to false externally + flag_iono_and_GST = true; // set to false externally break; case 2: // Ephemeris (1/3) and GST - FNAV_IODnav_2 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODnav_2_bit)); + FNAV_IODnav_2 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODnav_2_bit)); FNAV_M0_2 = static_cast(read_navigation_unsigned(data_bits, FNAV_M0_2_bit)); FNAV_M0_2 *= FNAV_M0_2_LSB; FNAV_omegadot_2 = static_cast(read_navigation_signed(data_bits, FNAV_omegadot_2_bit)); @@ -298,13 +286,12 @@ void Galileo_Fnav_Message::decode_page(std::string data) FNAV_idot_2 *= FNAV_idot_2_LSB; FNAV_WN_2 = static_cast(read_navigation_unsigned(data_bits, FNAV_WN_2_bit)); FNAV_TOW_2 = static_cast(read_navigation_unsigned(data_bits, FNAV_TOW_2_bit)); - flag_TOW_2 = true; flag_TOW_set = true; flag_ephemeris_1 = true; break; case 3: // Ephemeris (2/3) and GST - FNAV_IODnav_3 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODnav_3_bit)); + FNAV_IODnav_3 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODnav_3_bit)); FNAV_i0_3 = static_cast(read_navigation_signed(data_bits, FNAV_i0_3_bit)); FNAV_i0_3 *= FNAV_i0_3_LSB; FNAV_w_3 = static_cast(read_navigation_signed(data_bits, FNAV_w_3_bit)); @@ -323,13 +310,12 @@ void Galileo_Fnav_Message::decode_page(std::string data) FNAV_t0e_3 *= FNAV_t0e_3_LSB; FNAV_WN_3 = static_cast(read_navigation_unsigned(data_bits, FNAV_WN_3_bit)); FNAV_TOW_3 = static_cast(read_navigation_unsigned(data_bits, FNAV_TOW_3_bit)); - flag_TOW_3 = true; flag_TOW_set = true; flag_ephemeris_2 = true; break; case 4: // Ephemeris (3/3), GST-UTC conversion, GST-GPS conversion and TOW - FNAV_IODnav_4 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODnav_4_bit)); + FNAV_IODnav_4 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODnav_4_bit)); FNAV_Cic_4 = static_cast(read_navigation_unsigned(data_bits, FNAV_Cic_4_bit)); FNAV_Cic_4 *= FNAV_Cic_4_LSB; FNAV_Cis_4 = static_cast(read_navigation_unsigned(data_bits, FNAV_Cis_4_bit)); @@ -353,18 +339,17 @@ void Galileo_Fnav_Message::decode_page(std::string data) FNAV_A1g_4 *= FNAV_A1g_4_LSB; FNAV_WN0g_4 = static_cast(read_navigation_unsigned(data_bits, FNAV_WN0g_4_bit)); FNAV_TOW_4 = static_cast(read_navigation_unsigned(data_bits, FNAV_TOW_4_bit)); - flag_TOW_4 = true; flag_TOW_set = true; flag_ephemeris_3 = true; - flag_utc_model = true; //set to false externally + flag_utc_model = true; // set to false externally break; case 5: // Almanac (SVID1 and SVID2(1/2)), Week Number and almanac reference time - FNAV_IODa_5 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODa_5_bit)); + FNAV_IODa_5 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODa_5_bit)); FNAV_WNa_5 = static_cast(read_navigation_unsigned(data_bits, FNAV_WNa_5_bit)); FNAV_t0a_5 = static_cast(read_navigation_unsigned(data_bits, FNAV_t0a_5_bit)); FNAV_t0a_5 *= FNAV_t0a_5_LSB; - FNAV_SVID1_5 = static_cast(read_navigation_unsigned(data_bits, FNAV_SVID1_5_bit)); + FNAV_SVID1_5 = static_cast(read_navigation_unsigned(data_bits, FNAV_SVID1_5_bit)); FNAV_Deltaa12_1_5 = static_cast(read_navigation_signed(data_bits, FNAV_Deltaa12_1_5_bit)); FNAV_Deltaa12_1_5 *= FNAV_Deltaa12_5_LSB; FNAV_e_1_5 = static_cast(read_navigation_unsigned(data_bits, FNAV_e_1_5_bit)); @@ -384,7 +369,7 @@ void Galileo_Fnav_Message::decode_page(std::string data) FNAV_af1_1_5 = static_cast(read_navigation_signed(data_bits, FNAV_af1_1_5_bit)); FNAV_af1_1_5 *= FNAV_af1_5_LSB; FNAV_E5ahs_1_5 = static_cast(read_navigation_unsigned(data_bits, FNAV_E5ahs_1_5_bit)); - FNAV_SVID2_5 = static_cast(read_navigation_unsigned(data_bits, FNAV_SVID2_5_bit)); + FNAV_SVID2_5 = static_cast(read_navigation_unsigned(data_bits, FNAV_SVID2_5_bit)); FNAV_Deltaa12_2_5 = static_cast(read_navigation_signed(data_bits, FNAV_Deltaa12_2_5_bit)); FNAV_Deltaa12_2_5 *= FNAV_Deltaa12_5_LSB; FNAV_e_2_5 = static_cast(read_navigation_unsigned(data_bits, FNAV_e_2_5_bit)); @@ -399,21 +384,18 @@ void Galileo_Fnav_Message::decode_page(std::string data) //omega_flag=true; // //FNAV_Omega012_2_5=static_cast(read_navigation_signed(data_bits, FNAV_Omega012_2_5_bit); - flag_almanac_1 = true; break; case 6: // Almanac (SVID2(2/2) and SVID3) - FNAV_IODa_6 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODa_6_bit)); - - /* Don't worry about omega pieces. If page 5 has not been received, all_ephemeris - * flag will be set to false and the data won't be recorded.*/ + FNAV_IODa_6 = static_cast(read_navigation_unsigned(data_bits, FNAV_IODa_6_bit)); + // Don't worry about omega pieces. If page 5 has not been received, all_ephemeris + // flag will be set to false and the data won't be recorded.*/ std::string omega0_2 = data.substr(10, 12); std::string Omega0 = omega0_1 + omega0_2; std::bitset omega_bits(Omega0); - const std::vector> om_bit({{0, 12}}); + const std::vector> om_bit({{0, 12}}); FNAV_Omega0_2_6 = static_cast(read_navigation_signed(omega_bits, om_bit)); FNAV_Omega0_2_6 *= FNAV_Omega0_5_LSB; - // FNAV_Omegadot_2_6 = static_cast(read_navigation_signed(data_bits, FNAV_Omegadot_2_6_bit)); FNAV_Omegadot_2_6 *= FNAV_Omegadot_5_LSB; FNAV_M0_2_6 = static_cast(read_navigation_signed(data_bits, FNAV_M0_2_6_bit)); @@ -423,7 +405,7 @@ void Galileo_Fnav_Message::decode_page(std::string data) FNAV_af1_2_6 = static_cast(read_navigation_signed(data_bits, FNAV_af1_2_6_bit)); FNAV_af1_2_6 *= FNAV_af1_5_LSB; FNAV_E5ahs_2_6 = static_cast(read_navigation_unsigned(data_bits, FNAV_E5ahs_2_6_bit)); - FNAV_SVID3_6 = static_cast(read_navigation_unsigned(data_bits, FNAV_SVID3_6_bit)); + FNAV_SVID3_6 = static_cast(read_navigation_unsigned(data_bits, FNAV_SVID3_6_bit)); FNAV_Deltaa12_3_6 = static_cast(read_navigation_signed(data_bits, FNAV_Deltaa12_3_6_bit)); FNAV_Deltaa12_3_6 *= FNAV_Deltaa12_5_LSB; FNAV_e_3_6 = static_cast(read_navigation_unsigned(data_bits, FNAV_e_3_6_bit)); @@ -450,15 +432,15 @@ void Galileo_Fnav_Message::decode_page(std::string data) } -unsigned long int Galileo_Fnav_Message::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) +uint64_t Galileo_Fnav_Message::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) { - unsigned long int value = 0; + uint64_t value = 0ULL; int num_of_slices = parameter.size(); for (int i = 0; i < num_of_slices; i++) { for (int j = 0; j < parameter[i].second; j++) { - value <<= 1; //shift left + value <<= 1; // shift left if (bits[GALILEO_FNAV_DATA_FRAME_BITS - parameter[i].first - j] == 1) { value += 1; // insert the bit @@ -469,59 +451,30 @@ unsigned long int Galileo_Fnav_Message::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) +int64_t Galileo_Fnav_Message::read_navigation_signed(std::bitset bits, const std::vector> parameter) { - signed long int value = 0; + int64_t value = 0LL; int num_of_slices = parameter.size(); - // Discriminate between 64 bits and 32 bits compiler - int long_int_size_bytes = sizeof(signed long int); - if (long_int_size_bytes == 8) // if a long int takes 8 bytes, we are in a 64 bits system - { - // read the MSB and perform the sign extension - if (bits[GALILEO_FNAV_DATA_FRAME_BITS - parameter[0].first] == 1) - { - value ^= 0xFFFFFFFFFFFFFFFF; //64 bits variable - } - else - { - value &= 0; - } - for (int i = 0; i < num_of_slices; i++) - { - for (int j = 0; j < parameter[i].second; j++) - { - value <<= 1; //shift left - value &= 0xFFFFFFFFFFFFFFFE; //reset the corresponding bit (for the 64 bits variable) - if (bits[GALILEO_FNAV_DATA_FRAME_BITS - parameter[i].first - j] == 1) - { - value += 1; // insert the bit - } - } - } + // read the MSB and perform the sign extension + if (bits[GALILEO_FNAV_DATA_FRAME_BITS - parameter[0].first] == 1) + { + value ^= 0x0FFFFFFFFFFFFFFF; // 64 bits variable } - else // we assume we are in a 32 bits system + else { - // read the MSB and perform the sign extension - if (bits[GALILEO_FNAV_DATA_FRAME_BITS - parameter[0].first] == 1) - { - value ^= 0xFFFFFFFF; - } - else - { - value &= 0; - } + value &= 0; + } - for (int i = 0; i < num_of_slices; i++) + for (int i = 0; i < num_of_slices; i++) + { + for (int j = 0; j < parameter[i].second; j++) { - for (int j = 0; j < parameter[i].second; j++) + value <<= 1; // shift left + value &= 0xFFFFFFFFFFFFFFFE; // reset the corresponding bit (for the 64 bits variable) + if (bits[GALILEO_FNAV_DATA_FRAME_BITS - parameter[i].first - j] == 1) { - value <<= 1; //shift left - value &= 0xFFFFFFFE; //reset the corresponding bit - if (bits[GALILEO_FNAV_DATA_FRAME_BITS - parameter[i].first - j] == 1) - { - value += 1; // insert the bit - } + value += 1; // insert the bit } } } @@ -529,11 +482,11 @@ signed long int Galileo_Fnav_Message::read_navigation_signed(std::bitset // for boost::uint16_t #include +#include #include #include #include @@ -57,17 +57,6 @@ class Galileo_Fnav_Message { public: - // void Galileo_Fnav_Message::split_page(std::string page_string); - // void Galileo_Fnav_Message::reset(); - // bool Galileo_Fnav_Message::have_new_ephemeris(); - // bool Galileo_Fnav_Message::have_new_iono_and_GST(); - // bool Galileo_Fnav_Message::have_new_utc_model(); - // bool Galileo_Fnav_Message::have_new_almanac(); - // Galileo_Ephemeris Galileo_Fnav_Message::get_ephemeris(); - // Galileo_Iono Galileo_Fnav_Message::get_iono(); - // Galileo_Utc_Model Galileo_Fnav_Message::get_utc_model(); - // Galileo_Almanac Galileo_Fnav_Message::get_almanac(); - // void split_page(std::string page_string); void reset(); bool have_new_ephemeris(); @@ -77,7 +66,7 @@ public: Galileo_Ephemeris get_ephemeris(); Galileo_Iono get_iono(); Galileo_Utc_Model get_utc_model(); - Galileo_Almanac get_almanac(); + Galileo_Almanac_Helper get_almanac(); Galileo_Fnav_Message(); @@ -99,13 +88,13 @@ public: bool flag_almanac_1; //!< Flag indicating that almanac 1/2 (word 5) have been received bool flag_almanac_2; //!< Flag indicating that almanac 2/2 (word 6) have been received - int IOD_ephemeris; + int32_t IOD_ephemeris; - int page_type; - /* WORD 1 SVID, Clock correction, SISA, Ionospheric correction, BGD, GST, Signal - * health and Data validity status*/ - int FNAV_SV_ID_PRN_1; - int FNAV_IODnav_1; + int32_t page_type; + // WORD 1 SVID, Clock correction, SISA, Ionospheric correction, BGD, GST, Signal + // health and Data validity status + int32_t FNAV_SV_ID_PRN_1; + int32_t FNAV_IODnav_1; double FNAV_t0c_1; double FNAV_af0_1; double FNAV_af1_1; @@ -126,7 +115,7 @@ public: bool FNAV_E5advs_1; // WORD 2 Ephemeris (1/3) and GST - int FNAV_IODnav_2; + int32_t FNAV_IODnav_2; double FNAV_M0_2; double FNAV_omegadot_2; double FNAV_e_2; @@ -137,7 +126,7 @@ public: double FNAV_TOW_2; // WORD 3 Ephemeris (2/3) and GST - int FNAV_IODnav_3; + int32_t FNAV_IODnav_3; double FNAV_i0_3; double FNAV_w_3; double FNAV_deltan_3; @@ -149,9 +138,9 @@ public: double FNAV_WN_3; double FNAV_TOW_3; - /* WORD 4 Ephemeris (3/3), GST-UTC conversion, GST-GPS conversion and TOW. - Note that the clock is repeated in this page type*/ - int FNAV_IODnav_4; + // WORD 4 Ephemeris (3/3), GST-UTC conversion, GST-GPS conversion and TOW. + // Note that the clock is repeated in this page type + int32_t FNAV_IODnav_4; double FNAV_Cic_4; double FNAV_Cis_4; double FNAV_A0_4; @@ -169,10 +158,10 @@ public: double FNAV_TOW_4; // WORD 5 Almanac (SVID1 and SVID2(1/2)), Week Number and almanac reference time - int FNAV_IODa_5; + int32_t FNAV_IODa_5; double FNAV_WNa_5; double FNAV_t0a_5; - int FNAV_SVID1_5; + int32_t FNAV_SVID1_5; double FNAV_Deltaa12_1_5; double FNAV_e_1_5; double FNAV_w_1_5; @@ -182,22 +171,22 @@ public: double FNAV_M0_1_5; double FNAV_af0_1_5; double FNAV_af1_1_5; - unsigned int FNAV_E5ahs_1_5; - int FNAV_SVID2_5; + uint32_t FNAV_E5ahs_1_5; + int32_t FNAV_SVID2_5; double FNAV_Deltaa12_2_5; double FNAV_e_2_5; double FNAV_w_2_5; double FNAV_deltai_2_5; // WORD 6 Almanac (SVID2(2/2) and SVID3) - int FNAV_IODa_6; + int32_t FNAV_IODa_6; double FNAV_Omega0_2_6; double FNAV_Omegadot_2_6; double FNAV_M0_2_6; double FNAV_af0_2_6; double FNAV_af1_2_6; double FNAV_E5ahs_2_6; - int FNAV_SVID3_6; + int32_t FNAV_SVID3_6; double FNAV_Deltaa12_3_6; double FNAV_e_3_6; double FNAV_w_3_6; @@ -209,12 +198,11 @@ public: double FNAV_af1_3_6; double FNAV_E5ahs_3_6; - private: - bool _CRC_test(std::bitset bits, boost::uint32_t checksum); + bool _CRC_test(std::bitset bits, uint32_t checksum); void decode_page(std::string data); - unsigned long int read_navigation_unsigned(std::bitset bits, const std::vector> parameter); - signed long int read_navigation_signed(std::bitset bits, const std::vector> parameter); + uint64_t read_navigation_unsigned(std::bitset bits, const std::vector> parameter); + int64_t read_navigation_signed(std::bitset bits, const std::vector> parameter); std::string omega0_1; //std::string omega0_2; diff --git a/src/core/system_parameters/galileo_iono.cc b/src/core/system_parameters/galileo_iono.cc index 4a8eb35b0..d79b2a319 100644 --- a/src/core/system_parameters/galileo_iono.cc +++ b/src/core/system_parameters/galileo_iono.cc @@ -33,18 +33,18 @@ Galileo_Iono::Galileo_Iono() { - /* Ionospheric correction */ - ai0_5 = 0; // Effective Ionisation Level 1st order parameter [sfu] - ai1_5 = 0; // Effective Ionisation Level 2st order parameter [sfu/degree] - ai2_5 = 0; // Effective Ionisation Level 3st order parameter [sfu/degree] + // Ionospheric correction + ai0_5 = 0.0; // Effective Ionisation Level 1st order parameter [sfu] + ai1_5 = 0.0; // Effective Ionisation Level 2st order parameter [sfu/degree] + ai2_5 = 0.0; // Effective Ionisation Level 3st order parameter [sfu/degree] - /* Ionospheric disturbance flag */ + // Ionospheric disturbance flag Region1_flag_5 = false; // Ionospheric Disturbance Flag for region 1 Region2_flag_5 = false; // Ionospheric Disturbance Flag for region 2 Region3_flag_5 = false; // Ionospheric Disturbance Flag for region 3 Region4_flag_5 = false; // Ionospheric Disturbance Flag for region 4 Region5_flag_5 = false; // Ionospheric Disturbance Flag for region 5 - TOW_5 = 0; - WN_5 = 0; + TOW_5 = 0.0; + WN_5 = 0.0; } diff --git a/src/core/system_parameters/galileo_iono.h b/src/core/system_parameters/galileo_iono.h index 1c3278ed7..90c861c12 100644 --- a/src/core/system_parameters/galileo_iono.h +++ b/src/core/system_parameters/galileo_iono.h @@ -32,6 +32,7 @@ #ifndef GNSS_SDR_GALILEO_IONO_H_ #define GNSS_SDR_GALILEO_IONO_H_ +#include /*! * \brief This class is a storage for the GALILEO IONOSPHERIC data as described in Galileo ICD paragraph 5.1.6 @@ -41,19 +42,19 @@ class Galileo_Iono { public: - /*Ionospheric correction*/ + // Ionospheric correction double ai0_5; //!< Effective Ionisation Level 1st order parameter [sfu] double ai1_5; //!< Effective Ionisation Level 2st order parameter [sfu/degree] double ai2_5; //!< Effective Ionisation Level 3st order parameter [sfu/degree] - /*Ionospheric disturbance flag*/ + // Ionospheric disturbance flag bool Region1_flag_5; //!< Ionospheric Disturbance Flag for region 1 bool Region2_flag_5; //!< Ionospheric Disturbance Flag for region 2 bool Region3_flag_5; //!< Ionospheric Disturbance Flag for region 3 bool Region4_flag_5; //!< Ionospheric Disturbance Flag for region 4 bool Region5_flag_5; //!< Ionospheric Disturbance Flag for region 5 - /*from page 5 (UTC) to have a timestamp*/ + // from page 5 (UTC) to have a timestamp double TOW_5; //!< UTC data reference Time of Week [s] double WN_5; //!< UTC data reference Week number [week] @@ -61,6 +62,30 @@ public: * Default constructor */ Galileo_Iono(); + + template + + /*! + * \brief Serialize is a boost standard method to be called by the boost XML serialization. + Here is used to save the iono data on disk file. + */ + inline void serialize(Archive& archive, const unsigned int version) + { + using boost::serialization::make_nvp; + if (version) + { + }; + archive& make_nvp("ai0_5", ai0_5); + archive& make_nvp("ai1_5", ai1_5); + archive& make_nvp("ai2_5", ai2_5); + archive& make_nvp("Region1_flag_5", Region1_flag_5); + archive& make_nvp("Region2_flag_5", Region2_flag_5); + archive& make_nvp("Region3_flag_5", Region3_flag_5); + archive& make_nvp("Region4_flag_5", Region4_flag_5); + archive& make_nvp("Region5_flag_5", Region5_flag_5); + archive& make_nvp("TOW_5", TOW_5); + archive& make_nvp("WN_5", WN_5); + } }; #endif diff --git a/src/core/system_parameters/galileo_navigation_message.cc b/src/core/system_parameters/galileo_navigation_message.cc index 95edb4bd5..4e72f62d3 100644 --- a/src/core/system_parameters/galileo_navigation_message.cc +++ b/src/core/system_parameters/galileo_navigation_message.cc @@ -61,7 +61,7 @@ void Galileo_Navigation_Message::reset() flag_almanac_3 = false; // flag indicating that almanac 3/4 (word 9) have been received flag_almanac_4 = false; // flag indicating that almanac 4/4 (word 10) have been received - flag_TOW_5 = 0; + flag_TOW_5 = false; flag_TOW_set = false; flag_GGTO = false; @@ -71,139 +71,141 @@ void Galileo_Navigation_Message::reset() flag_GGTO_4 = false; IOD_ephemeris = 0; - /*Word type 1: Ephemeris (1/4)*/ + + // Word type 1: Ephemeris (1/4) IOD_nav_1 = 0; - t0e_1 = 0; - M0_1 = 0; - e_1 = 0; - A_1 = 0; + t0e_1 = 0.0; + M0_1 = 0.0; + e_1 = 0.0; + A_1 = 0.0; - /*Word type 2: Ephemeris (2/4)*/ - IOD_nav_2 = 0; // IOD_nav page 2 - OMEGA_0_2 = 0; // Longitude of ascending node of orbital plane at weekly epoch [semi-circles] - i_0_2 = 0; // Inclination angle at reference time [semi-circles] - omega_2 = 0; // Argument of perigee [semi-circles] - iDot_2 = 0; // Rate of inclination angle [semi-circles/sec] + // Word type 2: Ephemeris (2/4) + IOD_nav_2 = 0; // IOD_nav page 2 + OMEGA_0_2 = 0.0; // Longitude of ascending node of orbital plane at weekly epoch [semi-circles] + i_0_2 = 0.0; // Inclination angle at reference time [semi-circles] + omega_2 = 0.0; // Argument of perigee [semi-circles] + iDot_2 = 0.0; // Rate of inclination angle [semi-circles/sec] + // Word type 3: Ephemeris (3/4) and SISA + IOD_nav_3 = 0; + OMEGA_dot_3 = 0.0; // Rate of right ascension [semi-circles/sec] + delta_n_3 = 0.0; // Mean motion difference from computed value [semi-circles/sec] + C_uc_3 = 0.0; // Amplitude of the cosine harmonic correction term to the argument of latitude [radians] + C_us_3 = 0.0; // Amplitude of the sine harmonic correction term to the argument of latitude [radians] + C_rc_3 = 0.0; // Amplitude of the cosine harmonic correction term to the orbit radius [meters] + C_rs_3 = 0.0; // Amplitude of the sine harmonic correction term to the orbit radius [meters] + SISA_3 = 0.0; // - /*Word type 3: Ephemeris (3/4) and SISA*/ - IOD_nav_3 = 0; // - OMEGA_dot_3 = 0; // Rate of right ascension [semi-circles/sec] - delta_n_3 = 0; // Mean motion difference from computed value [semi-circles/sec] - C_uc_3 = 0; // Amplitude of the cosine harmonic correction term to the argument of latitude [radians] - C_us_3 = 0; // Amplitude of the sine harmonic correction term to the argument of latitude [radians] - C_rc_3 = 0; // Amplitude of the cosine harmonic correction term to the orbit radius [meters] - C_rs_3 = 0; // Amplitude of the sine harmonic correction term to the orbit radius [meters] - SISA_3 = 0; // + // Word type 4: Ephemeris (4/4) and Clock correction parameter/ + IOD_nav_4 = 0; + SV_ID_PRN_4 = 0; + C_ic_4 = 0.0; // Amplitude of the cosine harmonic correction term to the angle of inclination [radians] + C_is_4 = 0.0; // Amplitude of the sine harmonic correction term to the angle of inclination [radians] + // Clock correction parameters + t0c_4 = 0.0; + af0_4 = 0.0; + af1_4 = 0.0; + af2_4 = 0.0; + spare_4 = 0.0; - /*Word type 4: Ephemeris (4/4) and Clock correction parameters*/ - IOD_nav_4 = 0; // - SV_ID_PRN_4 = 0; // - C_ic_4 = 0; // Amplitude of the cosine harmonic correction term to the angle of inclination [radians] - C_is_4 = 0; // Amplitude of the sine harmonic correction term to the angle of inclination [radians] - /*Clock correction parameters*/ - t0c_4 = 0; // - af0_4 = 0; // - af1_4 = 0; // - af2_4 = 0; // - spare_4 = 0; + // Word type 5: Ionospheric correction, BGD, signal health and data validity status and GST + // Ionospheric correction + ai0_5 = 0.0; + ai1_5 = 0.0; + ai2_5 = 0.0; - /*Word type 5: Ionospheric correction, BGD, signal health and data validity status and GST*/ - /*Ionospheric correction*/ - /*Az*/ - ai0_5 = 0; // - ai1_5 = 0; // - ai2_5 = 0; // - /*Ionospheric disturbance flag*/ - Region1_flag_5 = 0; // Region1_flag_5; - Region2_flag_5 = 0; // - Region3_flag_5 = 0; // - Region4_flag_5 = 0; // - Region5_flag_5 = 0; // - BGD_E1E5a_5 = 0; // - BGD_E1E5b_5 = 0; // + // Ionospheric disturbance flag + Region1_flag_5 = false; // Region1_flag_5; + Region2_flag_5 = false; + Region3_flag_5 = false; + Region4_flag_5 = false; + Region5_flag_5 = false; + BGD_E1E5a_5 = 0.0; + BGD_E1E5b_5 = 0.0; E5b_HS_5 = 0; E1B_HS_5 = 0; - E5b_DVS_5 = 0; // - E1B_DVS_5 = 0; // - /*GST*/ - WN_5 = 0; - TOW_5 = 0; - spare_5 = 0; + E5b_DVS_5 = 0; + E1B_DVS_5 = 0; - /*Word type 6: GST-UTC conversion parameters*/ - A0_6 = 0; - A1_6 = 0; - Delta_tLS_6 = 0; - t0t_6 = 0; - WNot_6 = 0; - WN_LSF_6 = 0; - DN_6 = 0; - Delta_tLSF_6 = 0; - TOW_6 = 0; + // GST + WN_5 = 0.0; + TOW_5 = 0.0; + spare_5 = 0.0; - /*Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number*/ + // Word type 6: GST-UTC conversion parameters + A0_6 = 0.0; + A1_6 = 0.0; + Delta_tLS_6 = 0.0; + t0t_6 = 0.0; + WNot_6 = 0.0; + WN_LSF_6 = 0.0; + DN_6 = 0.0; + Delta_tLSF_6 = 0.0; + TOW_6 = 0.0; + + // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number IOD_a_7 = 0; WN_a_7 = 0; - t0a_7 = 0; + t0a_7 = 0.0; SVID1_7 = 0; - DELTA_A_7 = 0; - e_7 = 0; - omega_7 = 0; - delta_i_7 = 0; - Omega0_7 = 0; - Omega_dot_7 = 0; - M0_7 = 0; + DELTA_A_7 = 0.0; + e_7 = 0.0; + omega_7 = 0.0; + delta_i_7 = 0.0; + Omega0_7 = 0.0; + Omega_dot_7 = 0.0; + M0_7 = 0.0; - /*Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2)*/ + // Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2) IOD_a_8 = 0; - af0_8 = 0; - af1_8 = 0; + af0_8 = 0.0; + af1_8 = 0.0; E5b_HS_8 = 0; E1B_HS_8 = 0; SVID2_8 = 0; - DELTA_A_8 = 0; - e_8 = 0; - omega_8 = 0; - delta_i_8 = 0; - Omega0_8 = 0; - Omega_dot_8 = 0; + DELTA_A_8 = 0.0; + e_8 = 0.0; + omega_8 = 0.0; + delta_i_8 = 0.0; + Omega0_8 = 0.0; + Omega_dot_8 = 0.0; - /*Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2)*/ + // Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2) IOD_a_9 = 0; WN_a_9 = 0; - t0a_9 = 0; - M0_9 = 0; - af0_9 = 0; - af1_9 = 0; + t0a_9 = 0.0; + M0_9 = 0.0; + af0_9 = 0.0; + af1_9 = 0.0; E5b_HS_9 = 0; E1B_HS_9 = 0; SVID3_9 = 0; - DELTA_A_9 = 0; - e_9 = 0; - omega_9 = 0; - delta_i_9 = 0; + DELTA_A_9 = 0.0; + e_9 = 0.0; + omega_9 = 0.0; + delta_i_9 = 0.0; - /*Word type 10: Almanac for SVID3 (2/2) and GST-GPS conversion parameters*/ + // Word type 10: Almanac for SVID3 (2/2) and GST-GPS conversion parameters IOD_a_10 = 0; - Omega0_10 = 0; - Omega_dot_10 = 0; - M0_10 = 0; - af0_10 = 0; - af1_10 = 0; + Omega0_10 = 0.0; + Omega_dot_10 = 0.0; + M0_10 = 0.0; + af0_10 = 0.0; + af1_10 = 0.0; E5b_HS_10 = 0; E1B_HS_10 = 0; - //GST-GPS - A_0G_10 = 0; - A_1G_10 = 0; - t_0G_10 = 0; - WN_0G_10 = 0; - /*Word type 0: I/NAV Spare Word*/ - Time_0 = 0; - WN_0 = 0; - TOW_0 = 0; + // GST-GPS + A_0G_10 = 0.0; + A_1G_10 = 0.0; + t_0G_10 = 0.0; + WN_0G_10 = 0.0; + + // Word type 0: I/NAV Spare Word + Time_0 = 0.0; + WN_0 = 0.0; + TOW_0 = 0.0; flag_TOW_6 = false; @@ -227,11 +229,11 @@ Galileo_Navigation_Message::Galileo_Navigation_Message() } -bool Galileo_Navigation_Message::CRC_test(std::bitset bits, boost::uint32_t checksum) +bool Galileo_Navigation_Message::CRC_test(std::bitset bits, uint32_t checksum) { CRC_Galileo_INAV_type CRC_Galileo; - boost::uint32_t crc_computed; + uint32_t crc_computed; // Galileo INAV 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 @@ -258,15 +260,15 @@ bool Galileo_Navigation_Message::CRC_test(std::bitset b } -unsigned long int Galileo_Navigation_Message::read_navigation_unsigned(std::bitset bits, const std::vector > parameter) +uint64_t Galileo_Navigation_Message::read_navigation_unsigned(std::bitset bits, const std::vector > parameter) { - unsigned long int value = 0; - int num_of_slices = parameter.size(); - for (int i = 0; i < num_of_slices; i++) + uint64_t value = 0ULL; + int32_t num_of_slices = parameter.size(); + for (int32_t i = 0; i < num_of_slices; i++) { - for (int j = 0; j < parameter[i].second; j++) + for (int32_t j = 0; j < parameter[i].second; j++) { - value <<= 1; //shift left + value <<= 1; // shift left if (bits[GALILEO_DATA_JK_BITS - parameter[i].first - j] == 1) { value += 1; // insert the bit @@ -277,18 +279,18 @@ unsigned long int Galileo_Navigation_Message::read_navigation_unsigned(std::bits } -unsigned long int Galileo_Navigation_Message::read_page_type_unsigned(std::bitset bits, const std::vector > parameter) +uint64_t Galileo_Navigation_Message::read_page_type_unsigned(std::bitset bits, const std::vector > parameter) { - unsigned long int value = 0; - int num_of_slices = parameter.size(); - for (int i = 0; i < num_of_slices; i++) + uint64_t value = 0ULL; + int32_t num_of_slices = parameter.size(); + for (int32_t i = 0; i < num_of_slices; i++) { - for (int j = 0; j < parameter[i].second; j++) + for (int32_t j = 0; j < parameter[i].second; j++) { - value <<= 1; //shift left + value <<= 1; // shift left if (bits[GALILEO_PAGE_TYPE_BITS - parameter[i].first - j] == 1) { - value += 1; // insert the bit + value += 1ULL; // insert the bit } } } @@ -296,59 +298,30 @@ unsigned long int Galileo_Navigation_Message::read_page_type_unsigned(std::bitse } -signed long int Galileo_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector > parameter) +int64_t Galileo_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector > parameter) { - signed long int value = 0; - int num_of_slices = parameter.size(); - // Discriminate between 64 bits and 32 bits compiler - int long_int_size_bytes = sizeof(signed long int); - if (long_int_size_bytes == 8) // if a long int takes 8 bytes, we are in a 64 bits system - { - // read the MSB and perform the sign extension - if (bits[GALILEO_DATA_JK_BITS - parameter[0].first] == 1) - { - value ^= 0xFFFFFFFFFFFFFFFF; //64 bits variable - } - else - { - value &= 0; - } + int64_t value = 0LL; + int32_t num_of_slices = parameter.size(); - for (int i = 0; i < num_of_slices; i++) - { - for (int j = 0; j < parameter[i].second; j++) - { - value <<= 1; //shift left - value &= 0xFFFFFFFFFFFFFFFE; //reset the corresponding bit (for the 64 bits variable) - if (bits[GALILEO_DATA_JK_BITS - parameter[i].first - j] == 1) - { - value += 1; // insert the bit - } - } - } + // read the MSB and perform the sign extension + if (bits[GALILEO_DATA_JK_BITS - parameter[0].first] == 1) + { + value ^= 0xFFFFFFFFFFFFFFFFLL; // 64 bits variable } - else // we assume we are in a 32 bits system + else { - // read the MSB and perform the sign extension - if (bits[GALILEO_DATA_JK_BITS - parameter[0].first] == 1) - { - value ^= 0xFFFFFFFF; - } - else - { - value &= 0; - } + value &= 0LL; + } - for (int i = 0; i < num_of_slices; i++) + for (int32_t i = 0; i < num_of_slices; i++) + { + for (int32_t j = 0; j < parameter[i].second; j++) { - for (int j = 0; j < parameter[i].second; j++) + value <<= 1; // shift left + value &= 0xFFFFFFFFFFFFFFFE; // reset the corresponding bit (for the 64 bits variable) + if (bits[GALILEO_DATA_JK_BITS - parameter[i].first - j] == 1) { - value <<= 1; //shift left - value &= 0xFFFFFFFE; //reset the corresponding bit - if (bits[GALILEO_DATA_JK_BITS - parameter[i].first - j] == 1) - { - value += 1; // insert the bit - } + value += 1LL; // insert the bit } } } @@ -356,7 +329,7 @@ signed long int Galileo_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector > parameter) +bool Galileo_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector > parameter) { bool value; if (bits[GALILEO_DATA_JK_BITS - parameter[0].first] == 1) @@ -371,20 +344,20 @@ bool Galileo_Navigation_Message::read_navigation_bool(std::bitset page_type_bits(page_number_bits); // from string to bitset - Page_type = static_cast(read_page_type_unsigned(page_type_bits, type)); + Page_type = static_cast(read_page_type_unsigned(page_type_bits, type)); Page_type_time_stamp = Page_type; std::string Data_jk_ephemeris = Data_k + Data_j; page_jk_decoder(Data_jk_ephemeris.c_str()); @@ -452,11 +425,11 @@ void Galileo_Navigation_Message::split_page(std::string page_string, int flag_ev } -bool Galileo_Navigation_Message::have_new_ephemeris() //Check if we have a new ephemeris stored in the galileo navigation class +bool Galileo_Navigation_Message::have_new_ephemeris() // Check if we have a new ephemeris stored in the galileo navigation class { if ((flag_ephemeris_1 == true) and (flag_ephemeris_2 == true) and (flag_ephemeris_3 == true) and (flag_ephemeris_4 == true) and (flag_iono_and_GST == true)) { - //if all ephemeris pages have the same IOD, then they belong to the same block + // if all ephemeris pages have the same IOD, then they belong to the same block if ((IOD_nav_1 == IOD_nav_2) and (IOD_nav_3 == IOD_nav_4) and (IOD_nav_1 == IOD_nav_3)) { std::cout << "Ephemeris (1, 2, 3, 4) have been received and belong to the same batch" << std::endl; @@ -479,9 +452,9 @@ bool Galileo_Navigation_Message::have_new_ephemeris() //Check if we have a new } -bool Galileo_Navigation_Message::have_new_iono_and_GST() //Check if we have a new iono data set stored in the galileo navigation class +bool Galileo_Navigation_Message::have_new_iono_and_GST() // Check if we have a new iono data set stored in the galileo navigation class { - if ((flag_iono_and_GST == true) and (flag_utc_model == true)) //the condition on flag_utc_model is added to have a time stamp for iono + if ((flag_iono_and_GST == true) and (flag_utc_model == true)) // the condition on flag_utc_model is added to have a time stamp for iono { flag_iono_and_GST = false; // clear the flag return true; @@ -503,11 +476,11 @@ bool Galileo_Navigation_Message::have_new_utc_model() // Check if we have a new } -bool Galileo_Navigation_Message::have_new_almanac() //Check if we have a new almanac data set stored in the galileo navigation class +bool Galileo_Navigation_Message::have_new_almanac() // Check if we have a new almanac data set stored in the galileo navigation class { if ((flag_almanac_1 == true) and (flag_almanac_2 == true) and (flag_almanac_3 == true) and (flag_almanac_4 == true)) { - //All almanac have been received + // All almanac have been received flag_almanac_1 = false; flag_almanac_2 = false; flag_almanac_3 = false; @@ -544,13 +517,13 @@ Galileo_Ephemeris Galileo_Navigation_Message::get_ephemeris() ephemeris.C_is_4 = C_is_4; // Amplitude of the sine harmonic correction term to the angle of inclination [radians] ephemeris.t0e_1 = t0e_1; // Ephemeris reference time [s] - /*Clock correction parameters*/ + // Clock correction parameters ephemeris.t0c_4 = t0c_4; // Clock correction data reference Time of Week [sec] ephemeris.af0_4 = af0_4; // SV clock bias correction coefficient [s] ephemeris.af1_4 = af1_4; // SV clock drift correction coefficient [s/s] ephemeris.af2_4 = af2_4; // SV clock drift rate correction coefficient [s/s^2] - /*GST*/ + // GST ephemeris.WN_5 = WN_5; // Week number ephemeris.TOW_5 = TOW_5; // Time of Week @@ -572,20 +545,19 @@ Galileo_Ephemeris Galileo_Navigation_Message::get_ephemeris() Galileo_Iono Galileo_Navigation_Message::get_iono() { Galileo_Iono iono; - /*Ionospheric correction*/ - /*Az*/ + // Ionospheric correction iono.ai0_5 = ai0_5; // Effective Ionisation Level 1st order parameter [sfu] iono.ai1_5 = ai1_5; // Effective Ionisation Level 2st order parameter [sfu/degree] iono.ai2_5 = ai2_5; // Effective Ionisation Level 3st order parameter [sfu/degree] - /*Ionospheric disturbance flag*/ + // Ionospheric disturbance flag iono.Region1_flag_5 = Region1_flag_5; // Ionospheric Disturbance Flag for region 1 iono.Region2_flag_5 = Region2_flag_5; // Ionospheric Disturbance Flag for region 2 iono.Region3_flag_5 = Region3_flag_5; // Ionospheric Disturbance Flag for region 3 iono.Region4_flag_5 = Region4_flag_5; // Ionospheric Disturbance Flag for region 4 iono.Region5_flag_5 = Region5_flag_5; // Ionospheric Disturbance Flag for region 5 - /*GST*/ + // GST // This is the ONLY page containing the Week Number (WN) iono.TOW_5 = TOW_5; iono.WN_5 = WN_5; @@ -596,8 +568,7 @@ Galileo_Iono Galileo_Navigation_Message::get_iono() Galileo_Utc_Model Galileo_Navigation_Message::get_utc_model() { Galileo_Utc_Model utc_model; - //Gal_utc_model.valid = flag_utc_model_valid; - /*Word type 6: GST-UTC conversion parameters*/ + // Word type 6: GST-UTC conversion parameters utc_model.A0_6 = A0_6; utc_model.A1_6 = A1_6; utc_model.Delta_tLS_6 = Delta_tLS_6; @@ -607,17 +578,19 @@ Galileo_Utc_Model Galileo_Navigation_Message::get_utc_model() utc_model.DN_6 = DN_6; utc_model.Delta_tLSF_6 = Delta_tLSF_6; utc_model.flag_utc_model = flag_utc_model; - /*GST*/ - //utc_model.WN_5 = WN_5; //Week number - //utc_model.TOW_5 = WN_5; //Time of Week + // GPS to Galileo GST conversion parameters + utc_model.A_0G_10 = A_0G_10; + utc_model.A_1G_10 = A_1G_10; + utc_model.t_0G_10 = t_0G_10; + utc_model.WN_0G_10 = WN_0G_10; return utc_model; } -Galileo_Almanac Galileo_Navigation_Message::get_almanac() +Galileo_Almanac_Helper Galileo_Navigation_Message::get_almanac() { - Galileo_Almanac almanac; - /*Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number*/ + Galileo_Almanac_Helper almanac; + // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number almanac.IOD_a_7 = IOD_a_7; almanac.WN_a_7 = WN_a_7; almanac.t0a_7 = t0a_7; @@ -630,7 +603,7 @@ Galileo_Almanac Galileo_Navigation_Message::get_almanac() almanac.Omega_dot_7 = Omega_dot_7; almanac.M0_7 = M0_7; - /*Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2)*/ + // Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2) almanac.IOD_a_8 = IOD_a_8; almanac.af0_8 = af0_8; almanac.af1_8 = af1_8; @@ -644,7 +617,7 @@ Galileo_Almanac Galileo_Navigation_Message::get_almanac() almanac.Omega0_8 = Omega0_8; almanac.Omega_dot_8 = Omega_dot_8; - /*Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2)*/ + // Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2) almanac.IOD_a_9 = IOD_a_9; almanac.WN_a_9 = WN_a_9; almanac.t0a_9 = t0a_9; @@ -659,7 +632,7 @@ Galileo_Almanac Galileo_Navigation_Message::get_almanac() almanac.omega_9 = omega_9; almanac.delta_i_9 = delta_i_9; - /*Word type 10: Almanac for SVID3 (2/2)*/ + // Word type 10: Almanac for SVID3 (2/2) almanac.IOD_a_10 = IOD_a_10; almanac.Omega0_10 = Omega0_10; almanac.Omega_dot_10 = Omega_dot_10; @@ -669,31 +642,24 @@ Galileo_Almanac Galileo_Navigation_Message::get_almanac() almanac.E5b_HS_10 = E5b_HS_10; almanac.E1B_HS_10 = E1B_HS_10; - /*GPS to Galileo GST conversion parameters*/ - almanac.A_0G_10 = A_0G_10; - almanac.A_1G_10 = A_1G_10; - almanac.t_0G_10 = t_0G_10; - almanac.WN_0G_10 = WN_0G_10; - return almanac; } -int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) +int32_t Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) { - int page_number = 0; + int32_t page_number = 0; std::string data_jk_string = data_jk; std::bitset data_jk_bits(data_jk_string); - //DLOG(INFO) << "Data_jk_bits (bitset) "<< endl << data_jk_bits << endl; - page_number = static_cast(read_navigation_unsigned(data_jk_bits, PAGE_TYPE_bit)); + page_number = static_cast(read_navigation_unsigned(data_jk_bits, PAGE_TYPE_bit)); LOG(INFO) << "Page number = " << page_number; switch (page_number) { - case 1: /*Word type 1: Ephemeris (1/4)*/ - IOD_nav_1 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_nav_1_bit)); + case 1: // Word type 1: Ephemeris (1/4) + IOD_nav_1 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_nav_1_bit)); DLOG(INFO) << "IOD_nav_1= " << IOD_nav_1; t0e_1 = static_cast(read_navigation_unsigned(data_jk_bits, T0E_1_bit)); t0e_1 = t0e_1 * t0e_1_LSB; @@ -711,8 +677,8 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; - case 2: /*Word type 2: Ephemeris (2/4)*/ - IOD_nav_2 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_nav_2_bit)); + case 2: // Word type 2: Ephemeris (2/4) + IOD_nav_2 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_nav_2_bit)); DLOG(INFO) << "IOD_nav_2= " << IOD_nav_2; OMEGA_0_2 = static_cast(read_navigation_signed(data_jk_bits, OMEGA_0_2_bit)); OMEGA_0_2 = OMEGA_0_2 * OMEGA_0_2_LSB; @@ -730,8 +696,8 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; - case 3: /*Word type 3: Ephemeris (3/4) and SISA*/ - IOD_nav_3 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_nav_3_bit)); + case 3: // Word type 3: Ephemeris (3/4) and SISA + IOD_nav_3 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_nav_3_bit)); DLOG(INFO) << "IOD_nav_3= " << IOD_nav_3; OMEGA_dot_3 = static_cast(read_navigation_signed(data_jk_bits, OMEGA_dot_3_bit)); OMEGA_dot_3 = OMEGA_dot_3 * OMEGA_dot_3_LSB; @@ -757,10 +723,10 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; - case 4: /* Word type 4: Ephemeris (4/4) and Clock correction parameters*/ - IOD_nav_4 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_nav_4_bit)); + case 4: // Word type 4: Ephemeris (4/4) and Clock correction parameters + IOD_nav_4 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_nav_4_bit)); DLOG(INFO) << "IOD_nav_4= " << IOD_nav_4; - SV_ID_PRN_4 = static_cast(read_navigation_unsigned(data_jk_bits, SV_ID_PRN_4_bit)); + SV_ID_PRN_4 = static_cast(read_navigation_unsigned(data_jk_bits, SV_ID_PRN_4_bit)); DLOG(INFO) << "SV_ID_PRN_4= " << SV_ID_PRN_4; C_ic_4 = static_cast(read_navigation_signed(data_jk_bits, C_ic_4_bit)); C_ic_4 = C_ic_4 * C_ic_4_LSB; @@ -768,7 +734,7 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) C_is_4 = static_cast(read_navigation_signed(data_jk_bits, C_is_4_bit)); C_is_4 = C_is_4 * C_is_4_LSB; DLOG(INFO) << "C_is_4= " << C_is_4; - /*Clock correction parameters*/ + // Clock correction parameters t0c_4 = static_cast(read_navigation_unsigned(data_jk_bits, t0c_4_bit)); t0c_4 = t0c_4 * t0c_4_LSB; DLOG(INFO) << "t0c_4= " << t0c_4; @@ -787,9 +753,8 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; - case 5: /*Word type 5: Ionospheric correction, BGD, signal health and data validity status and GST*/ - /*Ionospheric correction*/ - /*Az*/ + case 5: // Word type 5: Ionospheric correction, BGD, signal health and data validity status and GST + // Ionospheric correction ai0_5 = static_cast(read_navigation_unsigned(data_jk_bits, ai0_5_bit)); ai0_5 = ai0_5 * ai0_5_LSB; DLOG(INFO) << "ai0_5= " << ai0_5; @@ -799,7 +764,7 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) ai2_5 = static_cast(read_navigation_signed(data_jk_bits, ai2_5_bit)); ai2_5 = ai2_5 * ai2_5_LSB; DLOG(INFO) << "ai2_5= " << ai2_5; - /*Ionospheric disturbance flag*/ + // Ionospheric disturbance flag Region1_flag_5 = static_cast(read_navigation_bool(data_jk_bits, Region1_5_bit)); DLOG(INFO) << "Region1_flag_5= " << Region1_flag_5; Region2_flag_5 = static_cast(read_navigation_bool(data_jk_bits, Region2_5_bit)); @@ -816,28 +781,28 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) BGD_E1E5b_5 = static_cast(read_navigation_signed(data_jk_bits, BGD_E1E5b_5_bit)); BGD_E1E5b_5 = BGD_E1E5b_5 * BGD_E1E5b_5_LSB; DLOG(INFO) << "BGD_E1E5b_5= " << BGD_E1E5b_5; - E5b_HS_5 = static_cast(read_navigation_unsigned(data_jk_bits, E5b_HS_5_bit)); + E5b_HS_5 = static_cast(read_navigation_unsigned(data_jk_bits, E5b_HS_5_bit)); DLOG(INFO) << "E5b_HS_5= " << E5b_HS_5; - E1B_HS_5 = static_cast(read_navigation_unsigned(data_jk_bits, E1B_HS_5_bit)); + E1B_HS_5 = static_cast(read_navigation_unsigned(data_jk_bits, E1B_HS_5_bit)); DLOG(INFO) << "E1B_HS_5= " << E1B_HS_5; - E5b_DVS_5 = static_cast(read_navigation_unsigned(data_jk_bits, E5b_DVS_5_bit)); + E5b_DVS_5 = static_cast(read_navigation_unsigned(data_jk_bits, E5b_DVS_5_bit)); DLOG(INFO) << "E5b_DVS_5= " << E5b_DVS_5; - E1B_DVS_5 = static_cast(read_navigation_unsigned(data_jk_bits, E1B_DVS_5_bit)); + E1B_DVS_5 = static_cast(read_navigation_unsigned(data_jk_bits, E1B_DVS_5_bit)); DLOG(INFO) << "E1B_DVS_5= " << E1B_DVS_5; - /*GST*/ + // GST WN_5 = static_cast(read_navigation_unsigned(data_jk_bits, WN_5_bit)); DLOG(INFO) << "WN_5= " << WN_5; TOW_5 = static_cast(read_navigation_unsigned(data_jk_bits, TOW_5_bit)); DLOG(INFO) << "TOW_5= " << TOW_5; - flag_TOW_5 = true; //set to false externally + flag_TOW_5 = true; // set to false externally spare_5 = static_cast(read_navigation_unsigned(data_jk_bits, spare_5_bit)); DLOG(INFO) << "spare_5= " << spare_5; - flag_iono_and_GST = true; //set to false externally - flag_TOW_set = true; //set to false externally + flag_iono_and_GST = true; // set to false externally + flag_TOW_set = true; // set to false externally DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; - case 6: /*Word type 6: GST-UTC conversion parameters*/ + case 6: // Word type 6: GST-UTC conversion parameters A0_6 = static_cast(read_navigation_signed(data_jk_bits, A0_6_bit)); A0_6 = A0_6 * A0_6_LSB; DLOG(INFO) << "A0_6= " << A0_6; @@ -859,16 +824,16 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) DLOG(INFO) << "Delta_tLSF_6= " << Delta_tLSF_6; TOW_6 = static_cast(read_navigation_unsigned(data_jk_bits, TOW_6_bit)); DLOG(INFO) << "TOW_6= " << TOW_6; - flag_TOW_6 = true; //set to false externally - flag_utc_model = true; //set to false externally - flag_TOW_set = true; //set to false externally + flag_TOW_6 = true; // set to false externally + flag_utc_model = true; // set to false externally + flag_TOW_set = true; // set to false externally DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; - case 7: /*Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number*/ + case 7: // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number IOD_a_7 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_a_7_bit)); DLOG(INFO) << "IOD_a_7= " << IOD_a_7; - WN_a_7 = static_cast(read_navigation_unsigned(data_jk_bits, WN_a_7_bit)); + WN_a_7 = static_cast(read_navigation_unsigned(data_jk_bits, WN_a_7_bit)); DLOG(INFO) << "WN_a_7= " << WN_a_7; t0a_7 = static_cast(read_navigation_unsigned(data_jk_bits, t0a_7_bit)); t0a_7 = t0a_7 * t0a_7_LSB; @@ -900,7 +865,7 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; - case 8: /*Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2)*/ + case 8: // Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2)*/ IOD_a_8 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_a_8_bit)); DLOG(INFO) << "IOD_a_8= " << IOD_a_8; af0_8 = static_cast(read_navigation_signed(data_jk_bits, af0_8_bit)); @@ -909,11 +874,11 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) af1_8 = static_cast(read_navigation_signed(data_jk_bits, af1_8_bit)); af1_8 = af1_8 * af1_8_LSB; DLOG(INFO) << "af1_8= " << af1_8; - E5b_HS_8 = static_cast(read_navigation_unsigned(data_jk_bits, E5b_HS_8_bit)); + E5b_HS_8 = static_cast(read_navigation_unsigned(data_jk_bits, E5b_HS_8_bit)); DLOG(INFO) << "E5b_HS_8= " << E5b_HS_8; - E1B_HS_8 = static_cast(read_navigation_unsigned(data_jk_bits, E1B_HS_8_bit)); + E1B_HS_8 = static_cast(read_navigation_unsigned(data_jk_bits, E1B_HS_8_bit)); DLOG(INFO) << "E1B_HS_8= " << E1B_HS_8; - SVID2_8 = static_cast(read_navigation_unsigned(data_jk_bits, SVID2_8_bit)); + SVID2_8 = static_cast(read_navigation_unsigned(data_jk_bits, SVID2_8_bit)); DLOG(INFO) << "SVID2_8= " << SVID2_8; DELTA_A_8 = static_cast(read_navigation_signed(data_jk_bits, DELTA_A_8_bit)); DELTA_A_8 = DELTA_A_8 * DELTA_A_8_LSB; @@ -937,10 +902,10 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; - case 9: /*Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2)*/ + case 9: // Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2) IOD_a_9 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_a_9_bit)); DLOG(INFO) << "IOD_a_9= " << IOD_a_9; - WN_a_9 = static_cast(read_navigation_unsigned(data_jk_bits, WN_a_9_bit)); + WN_a_9 = static_cast(read_navigation_unsigned(data_jk_bits, WN_a_9_bit)); DLOG(INFO) << "WN_a_9= " << WN_a_9; t0a_9 = static_cast(read_navigation_unsigned(data_jk_bits, t0a_9_bit)); t0a_9 = t0a_9 * t0a_9_LSB; @@ -954,11 +919,11 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) af1_9 = static_cast(read_navigation_signed(data_jk_bits, af1_9_bit)); af1_9 = af1_9 * af1_9_LSB; DLOG(INFO) << "af1_9= " << af1_9; - E5b_HS_9 = static_cast(read_navigation_unsigned(data_jk_bits, E5b_HS_9_bit)); + E5b_HS_9 = static_cast(read_navigation_unsigned(data_jk_bits, E5b_HS_9_bit)); DLOG(INFO) << "E5b_HS_9= " << E5b_HS_9; - E1B_HS_9 = static_cast(read_navigation_unsigned(data_jk_bits, E1B_HS_9_bit)); + E1B_HS_9 = static_cast(read_navigation_unsigned(data_jk_bits, E1B_HS_9_bit)); DLOG(INFO) << "E1B_HS_9= " << E1B_HS_9; - SVID3_9 = static_cast(read_navigation_unsigned(data_jk_bits, SVID3_9_bit)); + SVID3_9 = static_cast(read_navigation_unsigned(data_jk_bits, SVID3_9_bit)); DLOG(INFO) << "SVID3_9= " << SVID3_9; DELTA_A_9 = static_cast(read_navigation_signed(data_jk_bits, DELTA_A_9_bit)); DELTA_A_9 = DELTA_A_9 * DELTA_A_9_LSB; @@ -976,7 +941,7 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; - case 10: /*Word type 10: Almanac for SVID3 (2/2) and GST-GPS conversion parameters*/ + case 10: // Word type 10: Almanac for SVID3 (2/2) and GST-GPS conversion parameters IOD_a_10 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_a_10_bit)); DLOG(INFO) << "IOD_a_10= " << IOD_a_10; Omega0_10 = static_cast(read_navigation_signed(data_jk_bits, Omega0_10_bit)); @@ -994,9 +959,9 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) af1_10 = static_cast(read_navigation_signed(data_jk_bits, af1_10_bit)); af1_10 = af1_10 * af1_10_LSB; DLOG(INFO) << "af1_10= " << af1_10; - E5b_HS_10 = static_cast(read_navigation_unsigned(data_jk_bits, E5b_HS_10_bit)); + E5b_HS_10 = static_cast(read_navigation_unsigned(data_jk_bits, E5b_HS_10_bit)); DLOG(INFO) << "E5b_HS_10= " << E5b_HS_10; - E1B_HS_10 = static_cast(read_navigation_unsigned(data_jk_bits, E1B_HS_10_bit)); + E1B_HS_10 = static_cast(read_navigation_unsigned(data_jk_bits, E1B_HS_10_bit)); DLOG(INFO) << "E1B_HS_10= " << E1B_HS_10; A_0G_10 = static_cast(read_navigation_signed(data_jk_bits, A_0G_10_bit)); A_0G_10 = A_0G_10 * A_0G_10_LSB; @@ -1017,7 +982,7 @@ int Galileo_Navigation_Message::page_jk_decoder(const char *data_jk) DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; - case 0: /*Word type 0: I/NAV Spare Word*/ + case 0: // Word type 0: I/NAV Spare Word Time_0 = static_cast(read_navigation_unsigned(data_jk_bits, Time_0_bit)); DLOG(INFO) << "Time_0= " << Time_0; WN_0 = static_cast(read_navigation_unsigned(data_jk_bits, WN_0_bit)); diff --git a/src/core/system_parameters/galileo_navigation_message.h b/src/core/system_parameters/galileo_navigation_message.h index 2108a1568..1e71baafd 100644 --- a/src/core/system_parameters/galileo_navigation_message.h +++ b/src/core/system_parameters/galileo_navigation_message.h @@ -35,11 +35,11 @@ #include "galileo_ephemeris.h" #include "galileo_iono.h" -#include "galileo_almanac.h" +#include "galileo_almanac_helper.h" #include "galileo_utc_model.h" #include "Galileo_E1.h" -#include // for boost::uint32_t #include +#include #include #include #include @@ -54,16 +54,15 @@ class Galileo_Navigation_Message { private: - bool CRC_test(std::bitset bits, boost::uint32_t checksum); - bool read_navigation_bool(std::bitset bits, const std::vector > parameter); - //void print_galileo_word_bytes(unsigned int GPS_word); - unsigned long int read_navigation_unsigned(std::bitset bits, const std::vector > parameter); - unsigned long int read_page_type_unsigned(std::bitset bits, const std::vector > parameter); - signed long int read_navigation_signed(std::bitset bits, const std::vector > parameter); + bool CRC_test(std::bitset bits, uint32_t checksum); + bool read_navigation_bool(std::bitset bits, const std::vector > parameter); + uint64_t read_navigation_unsigned(std::bitset bits, const std::vector > parameter); + uint64_t read_page_type_unsigned(std::bitset bits, const std::vector > parameter); + int64_t read_navigation_signed(std::bitset bits, const std::vector > parameter); public: - int Page_type_time_stamp; - int flag_even_word; + int32_t Page_type_time_stamp; + int32_t flag_even_word; std::string page_Even; bool flag_CRC_test; bool flag_all_ephemeris; //!< Flag indicating that all words containing ephemeris have been received @@ -84,7 +83,7 @@ public: bool flag_almanac_3; //!< Flag indicating that almanac 3/4 (word 9) have been received bool flag_almanac_4; //!< Flag indicating that almanac 4/4 (word 10) have been received - int IOD_ephemeris; + int32_t IOD_ephemeris; bool flag_GGTO; bool flag_GGTO_1; @@ -92,22 +91,22 @@ public: bool flag_GGTO_3; bool flag_GGTO_4; - /*Word type 1: Ephemeris (1/4)*/ - int IOD_nav_1; //!< IOD_nav page 1 - double t0e_1; //!< Ephemeris reference time [s] - double M0_1; //!< Mean anomaly at reference time [semi-circles] - double e_1; //!< Eccentricity - double A_1; //!< Square root of the semi-major axis [meters^1/2] + // Word type 1: Ephemeris (1/4) + int32_t IOD_nav_1; //!< IOD_nav page 1 + double t0e_1; //!< Ephemeris reference time [s] + double M0_1; //!< Mean anomaly at reference time [semi-circles] + double e_1; //!< Eccentricity + double A_1; //!< Square root of the semi-major axis [meters^1/2] - /*Word type 2: Ephemeris (2/4)*/ - int IOD_nav_2; //!< IOD_nav page 2 - double OMEGA_0_2; //!< Longitude of ascending node of orbital plane at weekly epoch [semi-circles] - double i_0_2; //!< Inclination angle at reference time [semi-circles] - double omega_2; //!< Argument of perigee [semi-circles] - double iDot_2; //!< Rate of inclination angle [semi-circles/sec] + // Word type 2: Ephemeris (2/4) + int32_t IOD_nav_2; //!< IOD_nav page 2 + double OMEGA_0_2; //!< Longitude of ascending node of orbital plane at weekly epoch [semi-circles] + double i_0_2; //!< Inclination angle at reference time [semi-circles] + double omega_2; //!< Argument of perigee [semi-circles] + double iDot_2; //!< Rate of inclination angle [semi-circles/sec] - /*Word type 3: Ephemeris (3/4) and SISA*/ - int IOD_nav_3; // + // Word type 3: Ephemeris (3/4) and SISA + int32_t IOD_nav_3; // double OMEGA_dot_3; //!< Rate of right ascension [semi-circles/sec] double delta_n_3; //!< Mean motion difference from computed value [semi-circles/sec] double C_uc_3; //!< Amplitude of the cosine harmonic correction term to the argument of latitude [radians] @@ -116,25 +115,26 @@ public: double C_rs_3; //!< Amplitude of the sine harmonic correction term to the orbit radius [meters] double SISA_3; - /*Word type 4: Ephemeris (4/4) and Clock correction parameters*/ - int IOD_nav_4; // - int SV_ID_PRN_4; // - double C_ic_4; //!= 0) // is not in the past { - //Detect if the effectivity time and user's time is within six hours = 6 * 60 *60 = 21600 s + // Detect if the effectivity time and user's time is within six hours = 6 * 60 *60 = 21600 s int secondOfLeapSecondEvent = DN_6 * 24 * 60 * 60; if (std::abs(t_e - secondOfLeapSecondEvent) > 21600) { @@ -74,7 +79,7 @@ double Galileo_Utc_Model::GST_to_UTC_time(double t_e, int WN) { /* 5.1.7b GST->UTC case b * Whenever the user's current time falls within the time span of six hours - * prior to the leap second adjustment to six hours after the adjustment time, , + * prior to the leap second adjustment to six hours after the adjustment time, * the effective time is computed according to the following equations: */ Delta_t_Utc = Delta_tLS_6 + A0_6 + A1_6 * (t_e - t0t_6 + 604800 * static_cast((WN % 256) - WNot_6)); diff --git a/src/core/system_parameters/galileo_utc_model.h b/src/core/system_parameters/galileo_utc_model.h index 00822c44c..174fb0754 100644 --- a/src/core/system_parameters/galileo_utc_model.h +++ b/src/core/system_parameters/galileo_utc_model.h @@ -33,6 +33,7 @@ #ifndef GNSS_SDR_GALILEO_UTC_MODEL_H_ #define GNSS_SDR_GALILEO_UTC_MODEL_H_ +#include /*! * \brief This class is a storage for the GALILEO UTC MODEL data as described in Galileo ICD @@ -42,7 +43,7 @@ class Galileo_Utc_Model { public: - /*Word type 6: GST-UTC conversion parameters*/ + // Word type 6: GST-UTC conversion parameters double A0_6; double A1_6; double Delta_tLS_6; @@ -52,12 +53,42 @@ public: double DN_6; double Delta_tLSF_6; bool flag_utc_model; + + // GPS to Galileo GST conversion parameters + double A_0G_10; + double A_1G_10; + double t_0G_10; + double WN_0G_10; + //double TOW_6; double GST_to_UTC_time(double t_e, int WN); //!< GST-UTC Conversion Algorithm and Parameters /*! * Default constructor */ Galileo_Utc_Model(); + + template + + /*! + * \brief Serialize is a boost standard method to be called by the boost XML serialization. + Here is used to save the UTC data on disk file. + */ + inline void serialize(Archive& archive, const unsigned int version) + { + using boost::serialization::make_nvp; + if (version) + { + }; + archive& make_nvp("A0_6", A0_6); + archive& make_nvp("A1_6", A1_6); + archive& make_nvp("Delta_tLS_6", Delta_tLS_6); + archive& make_nvp("t0t_6", t0t_6); + archive& make_nvp("WNot_6", WNot_6); + archive& make_nvp("WN_LSF_6", WN_LSF_6); + archive& make_nvp("DN_6", DN_6); + archive& make_nvp("Delta_tLSF_6", Delta_tLSF_6); + archive& make_nvp("flag_utc_model", flag_utc_model); + } }; #endif diff --git a/src/core/system_parameters/glonass_gnav_almanac.cc b/src/core/system_parameters/glonass_gnav_almanac.cc index 0ed27cb6f..e89d31f64 100644 --- a/src/core/system_parameters/glonass_gnav_almanac.cc +++ b/src/core/system_parameters/glonass_gnav_almanac.cc @@ -35,8 +35,8 @@ Glonass_Gnav_Almanac::Glonass_Gnav_Almanac() { i_satellite_freq_channel = 0; - i_satellite_PRN = 0; - i_satellite_slot_number = 0; + i_satellite_PRN = 0U; + i_satellite_slot_number = 0U; d_n_A = 0.0; d_H_n_A = 0.0; diff --git a/src/core/system_parameters/glonass_gnav_almanac.h b/src/core/system_parameters/glonass_gnav_almanac.h index f36fdfbb0..37927bc6b 100644 --- a/src/core/system_parameters/glonass_gnav_almanac.h +++ b/src/core/system_parameters/glonass_gnav_almanac.h @@ -35,6 +35,7 @@ #define GNSS_SDR_GLONASS_ALMANAC_H_ #include +#include /*! * \brief This class is a storage for the GLONASS SV ALMANAC data as described GLONASS ICD (Edition 5.1) @@ -60,15 +61,15 @@ public: bool d_l_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] // Satellite Identification Information - int i_satellite_freq_channel; //!< SV Frequency Channel Number - unsigned int i_satellite_PRN; //!< SV PRN Number, equivalent to slot number for compatibility with GPS - unsigned int i_satellite_slot_number; //!< SV Slot Number + int32_t i_satellite_freq_channel; //!< SV Frequency Channel Number + uint32_t i_satellite_PRN; //!< SV PRN Number, equivalent to slot number for compatibility with GPS + uint32_t i_satellite_slot_number; //!< SV Slot Number template /*! * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the almanac data on disk file. */ - void serialize(Archive& archive, const unsigned int version) + void serialize(Archive& archive, const uint32_t version) { using boost::serialization::make_nvp; if (version) diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.cc b/src/core/system_parameters/glonass_gnav_ephemeris.cc index 2a6ea3eb0..b063d22ba 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.cc +++ b/src/core/system_parameters/glonass_gnav_ephemeris.cc @@ -69,8 +69,8 @@ Glonass_Gnav_Ephemeris::Glonass_Gnav_Ephemeris() // Satellite Identification Information i_satellite_freq_channel = 0; //!< SV Frequency Channel Number - i_satellite_PRN = 0; //!< SV PRN Number, equivalent to slot number for compatibility with GPS - i_satellite_slot_number = 0; //!< SV Slot Number + i_satellite_PRN = 0U; //!< SV PRN Number, equivalent to slot number for compatibility with GPS + i_satellite_slot_number = 0U; //!< SV Slot Number d_yr = 1972; //!< Current year, defaults to 1972 (UTC Epoch with leap seconds) d_satClkDrift = 0.0; //!< GLONASS clock error d_dtr = 0.0; //!< relativistic clock correction term diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.h b/src/core/system_parameters/glonass_gnav_ephemeris.h index ef375ab2e..ebea99d58 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.h +++ b/src/core/system_parameters/glonass_gnav_ephemeris.h @@ -37,7 +37,7 @@ #include #include - +#include /*! * \brief This class is a storage and orbital model functions for the GLONASS SV ephemeris data as described in GLONASS ICD (Edition 5.1) @@ -86,26 +86,26 @@ public: bool d_l3rd_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is healthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] bool d_l5th_n; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is healthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] - // Inmediate deliverables of ephemeris information + // Immediate deliverables of ephemeris information // Satellite Identification Information - int i_satellite_freq_channel; //!< SV Frequency Channel Number - unsigned int i_satellite_PRN; //!< SV PRN Number, equivalent to slot number for compatibility with GPS - unsigned int i_satellite_slot_number; //!< SV Slot Number - double d_yr; //!< Current year - double d_satClkDrift; //!< GLONASS clock error - double d_dtr; //!< relativistic clock correction term - double d_iode; //!< Issue of data, ephemeris (Bit 0-6 of tb) - double d_tau_c; //!< GLONASST 2 UTC correction (todo) may be eliminated - double d_TOW; //!< GLONASST IN GPST seconds of week - double d_WN; //!< GLONASST IN GPST week number of the start of frame - double d_tod; //!< Time of Day since ephemeris where decoded + int32_t i_satellite_freq_channel; //!< SV Frequency Channel Number + uint32_t i_satellite_PRN; //!< SV PRN Number, equivalent to slot number for compatibility with GPS + uint32_t i_satellite_slot_number; //!< SV Slot Number + double d_yr; //!< Current year + double d_satClkDrift; //!< GLONASS clock error + double d_dtr; //!< relativistic clock correction term + double d_iode; //!< Issue of data, ephemeris (Bit 0-6 of tb) + double d_tau_c; //!< GLONASST 2 UTC correction (todo) may be eliminated + double d_TOW; //!< GLONASST IN GPST seconds of week + double d_WN; //!< GLONASST IN GPST week number of the start of frame + double d_tod; //!< Time of Day since ephemeris where decoded template /*! * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file. */ - void serialize(Archive& archive, const unsigned int version) + void serialize(Archive& archive, const uint32_t version) { using boost::serialization::make_nvp; if (version) diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.cc b/src/core/system_parameters/glonass_gnav_navigation_message.cc index 469c42ae3..db4a9f9a4 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.cc +++ b/src/core/system_parameters/glonass_gnav_navigation_message.cc @@ -38,8 +38,8 @@ void Glonass_Gnav_Navigation_Message::reset() { // Satellite Identification - i_satellite_PRN = 0; - i_alm_satellite_slot_number = 0; //!< SV Orbit Slot Number + i_satellite_PRN = 0U; + i_alm_satellite_slot_number = 0; // SV Orbit Slot Number flag_update_slot_number = false; // Ephmeris Flags @@ -63,17 +63,17 @@ void Glonass_Gnav_Navigation_Message::reset() flag_almanac_str_15 = false; // UTC and System Clocks Flags - flag_utc_model_valid = false; //!< If set, it indicates that the UTC model parameters are filled - flag_utc_model_str_5 = false; //!< Clock info send in string 5 of navigation data - flag_utc_model_str_15 = false; //!< Clock info send in string 15 of frame 5 of navigation data + flag_utc_model_valid = false; // If set, it indicates that the UTC model parameters are filled + flag_utc_model_str_5 = false; // Clock info send in string 5 of navigation data + flag_utc_model_str_15 = false; // Clock info send in string 15 of frame 5 of navigation data // broadcast orbit 1 flag_TOW_set = false; flag_TOW_new = false; flag_CRC_test = false; - d_frame_ID = 0; - d_string_ID = 0; + d_frame_ID = 0U; + d_string_ID = 0U; i_channel_ID = 0; // Clock terms @@ -83,15 +83,15 @@ void Glonass_Gnav_Navigation_Message::reset() // Data update information d_previous_tb = 0.0; - for (unsigned int i = 0; i < GLONASS_CA_NBR_SATS; i++) + for (uint32_t i = 0; i < GLONASS_CA_NBR_SATS; i++) d_previous_Na[i] = 0.0; - std::map satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus + std::map satelliteBlock; // Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus auto gnss_sat = Gnss_Satellite(); std::string _system("GLONASS"); //TODO SHould number of channels be hardcoded? - for (unsigned int i = 1; i < 14; i++) + for (uint32_t i = 1; i < 14; i++) { satelliteBlock[i] = gnss_sat.what_block(_system, i); } @@ -106,94 +106,94 @@ Glonass_Gnav_Navigation_Message::Glonass_Gnav_Navigation_Message() bool Glonass_Gnav_Navigation_Message::CRC_test(std::bitset bits) { - int sum_bits = 0; - int sum_hamming = 0; - int C1 = 0; - int C2 = 0; - int C3 = 0; - int C4 = 0; - int C5 = 0; - int C6 = 0; - int C7 = 0; - int C_Sigma = 0; - std::vector string_bits(GLONASS_GNAV_STRING_BITS); + int32_t sum_bits = 0; + int32_t sum_hamming = 0; + int32_t C1 = 0; + int32_t C2 = 0; + int32_t C3 = 0; + int32_t C4 = 0; + int32_t C5 = 0; + int32_t C6 = 0; + int32_t C7 = 0; + int32_t C_Sigma = 0; + std::vector string_bits(GLONASS_GNAV_STRING_BITS); - //!< Populate data and hamming code vectors - for (int i = 0; i < static_cast(GLONASS_GNAV_STRING_BITS); i++) + // Populate data and hamming code vectors + for (int32_t i = 0; i < static_cast(GLONASS_GNAV_STRING_BITS); i++) { - string_bits[i] = static_cast(bits[i]); + string_bits[i] = static_cast(bits[i]); } - //!< Compute C1 term + // Compute C1 term sum_bits = 0; - for (int i = 0; i < static_cast(GLONASS_GNAV_CRC_I_INDEX.size()); i++) + for (int32_t i = 0; i < static_cast(GLONASS_GNAV_CRC_I_INDEX.size()); i++) { sum_bits += string_bits[GLONASS_GNAV_CRC_I_INDEX[i] - 1]; } C1 = string_bits[0] ^ (sum_bits % 2); - //!< Compute C2 term + // Compute C2 term sum_bits = 0; - for (int j = 0; j < static_cast(GLONASS_GNAV_CRC_J_INDEX.size()); j++) + for (int32_t j = 0; j < static_cast(GLONASS_GNAV_CRC_J_INDEX.size()); j++) { sum_bits += string_bits[GLONASS_GNAV_CRC_J_INDEX[j] - 1]; } C2 = (string_bits[1]) ^ (sum_bits % 2); - //!< Compute C3 term + // Compute C3 term sum_bits = 0; - for (int k = 0; k < static_cast(GLONASS_GNAV_CRC_K_INDEX.size()); k++) + for (int32_t k = 0; k < static_cast(GLONASS_GNAV_CRC_K_INDEX.size()); k++) { sum_bits += string_bits[GLONASS_GNAV_CRC_K_INDEX[k] - 1]; } C3 = string_bits[2] ^ (sum_bits % 2); - //!< Compute C4 term + // Compute C4 term sum_bits = 0; - for (int l = 0; l < static_cast(GLONASS_GNAV_CRC_L_INDEX.size()); l++) + for (int32_t l = 0; l < static_cast(GLONASS_GNAV_CRC_L_INDEX.size()); l++) { sum_bits += string_bits[GLONASS_GNAV_CRC_L_INDEX[l] - 1]; } C4 = string_bits[3] ^ (sum_bits % 2); - //!< Compute C5 term + // Compute C5 term sum_bits = 0; - for (int m = 0; m < static_cast(GLONASS_GNAV_CRC_M_INDEX.size()); m++) + for (int32_t m = 0; m < static_cast(GLONASS_GNAV_CRC_M_INDEX.size()); m++) { sum_bits += string_bits[GLONASS_GNAV_CRC_M_INDEX[m] - 1]; } C5 = string_bits[4] ^ (sum_bits % 2); - //!< Compute C6 term + // Compute C6 term sum_bits = 0; - for (int n = 0; n < static_cast(GLONASS_GNAV_CRC_N_INDEX.size()); n++) + for (int32_t n = 0; n < static_cast(GLONASS_GNAV_CRC_N_INDEX.size()); n++) { sum_bits += string_bits[GLONASS_GNAV_CRC_N_INDEX[n] - 1]; } C6 = string_bits[5] ^ (sum_bits % 2); - //!< Compute C7 term + // Compute C7 term sum_bits = 0; - for (int p = 0; p < static_cast(GLONASS_GNAV_CRC_P_INDEX.size()); p++) + for (int32_t p = 0; p < static_cast(GLONASS_GNAV_CRC_P_INDEX.size()); p++) { sum_bits += string_bits[GLONASS_GNAV_CRC_P_INDEX[p] - 1]; } C7 = string_bits[6] ^ (sum_bits % 2); - //!< Compute C_Sigma term + // Compute C_Sigma term sum_bits = 0; sum_hamming = 0; - for (int q = 0; q < static_cast(GLONASS_GNAV_CRC_Q_INDEX.size()); q++) + for (int32_t q = 0; q < static_cast(GLONASS_GNAV_CRC_Q_INDEX.size()); q++) { sum_bits += string_bits[GLONASS_GNAV_CRC_Q_INDEX[q] - 1]; } - for (int q = 0; q < 8; q++) + for (int32_t q = 0; q < 8; q++) { sum_hamming += string_bits[q]; } C_Sigma = (sum_hamming % 2) ^ (sum_bits % 2); - //!< Verification of the data + // Verification of the data // (a-i) All checksums (C1,...,C7 and C_Sigma) are equal to zero if ((C1 + C2 + C3 + C4 + C5 + C6 + C7 + C_Sigma) == 0) { @@ -212,7 +212,7 @@ bool Glonass_Gnav_Navigation_Message::CRC_test(std::bitset bits, const std::vector> parameter) +bool Glonass_Gnav_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) { bool value; @@ -228,18 +228,18 @@ bool Glonass_Gnav_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) +uint64_t Glonass_Gnav_Navigation_Message::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) { - unsigned long int value = 0; - int num_of_slices = parameter.size(); - for (int i = 0; i < num_of_slices; i++) + uint64_t value = 0ULL; + int32_t num_of_slices = parameter.size(); + for (int32_t i = 0; i < num_of_slices; i++) { - for (int j = 0; j < parameter[i].second; j++) + for (int32_t j = 0; j < parameter[i].second; j++) { - value <<= 1; //shift left + value <<= 1; // shift left if (bits[GLONASS_GNAV_STRING_BITS - parameter[i].first - j] == 1) { - value += 1; // insert the bit + value += 1ULL; // insert the bit } } } @@ -247,28 +247,28 @@ unsigned long int Glonass_Gnav_Navigation_Message::read_navigation_unsigned(std: } -signed long int Glonass_Gnav_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector> parameter) +int64_t Glonass_Gnav_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector> parameter) { - signed long int value = 0; - signed long int sign = 0; - int num_of_slices = parameter.size(); + int64_t value = 0LL; + int64_t sign = 0LL; + int32_t num_of_slices = parameter.size(); // read the MSB and perform the sign extension if (bits[GLONASS_GNAV_STRING_BITS - parameter[0].first] == 1) { - sign = -1; + sign = -1LL; } else { - sign = 1; + sign = 1LL; } - for (int i = 0; i < num_of_slices; i++) + for (int32_t i = 0; i < num_of_slices; i++) { - for (int j = 1; j < parameter[i].second; j++) + for (int32_t j = 1; j < parameter[i].second; j++) { - value <<= 1; //shift left + value <<= 1; // shift left if (bits[GLONASS_GNAV_STRING_BITS - parameter[i].first - j] == 1) { - value += 1; // insert the bit + value += 1LL; // insert the bit } } } @@ -276,45 +276,45 @@ signed long int Glonass_Gnav_Navigation_Message::read_navigation_signed(std::bit } -unsigned int Glonass_Gnav_Navigation_Message::get_frame_number(unsigned int satellite_slot_number) +uint32_t Glonass_Gnav_Navigation_Message::get_frame_number(uint32_t satellite_slot_number) { - unsigned int frame_ID = 0; + uint32_t frame_ID = 0U; if (satellite_slot_number >= 1 and satellite_slot_number <= 5) { - frame_ID = 1; + frame_ID = 1U; } else if (satellite_slot_number >= 6 and satellite_slot_number <= 10) { - frame_ID = 2; + frame_ID = 2U; } else if (satellite_slot_number >= 11 and satellite_slot_number <= 15) { - frame_ID = 3; + frame_ID = 3U; } else if (satellite_slot_number >= 16 and satellite_slot_number <= 20) { - frame_ID = 4; + frame_ID = 4U; } else if (satellite_slot_number >= 21 and satellite_slot_number <= 24) { - frame_ID = 5; + frame_ID = 5U; } else { LOG(WARNING) << "GLONASS GNAV: Invalid Satellite Slot Number"; - frame_ID = 0; + frame_ID = 0U; } return frame_ID; } -int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) +int32_t Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) { - int J = 0; - d_string_ID = 0; - d_frame_ID = 0; + int32_t J = 0; + d_string_ID = 0U; + d_frame_ID = 0U; // Unpack bytes to bits std::bitset string_bits(frame_string); @@ -325,11 +325,11 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) return 0; // Decode all 15 string messages - d_string_ID = static_cast(read_navigation_unsigned(string_bits, STRING_ID)); + d_string_ID = static_cast(read_navigation_unsigned(string_bits, STRING_ID)); switch (d_string_ID) { case 1: - //--- It is string 1 ----------------------------------------------- + // --- It is string 1 ----------------------------------------------- gnav_ephemeris.d_P_1 = (static_cast(read_navigation_unsigned(string_bits, P1)) + 1) * 15; gnav_ephemeris.d_t_k = static_cast(read_navigation_unsigned(string_bits, T_K_HR)) * 3600 + static_cast(read_navigation_unsigned(string_bits, T_K_MIN)) * 60 + @@ -343,7 +343,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) break; case 2: - //--- It is string 2 ----------------------------------------------- + // --- It is string 2 ----------------------------------------------- if (flag_ephemeris_str_1 == true) { gnav_ephemeris.d_B_n = static_cast(read_navigation_unsigned(string_bits, B_N)); @@ -391,8 +391,8 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) // Fill in ephemeris deliverables in the code flag_update_slot_number = true; - gnav_ephemeris.i_satellite_slot_number = static_cast(gnav_ephemeris.d_n); - gnav_ephemeris.i_satellite_PRN = static_cast(gnav_ephemeris.d_n); + gnav_ephemeris.i_satellite_slot_number = static_cast(gnav_ephemeris.d_n); + gnav_ephemeris.i_satellite_PRN = static_cast(gnav_ephemeris.d_n); flag_ephemeris_str_4 = true; } @@ -449,7 +449,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) case 6: // --- It is string 6 ---------------------------------------------- - i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); d_frame_ID = get_frame_number(i_alm_satellite_slot_number); // Make sure a valid frame_ID or satellite slot number is returned if (d_frame_ID == 0) @@ -497,7 +497,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) case 8: // --- It is string 8 ---------------------------------------------- - i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); d_frame_ID = get_frame_number(i_alm_satellite_slot_number); // Make sure a valid frame_ID or satellite slot number is returned if (d_frame_ID == 0) @@ -540,7 +540,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) case 10: // --- It is string 10 --------------------------------------------- - i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); d_frame_ID = get_frame_number(i_alm_satellite_slot_number); // Make sure a valid frame_ID or satellite slot number is returned if (d_frame_ID == 0) @@ -583,7 +583,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) case 12: // --- It is string 12 --------------------------------------------- - i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); d_frame_ID = get_frame_number(i_alm_satellite_slot_number); // Make sure a valid frame_ID or satellite slot number is returned if (d_frame_ID == 0) @@ -632,7 +632,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) } else { - i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); + i_alm_satellite_slot_number = static_cast(read_navigation_unsigned(string_bits, n_A)); d_frame_ID = get_frame_number(i_alm_satellite_slot_number); // Make sure a valid frame_ID or satellite slot number is returned if (d_frame_ID == 0) @@ -694,7 +694,7 @@ Glonass_Gnav_Utc_Model Glonass_Gnav_Navigation_Message::get_utc_model() } -Glonass_Gnav_Almanac Glonass_Gnav_Navigation_Message::get_almanac(unsigned int satellite_slot_number) +Glonass_Gnav_Almanac Glonass_Gnav_Navigation_Message::get_almanac(uint32_t satellite_slot_number) { return gnav_almanac[satellite_slot_number - 1]; } @@ -738,14 +738,14 @@ bool Glonass_Gnav_Navigation_Message::have_new_utc_model() // Check if we have } -bool Glonass_Gnav_Navigation_Message::have_new_almanac() //Check if we have a new almanac data set stored in the galileo navigation class +bool Glonass_Gnav_Navigation_Message::have_new_almanac() // Check if we have a new almanac data set stored in the galileo navigation class { bool new_alm = false; if ((flag_almanac_str_6 == true) and (flag_almanac_str_7 == true)) { if (d_previous_Na[i_alm_satellite_slot_number] != gnav_utc_model.d_N_A) { - //All almanac have been received for this satellite + // All almanac have been received for this satellite flag_almanac_str_6 = false; flag_almanac_str_7 = false; new_alm = true; diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.h b/src/core/system_parameters/glonass_gnav_navigation_message.h index 54fe5219b..e13f41511 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.h +++ b/src/core/system_parameters/glonass_gnav_navigation_message.h @@ -40,6 +40,7 @@ #include "glonass_gnav_utc_model.h" #include "GLONASS_L1_L2_CA.h" #include +#include /*! @@ -50,18 +51,18 @@ class Glonass_Gnav_Navigation_Message { private: - unsigned long int read_navigation_unsigned(std::bitset bits, const std::vector> parameter); - signed long int read_navigation_signed(std::bitset bits, const std::vector> parameter); - bool read_navigation_bool(std::bitset bits, const std::vector> parameter); + uint64_t read_navigation_unsigned(std::bitset bits, const std::vector> parameter); + int64_t read_navigation_signed(std::bitset bits, const std::vector> parameter); + bool read_navigation_bool(std::bitset bits, const std::vector> parameter); public: bool flag_CRC_test; - unsigned int d_frame_ID; - unsigned int d_string_ID; + uint32_t d_frame_ID; + uint32_t d_string_ID; bool flag_update_slot_number; - int i_channel_ID; - unsigned int i_satellite_PRN; + int32_t i_channel_ID; + uint32_t i_satellite_PRN; Glonass_Gnav_Ephemeris gnav_ephemeris; //!< Ephemeris information decoded Glonass_Gnav_Utc_Model gnav_utc_model; //!< UTC model information @@ -75,18 +76,18 @@ public: bool flag_ephemeris_str_4; //!< Flag indicating that ephemeris 4/4 (string 4) have been received // Almanac Flags - bool flag_all_almanac; //!< Flag indicating that all almanac have been received - bool flag_almanac_str_6; //!< Flag indicating that almanac of string 6 have been received - bool flag_almanac_str_7; //!< Flag indicating that almanac of string 7 have been received - bool flag_almanac_str_8; //!< Flag indicating that almanac of string 8 have been received - bool flag_almanac_str_9; //!< Flag indicating that almanac of string 9 have been received - bool flag_almanac_str_10; //!< Flag indicating that almanac of string 10 have been received - bool flag_almanac_str_11; //!< Flag indicating that almanac of string 11 have been received - bool flag_almanac_str_12; //!< Flag indicating that almanac of string 12 have been received - bool flag_almanac_str_13; //!< Flag indicating that almanac of string 13 have been received - bool flag_almanac_str_14; //!< Flag indicating that almanac of string 14 have been received - bool flag_almanac_str_15; //!< Flag indicating that almanac of string 15 have been received - unsigned int i_alm_satellite_slot_number; //!< SV Orbit Slot Number + bool flag_all_almanac; //!< Flag indicating that all almanac have been received + bool flag_almanac_str_6; //!< Flag indicating that almanac of string 6 have been received + bool flag_almanac_str_7; //!< Flag indicating that almanac of string 7 have been received + bool flag_almanac_str_8; //!< Flag indicating that almanac of string 8 have been received + bool flag_almanac_str_9; //!< Flag indicating that almanac of string 9 have been received + bool flag_almanac_str_10; //!< Flag indicating that almanac of string 10 have been received + bool flag_almanac_str_11; //!< Flag indicating that almanac of string 11 have been received + bool flag_almanac_str_12; //!< Flag indicating that almanac of string 12 have been received + bool flag_almanac_str_13; //!< Flag indicating that almanac of string 13 have been received + bool flag_almanac_str_14; //!< Flag indicating that almanac of string 14 have been received + bool flag_almanac_str_15; //!< Flag indicating that almanac of string 15 have been received + uint32_t i_alm_satellite_slot_number; //!< SV Orbit Slot Number // UTC and System Clocks Flags bool flag_utc_model_valid; //!< If set, it indicates that the UTC model parameters are filled @@ -114,7 +115,7 @@ public: * \param satellite_slot_number [in] Satellite slot number identifier * \returns Frame number being decoded, 0 if operation was not successful. */ - unsigned int get_frame_number(unsigned int satellite_slot_number); + uint32_t get_frame_number(uint32_t satellite_slot_number); /*! * \brief Reset GLONASS GNAV Navigation Information @@ -136,7 +137,7 @@ public: * \param satellite_slot_number Slot number identifier for the satellite * \returns Returns the Glonass_Gnav_Almanac object for the input slot number */ - Glonass_Gnav_Almanac get_almanac(unsigned int satellite_slot_number); + Glonass_Gnav_Almanac get_almanac(uint32_t satellite_slot_number); /*! * \brief Returns true if a new Glonass_Gnav_Ephemeris object has arrived. @@ -158,7 +159,7 @@ public: * \param frame_string [in] is the string message within the parsed frame * \returns Returns the ID of the decoded string */ - int string_decoder(std::string frame_string); + int32_t string_decoder(std::string frame_string); /*! * Default constructor diff --git a/src/core/system_parameters/glonass_gnav_utc_model.cc b/src/core/system_parameters/glonass_gnav_utc_model.cc index ceea01529..5450d1581 100644 --- a/src/core/system_parameters/glonass_gnav_utc_model.cc +++ b/src/core/system_parameters/glonass_gnav_utc_model.cc @@ -49,7 +49,7 @@ double Glonass_Gnav_Utc_Model::utc_time(double glonass_time_corrected) double t_utc; // GLONASS Time is relative to UTC Moscow, so we simply add its time difference - t_utc = glonass_time_corrected + 3 * 3600 + d_tau_c; + t_utc = glonass_time_corrected + 3.0 * 3600.0 + d_tau_c; return t_utc; } diff --git a/src/core/system_parameters/glonass_gnav_utc_model.h b/src/core/system_parameters/glonass_gnav_utc_model.h index 8d76d90e2..5a082cb7e 100644 --- a/src/core/system_parameters/glonass_gnav_utc_model.h +++ b/src/core/system_parameters/glonass_gnav_utc_model.h @@ -34,8 +34,8 @@ #ifndef GNSS_SDR_GLONASS_GNAV_UTC_MODEL_H_ #define GNSS_SDR_GLONASS_GNAV_UTC_MODEL_H_ -#include #include +#include /*! * \brief This class is a storage for the GLONASS GNAV UTC MODEL data as described in GLONASS ICD (Edition 5.1) @@ -58,7 +58,7 @@ public: /*! * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the almanac data on disk file. */ - void serialize(Archive& archive, const unsigned int version) + void serialize(Archive& archive, const uint32_t version) { using boost::serialization::make_nvp; if (version) diff --git a/src/core/system_parameters/gnss_obs_codes.h b/src/core/system_parameters/gnss_obs_codes.h index a28329760..b1e772466 100644 --- a/src/core/system_parameters/gnss_obs_codes.h +++ b/src/core/system_parameters/gnss_obs_codes.h @@ -33,64 +33,65 @@ #ifndef GNSS_SDR_GNSS_OBS_CODES_H_ #define GNSS_SDR_GNSS_OBS_CODES_H_ +#include -const unsigned int CODE_NONE = 0; //!< obs code: none or unknown -const unsigned int CODE_L1C = 1; //!< obs code: L1C/A,G1C/A,E1C (GPS,GLO,GAL,QZS,SBS) -const unsigned int CODE_L1P = 2; //!< obs code: L1P,G1P (GPS,GLO) -const unsigned int CODE_L1W = 3; //!< obs code: L1 Z-track (GPS) -const unsigned int CODE_L1Y = 4; //!< obs code: L1Y (GPS) -const unsigned int CODE_L1M = 5; //!< obs code: L1M (GPS) -const unsigned int CODE_L1N = 6; //!< obs code: L1codeless (GPS) -const unsigned int CODE_L1S = 7; //!< obs code: L1C(D) (GPS,QZS) -const unsigned int CODE_L1L = 8; //!< obs code: L1C(P) (GPS,QZS) -const unsigned int CODE_L1E = 9; //!< (not used) -const unsigned int CODE_L1A = 10; //!< obs code: E1A (GAL) -const unsigned int CODE_L1B = 11; //!< obs code: E1B (GAL) -const unsigned int CODE_L1X = 12; //!< obs code: E1B+C,L1C(D+P) (GAL,QZS) -const unsigned int CODE_L1Z = 13; //!< obs code: E1A+B+C,L1SAIF (GAL,QZS) -const unsigned int CODE_L2C = 14; //!< obs code: L2C/A,G1C/A (GPS,GLO) -const unsigned int CODE_L2D = 15; //!< obs code: L2 L1C/A-(P2-P1) (GPS) -const unsigned int CODE_L2S = 16; //!< obs code: L2C(M) (GPS,QZS) -const unsigned int CODE_L2L = 17; //!< obs code: L2C(L) (GPS,QZS) -const unsigned int CODE_L2X = 18; //!< obs code: L2C(M+L),B1I+Q (GPS,QZS,BDS) -const unsigned int CODE_L2P = 19; //!< obs code: L2P,G2P (GPS,GLO) -const unsigned int CODE_L2W = 20; //!< obs code: L2 Z-track (GPS) -const unsigned int CODE_L2Y = 21; //!< obs code: L2Y (GPS) -const unsigned int CODE_L2M = 22; //!< obs code: L2M (GPS) -const unsigned int CODE_L2N = 23; //!< obs code: L2codeless (GPS) -const unsigned int CODE_L5I = 24; //!< obs code: L5/E5aI (GPS,GAL,QZS,SBS) -const unsigned int CODE_L5Q = 25; //!< obs code: L5/E5aQ (GPS,GAL,QZS,SBS) -const unsigned int CODE_L5X = 26; //!< obs code: L5/E5aI+Q/L5B+C (GPS,GAL,QZS,IRN,SBS) -const unsigned int CODE_L7I = 27; //!< obs code: E5bI,B2I (GAL,BDS) -const unsigned int CODE_L7Q = 28; //!< obs code: E5bQ,B2Q (GAL,BDS) -const unsigned int CODE_L7X = 29; //!< obs code: E5bI+Q,B2I+Q (GAL,BDS) -const unsigned int CODE_L6A = 30; //!< obs code: E6A (GAL) -const unsigned int CODE_L6B = 31; //!< obs code: E6B (GAL) -const unsigned int CODE_L6C = 32; //!< obs code: E6C (GAL) -const unsigned int CODE_L6X = 33; //!< obs code: E6B+C,LEXS+L,B3I+Q (GAL,QZS,BDS) -const unsigned int CODE_L6Z = 34; //!< obs code: E6A+B+C (GAL) -const unsigned int CODE_L6S = 35; //!< obs code: LEXS (QZS) -const unsigned int CODE_L6L = 36; //!< obs code: LEXL (QZS) -const unsigned int CODE_L8I = 37; //!< obs code: E5(a+b)I (GAL) -const unsigned int CODE_L8Q = 38; //!< obs code: E5(a+b)Q (GAL) -const unsigned int CODE_L8X = 39; //!< obs code: E5(a+b)I+Q (GAL) -const unsigned int CODE_L2I = 40; //!< obs code: B1I (BDS) -const unsigned int CODE_L2Q = 41; //!< obs code: B1Q (BDS) -const unsigned int CODE_L6I = 42; //!< obs code: B3I (BDS) -const unsigned int CODE_L6Q = 43; //!< obs code: B3Q (BDS) -const unsigned int CODE_L3I = 44; //!< obs code: G3I (GLO) -const unsigned int CODE_L3Q = 45; //!< obs code: G3Q (GLO) -const unsigned int CODE_L3X = 46; //!< obs code: G3I+Q (GLO) -const unsigned int CODE_L1I = 47; //!< obs code: B1I (BDS) -const unsigned int CODE_L1Q = 48; //!< obs code: B1Q (BDS) -const unsigned int CODE_L5A = 49; //!< obs code: L5A SPS (IRN) -const unsigned int CODE_L5B = 50; //!< obs code: L5B RS(D) (IRN) -const unsigned int CODE_L5C = 51; //!< obs code: L5C RS(P) (IRN) -const unsigned int CODE_L9A = 52; //!< obs code: SA SPS (IRN) -const unsigned int CODE_L9B = 53; //!< obs code: SB RS(D) (IRN) -const unsigned int CODE_L9C = 54; //!< obs code: SC RS(P) (IRN) -const unsigned int CODE_L9X = 55; //!< obs code: SB+C (IRN) -const int MAXCODE = 55; //!< max number of obs code +const uint32_t CODE_NONE = 0; //!< obs code: none or unknown +const uint32_t CODE_L1C = 1; //!< obs code: L1C/A,G1C/A,E1C (GPS,GLO,GAL,QZS,SBS) +const uint32_t CODE_L1P = 2; //!< obs code: L1P,G1P (GPS,GLO) +const uint32_t CODE_L1W = 3; //!< obs code: L1 Z-track (GPS) +const uint32_t CODE_L1Y = 4; //!< obs code: L1Y (GPS) +const uint32_t CODE_L1M = 5; //!< obs code: L1M (GPS) +const uint32_t CODE_L1N = 6; //!< obs code: L1codeless (GPS) +const uint32_t CODE_L1S = 7; //!< obs code: L1C(D) (GPS,QZS) +const uint32_t CODE_L1L = 8; //!< obs code: L1C(P) (GPS,QZS) +const uint32_t CODE_L1E = 9; //!< (not used) +const uint32_t CODE_L1A = 10; //!< obs code: E1A (GAL) +const uint32_t CODE_L1B = 11; //!< obs code: E1B (GAL) +const uint32_t CODE_L1X = 12; //!< obs code: E1B+C,L1C(D+P) (GAL,QZS) +const uint32_t CODE_L1Z = 13; //!< obs code: E1A+B+C,L1SAIF (GAL,QZS) +const uint32_t CODE_L2C = 14; //!< obs code: L2C/A,G1C/A (GPS,GLO) +const uint32_t CODE_L2D = 15; //!< obs code: L2 L1C/A-(P2-P1) (GPS) +const uint32_t CODE_L2S = 16; //!< obs code: L2C(M) (GPS,QZS) +const uint32_t CODE_L2L = 17; //!< obs code: L2C(L) (GPS,QZS) +const uint32_t CODE_L2X = 18; //!< obs code: L2C(M+L),B1I+Q (GPS,QZS,BDS) +const uint32_t CODE_L2P = 19; //!< obs code: L2P,G2P (GPS,GLO) +const uint32_t CODE_L2W = 20; //!< obs code: L2 Z-track (GPS) +const uint32_t CODE_L2Y = 21; //!< obs code: L2Y (GPS) +const uint32_t CODE_L2M = 22; //!< obs code: L2M (GPS) +const uint32_t CODE_L2N = 23; //!< obs code: L2codeless (GPS) +const uint32_t CODE_L5I = 24; //!< obs code: L5/E5aI (GPS,GAL,QZS,SBS) +const uint32_t CODE_L5Q = 25; //!< obs code: L5/E5aQ (GPS,GAL,QZS,SBS) +const uint32_t CODE_L5X = 26; //!< obs code: L5/E5aI+Q/L5B+C (GPS,GAL,QZS,IRN,SBS) +const uint32_t CODE_L7I = 27; //!< obs code: E5bI,B2I (GAL,BDS) +const uint32_t CODE_L7Q = 28; //!< obs code: E5bQ,B2Q (GAL,BDS) +const uint32_t CODE_L7X = 29; //!< obs code: E5bI+Q,B2I+Q (GAL,BDS) +const uint32_t CODE_L6A = 30; //!< obs code: E6A (GAL) +const uint32_t CODE_L6B = 31; //!< obs code: E6B (GAL) +const uint32_t CODE_L6C = 32; //!< obs code: E6C (GAL) +const uint32_t CODE_L6X = 33; //!< obs code: E6B+C,LEXS+L,B3I+Q (GAL,QZS,BDS) +const uint32_t CODE_L6Z = 34; //!< obs code: E6A+B+C (GAL) +const uint32_t CODE_L6S = 35; //!< obs code: LEXS (QZS) +const uint32_t CODE_L6L = 36; //!< obs code: LEXL (QZS) +const uint32_t CODE_L8I = 37; //!< obs code: E5(a+b)I (GAL) +const uint32_t CODE_L8Q = 38; //!< obs code: E5(a+b)Q (GAL) +const uint32_t CODE_L8X = 39; //!< obs code: E5(a+b)I+Q (GAL) +const uint32_t CODE_L2I = 40; //!< obs code: B1I (BDS) +const uint32_t CODE_L2Q = 41; //!< obs code: B1Q (BDS) +const uint32_t CODE_L6I = 42; //!< obs code: B3I (BDS) +const uint32_t CODE_L6Q = 43; //!< obs code: B3Q (BDS) +const uint32_t CODE_L3I = 44; //!< obs code: G3I (GLO) +const uint32_t CODE_L3Q = 45; //!< obs code: G3Q (GLO) +const uint32_t CODE_L3X = 46; //!< obs code: G3I+Q (GLO) +const uint32_t CODE_L1I = 47; //!< obs code: B1I (BDS) +const uint32_t CODE_L1Q = 48; //!< obs code: B1Q (BDS) +const uint32_t CODE_L5A = 49; //!< obs code: L5A SPS (IRN) +const uint32_t CODE_L5B = 50; //!< obs code: L5B RS(D) (IRN) +const uint32_t CODE_L5C = 51; //!< obs code: L5C RS(P) (IRN) +const uint32_t CODE_L9A = 52; //!< obs code: SA SPS (IRN) +const uint32_t CODE_L9B = 53; //!< obs code: SB RS(D) (IRN) +const uint32_t CODE_L9C = 54; //!< obs code: SC RS(P) (IRN) +const uint32_t CODE_L9X = 55; //!< obs code: SB+C (IRN) +const int32_t MAXCODE = 55; //!< max number of obs code #endif diff --git a/src/core/system_parameters/gnss_satellite.cc b/src/core/system_parameters/gnss_satellite.cc index bb9655bc1..dd8c8ffc8 100644 --- a/src/core/system_parameters/gnss_satellite.cc +++ b/src/core/system_parameters/gnss_satellite.cc @@ -38,7 +38,7 @@ Gnss_Satellite::Gnss_Satellite() } -Gnss_Satellite::Gnss_Satellite(const std::string& system_, unsigned int PRN_) +Gnss_Satellite::Gnss_Satellite(const std::string& system_, uint32_t PRN_) { Gnss_Satellite::reset(); Gnss_Satellite::set_system(system_); @@ -98,9 +98,9 @@ Gnss_Satellite& Gnss_Satellite::operator=(const Gnss_Satellite &rhs) { if (this != &rhs) { // Deallocate, allocate new space, copy values... const std::string system_ = rhs.get_system(); - const unsigned int PRN_ = rhs.get_PRN(); + const uint32_t PRN_ = rhs.get_PRN(); const std::string block_ = rhs.get_block(); - // const signed int rf_link_ = 0; + // const int32_t rf_link_ = 0; this->set_system(system_); this->set_PRN(PRN_); this->set_block(system_, PRN_); @@ -127,7 +127,7 @@ void Gnss_Satellite::set_system(const std::string& system_) } -void Gnss_Satellite::update_PRN(unsigned int PRN_) +void Gnss_Satellite::update_PRN(uint32_t PRN_) { if (system.compare("Glonass") != 0) { @@ -150,7 +150,7 @@ void Gnss_Satellite::update_PRN(unsigned int PRN_) } -void Gnss_Satellite::set_PRN(unsigned int PRN_) +void Gnss_Satellite::set_PRN(uint32_t PRN_) { // Set satellite's PRN if (system.compare("") == 0) @@ -184,26 +184,30 @@ void Gnss_Satellite::set_PRN(unsigned int PRN_) } else if (system.compare("SBAS") == 0) { - if (PRN_ == 122) + if (PRN_ == 120) { PRN = PRN_; - } // WAAS Inmarsat 3F4 (AOR-W) - else if (PRN_ == 134) + } // EGNOS Test Platform.Inmarsat 3-F2 (Atlantic Ocean Region-East) + else if (PRN_ == 123) { PRN = PRN_; - } // WAAS Inmarsat 3F3 (POR) - else if (PRN_ == 120) + } // EGNOS Operational Platform. Astra 5B + else if (PRN_ == 131) { PRN = PRN_; - } // EGNOS AOR-E Broadcast satellite http://www.egnos-pro.esa.int/index.html - else if (PRN_ == 124) + } // WAAS Eutelsat 117 West B + else if (PRN_ == 135) { PRN = PRN_; - } // EGNOS ESA ARTEMIS used for EGNOS Operations - else if (PRN_ == 126) + } // WAAS Galaxy 15 + else if (PRN_ == 136) { PRN = PRN_; - } // EGNOS IOR-W currently used by Industry to perform various tests on the system. + } // EGNOS Operational Platform. SES-5 (a.k.a. Sirius 5 or Astra 4B) + else if (PRN_ == 138) + { + PRN = PRN_; + } // WAAS Anik F1R else { DLOG(INFO) << "This PRN is not defined"; @@ -230,19 +234,19 @@ void Gnss_Satellite::set_PRN(unsigned int PRN_) } -signed int Gnss_Satellite::get_rf_link() const +int32_t Gnss_Satellite::get_rf_link() const { // Get satellite's rf link. Identifies the GLONASS Frequency Channel - signed int rf_link_; + int32_t rf_link_; rf_link_ = rf_link; return rf_link_; } -unsigned int Gnss_Satellite::get_PRN() const +uint32_t Gnss_Satellite::get_PRN() const { // Get satellite's PRN - unsigned int PRN_; + uint32_t PRN_; PRN_ = PRN; return PRN_; } @@ -273,7 +277,7 @@ std::string Gnss_Satellite::get_block() const } -std::string Gnss_Satellite::what_block(const std::string& system_, unsigned int PRN_) +std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_) { std::string block_ = "Unknown"; if (system_.compare("GPS") == 0) @@ -492,20 +496,23 @@ std::string Gnss_Satellite::what_block(const std::string& system_, unsigned int { switch (PRN_) { - case 122: - block_ = std::string("WAAS"); // WAAS Inmarsat 3F4 (AOR-W) - break; - case 134: - block_ = std::string("WAAS"); // WAAS Inmarsat 3F3 (POR) - break; case 120: - block_ = std::string("EGNOS"); // EGNOS AOR-E Broadcast satellite http://www.egnos-pro.esa.int/index.html + block_ = std::string("EGNOS Test Platform"); // Inmarsat 3-F2 (Atlantic Ocean Region-East) break; - case 124: - block_ = std::string("EGNOS"); // EGNOS ESA ARTEMIS used for EGNOS Operations + case 123: + block_ = std::string("EGNOS"); // EGNOS Operational Platform. Astra 5B break; - case 126: - block_ = std::string("EGNOS"); // EGNOS IOR-W currently used by Industry to perform various tests on the system. + case 131: + block_ = std::string("WAAS"); // WAAS Eutelsat 117 West B + break; + case 135: + block_ = std::string("WAAS"); // WAAS Galaxy 15 + break; + case 136: + block_ = std::string("EGNOS"); // EGNOS Operational Platform. SES-5 (a.k.a. Sirius 5 or Astra 4B) + break; + case 138: + block_ = std::string("WAAS"); // WAAS Anik F1R break; default: block_ = std::string("Unknown"); @@ -546,9 +553,15 @@ std::string Gnss_Satellite::what_block(const std::string& system_, unsigned int case 12: block_ = std::string("IOV-FM2"); // Galileo In-Orbit Validation (IOV) satellite FM2 (Flight Model 2) also known as GSAT0102, from French Guiana at 10:30 GMT on October 21, 2011. break; + case 13: + block_ = std::string("FOC-FM20"); // Galileo Full Operational Capability (FOC) satellite FM20 / GSAT0220, launched on Jul. 25, 2018. UNDER COMMISSIONING. + break; case 14: block_ = std::string("FOC-FM2*"); // Galileo Full Operational Capability (FOC) satellite FM2 / GSAT0202, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in March, 2015. UNDER TESTING. break; + case 15: + block_ = std::string("FOC-FM21"); // Galileo Full Operational Capability (FOC) satellite FM21 / GSAT0221, launched on Jul. 25, 2018. UNDER COMMISSIONING. + break; case 18: block_ = std::string("FOC-FM1*"); // Galileo Full Operational Capability (FOC) satellite FM1 / GSAT0201, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in December, 2014. UNDER TESTING. break; @@ -582,6 +595,12 @@ std::string Gnss_Satellite::what_block(const std::string& system_, unsigned int case 31: block_ = std::string("FOC-FM18"); // Galileo Full Operational Capability (FOC) satellite FM18 / GSAT0218, launched on Dec. 12, 2017. UNDER COMMISSIONING. break; + case 33: + block_ = std::string("FOC-FM22"); // Galileo Full Operational Capability (FOC) satellite FM22 / GSAT0222, launched on Jul. 25, 2018. UNDER COMMISSIONING. + break; + case 36: + block_ = std::string("FOC-FM19"); // Galileo Full Operational Capability (FOC) satellite FM19 / GSAT0219, launched on Jul. 25, 2018. UNDER COMMISSIONING. + break; default: block_ = std::string("Unknown(Simulated)"); } @@ -590,7 +609,7 @@ std::string Gnss_Satellite::what_block(const std::string& system_, unsigned int } -void Gnss_Satellite::set_block(const std::string& system_, unsigned int PRN_) +void Gnss_Satellite::set_block(const std::string& system_, uint32_t PRN_) { block = what_block(system_, PRN_); } diff --git a/src/core/system_parameters/gnss_satellite.h b/src/core/system_parameters/gnss_satellite.h index 65e261ab6..58a3b1165 100644 --- a/src/core/system_parameters/gnss_satellite.h +++ b/src/core/system_parameters/gnss_satellite.h @@ -32,9 +32,10 @@ #ifndef GNSS_SDR_GNSS_SATELLITE_H_ #define GNSS_SDR_GNSS_SATELLITE_H_ +#include +#include #include #include -#include /*! @@ -47,27 +48,27 @@ class Gnss_Satellite { public: Gnss_Satellite(); //!< Default Constructor. - Gnss_Satellite(const std::string& system_, unsigned int PRN_); //!< Concrete GNSS satellite Constructor. + Gnss_Satellite(const std::string& system_, uint32_t PRN_); //!< Concrete GNSS satellite Constructor. ~Gnss_Satellite(); //!< Default Destructor. - void update_PRN(unsigned int PRN); //!< Updates the PRN Number when information is decoded, only applies to GLONASS GNAV messages - unsigned int get_PRN() const; //!< Gets satellite's PRN - signed int get_rf_link() const; //!< Gets the satellite's rf link + void update_PRN(uint32_t PRN); //!< Updates the PRN Number when information is decoded, only applies to GLONASS GNAV messages + uint32_t get_PRN() const; //!< Gets satellite's PRN + int32_t get_rf_link() const; //!< Gets the satellite's rf link std::string get_system() const; //!< Gets the satellite system {"GPS", "GLONASS", "SBAS", "Galileo", "Beidou"} std::string get_system_short() const; //!< Gets the satellite system {"G", "R", "SBAS", "E", "C"} std::string get_block() const; //!< Gets the satellite block. If GPS, returns {"IIA", "IIR", "IIR-M", "IIF"} - std::string what_block(const std::string& system_, unsigned int PRN_); //!< Gets the block of a given satellite + std::string what_block(const std::string& system_, uint32_t PRN_); //!< Gets the block of a given satellite friend bool operator==(const Gnss_Satellite&, const Gnss_Satellite&); //!< operator== for comparison friend std::ostream& operator<<(std::ostream&, const Gnss_Satellite&); //!< operator<< for pretty printing //Gnss_Satellite& operator=(const Gnss_Satellite &); private: - unsigned int PRN; + uint32_t PRN; std::string system; std::map satelliteSystem; std::string block; - signed int rf_link; + int32_t rf_link; void set_system(const std::string& system); // Sets the satellite system {"GPS", "GLONASS", "SBAS", "Galileo", "Beidou"}. - void set_PRN(unsigned int PRN); // Sets satellite's PRN - void set_block(const std::string& system_, unsigned int PRN_); + void set_PRN(uint32_t PRN); // Sets satellite's PRN + void set_block(const std::string& system_, uint32_t PRN_); std::set system_set; // = {"GPS", "GLONASS", "SBAS", "Galileo", "Compass"}; void reset(); }; diff --git a/src/core/system_parameters/gnss_signal.cc b/src/core/system_parameters/gnss_signal.cc index 882b5d231..cc2e8effd 100644 --- a/src/core/system_parameters/gnss_signal.cc +++ b/src/core/system_parameters/gnss_signal.cc @@ -36,11 +36,13 @@ Gnss_Signal::Gnss_Signal() this->signal = ""; } + Gnss_Signal::Gnss_Signal(const std::string& signal_) { this->signal = signal_; } + Gnss_Signal::Gnss_Signal(const Gnss_Satellite& satellite_, const std::string& signal_) { this->satellite = satellite_; diff --git a/src/core/system_parameters/gnss_signal.h b/src/core/system_parameters/gnss_signal.h index f857042e8..2b739c633 100644 --- a/src/core/system_parameters/gnss_signal.h +++ b/src/core/system_parameters/gnss_signal.h @@ -52,7 +52,7 @@ public: Gnss_Signal(const std::string& signal_); Gnss_Signal(const Gnss_Satellite& satellite_, const std::string& signal_); ~Gnss_Signal(); - std::string get_signal_str() const; //!< Get the satellite signal {"1C" for GPS L1 C/A, "2S" for GPS L2C (M), "L5" for GPS L5, "1G" for GLONASS L1 C/A, "1B" for Galileo E1B, "5X" for Galileo E5a. + std::string get_signal_str() const; //!< Get the satellite signal {"1C" for GPS L1 C/A, "2S" for GPS L2C (M), "L5" for GPS L5, "1G" for GLONASS L1 C/A, "1B" for Galileo E1B, "5X" for Galileo E5a. Gnss_Satellite get_satellite() const; //!< Get the Gnss_Satellite associated to the signal friend bool operator==(const Gnss_Signal&, const Gnss_Signal&); //!< operator== for comparison friend std::ostream& operator<<(std::ostream&, const Gnss_Signal&); //!< operator<< for pretty printing diff --git a/src/core/system_parameters/gnss_synchro.h b/src/core/system_parameters/gnss_synchro.h index c9cd0ee0c..9e0580544 100644 --- a/src/core/system_parameters/gnss_synchro.h +++ b/src/core/system_parameters/gnss_synchro.h @@ -29,11 +29,13 @@ * * ------------------------------------------------------------------------- */ + #ifndef GNSS_SDR_GNSS_SYNCHRO_H_ #define GNSS_SDR_GNSS_SYNCHRO_H_ +#include #include "gnss_signal.h" - +#include /*! * \brief This is the class that contains the information that is shared @@ -43,31 +45,33 @@ class Gnss_Synchro { public: // Satellite and signal info - char System; //!< Set by Channel::set_signal(Gnss_Signal gnss_signal) - char Signal[3]; //!< Set by Channel::set_signal(Gnss_Signal gnss_signal) - unsigned int PRN; //!< Set by Channel::set_signal(Gnss_Signal gnss_signal) - int Channel_ID; //!< Set by Channel constructor + char System; //!< Set by Channel::set_signal(Gnss_Signal gnss_signal) + char Signal[3]; //!< Set by Channel::set_signal(Gnss_Signal gnss_signal) + uint32_t PRN; //!< Set by Channel::set_signal(Gnss_Signal gnss_signal) + int32_t Channel_ID; //!< Set by Channel constructor + // Acquisition - double Acq_delay_samples; //!< Set by Acquisition processing block - double Acq_doppler_hz; //!< Set by Acquisition processing block - unsigned long int Acq_samplestamp_samples; //!< Set by Acquisition processing block - bool Flag_valid_acquisition; //!< Set by Acquisition processing block - //Tracking - long int fs; //!< Set by Tracking processing block - double Prompt_I; //!< Set by Tracking processing block - double Prompt_Q; //!< Set by Tracking processing block - double CN0_dB_hz; //!< Set by Tracking processing block - double Carrier_Doppler_hz; //!< Set by Tracking processing block - double Carrier_phase_rads; //!< Set by Tracking processing block - double Code_phase_samples; //!< Set by Tracking processing block - unsigned long int Tracking_sample_counter; //!< Set by Tracking processing block + double Acq_delay_samples; //!< Set by Acquisition processing block + double Acq_doppler_hz; //!< Set by Acquisition processing block + uint64_t Acq_samplestamp_samples; //!< Set by Acquisition processing block + uint32_t Acq_doppler_step; //!< Set by Acquisition processing block + bool Flag_valid_acquisition; //!< Set by Acquisition processing block - bool Flag_valid_symbol_output; //!< Set by Tracking processing block - int correlation_length_ms; //!< Set by Tracking processing block + // Tracking + int64_t fs; //!< Set by Tracking processing block + double Prompt_I; //!< Set by Tracking processing block + double Prompt_Q; //!< Set by Tracking processing block + double CN0_dB_hz; //!< Set by Tracking processing block + double Carrier_Doppler_hz; //!< Set by Tracking processing block + double Carrier_phase_rads; //!< Set by Tracking processing block + double Code_phase_samples; //!< Set by Tracking processing block + uint64_t Tracking_sample_counter; //!< Set by Tracking processing block + bool Flag_valid_symbol_output; //!< Set by Tracking processing block + int32_t correlation_length_ms; //!< Set by Tracking processing block - //Telemetry Decoder - bool Flag_valid_word; //!< Set by Telemetry Decoder processing block - unsigned int TOW_at_current_symbol_ms; //!< Set by Telemetry Decoder processing block + // Telemetry Decoder + bool Flag_valid_word; //!< Set by Telemetry Decoder processing block + uint32_t TOW_at_current_symbol_ms; //!< Set by Telemetry Decoder processing block // Observables double Pseudorange_m; //!< Set by Observables processing block @@ -75,45 +79,47 @@ public: bool Flag_valid_pseudorange; //!< Set by Observables processing block double interp_TOW_ms; //!< Set by Observables processing block - /*! - * \brief This member function is necessary to serialize and restore + * \brief This member function serializes and restores * Gnss_Synchro objects from a byte stream. */ template + void serialize(Archive& ar, const unsigned int version) { if (version) { }; // Satellite and signal info - ar& System; - ar& Signal; - ar& PRN; - ar& Channel_ID; - ar& Acq_delay_samples; - ar& Acq_doppler_hz; - ar& Acq_samplestamp_samples; - ar& Flag_valid_acquisition; - //Tracking - ar& fs; - ar& Prompt_I; - ar& Prompt_Q; - ar& CN0_dB_hz; - ar& Carrier_Doppler_hz; - ar& Carrier_phase_rads; - ar& Code_phase_samples; - ar& Tracking_sample_counter; - ar& Flag_valid_symbol_output; - ar& correlation_length_ms; - //Telemetry Decoder - ar& Flag_valid_word; - ar& TOW_at_current_symbol_ms; + ar& BOOST_SERIALIZATION_NVP(System); + ar& BOOST_SERIALIZATION_NVP(Signal); + ar& BOOST_SERIALIZATION_NVP(PRN); + ar& BOOST_SERIALIZATION_NVP(Channel_ID); + // Acquisition + ar& BOOST_SERIALIZATION_NVP(Acq_delay_samples); + ar& BOOST_SERIALIZATION_NVP(Acq_doppler_hz); + ar& BOOST_SERIALIZATION_NVP(Acq_samplestamp_samples); + ar& BOOST_SERIALIZATION_NVP(Acq_doppler_step); + ar& BOOST_SERIALIZATION_NVP(Flag_valid_acquisition); + // Tracking + ar& BOOST_SERIALIZATION_NVP(fs); + ar& BOOST_SERIALIZATION_NVP(Prompt_I); + ar& BOOST_SERIALIZATION_NVP(Prompt_Q); + ar& BOOST_SERIALIZATION_NVP(CN0_dB_hz); + ar& BOOST_SERIALIZATION_NVP(Carrier_Doppler_hz); + ar& BOOST_SERIALIZATION_NVP(Carrier_phase_rads); + ar& BOOST_SERIALIZATION_NVP(Code_phase_samples); + ar& BOOST_SERIALIZATION_NVP(Tracking_sample_counter); + ar& BOOST_SERIALIZATION_NVP(Flag_valid_symbol_output); + ar& BOOST_SERIALIZATION_NVP(correlation_length_ms); + // Telemetry Decoder + ar& BOOST_SERIALIZATION_NVP(Flag_valid_word); + ar& BOOST_SERIALIZATION_NVP(TOW_at_current_symbol_ms); // Observables - ar& Pseudorange_m; - ar& RX_time; - ar& Flag_valid_pseudorange; - ar& interp_TOW_ms; + ar& BOOST_SERIALIZATION_NVP(Pseudorange_m); + ar& BOOST_SERIALIZATION_NVP(RX_time); + ar& BOOST_SERIALIZATION_NVP(Flag_valid_pseudorange); + ar& BOOST_SERIALIZATION_NVP(interp_TOW_ms); } }; diff --git a/src/core/system_parameters/gps_acq_assist.cc b/src/core/system_parameters/gps_acq_assist.cc index 5b4510560..128772316 100644 --- a/src/core/system_parameters/gps_acq_assist.cc +++ b/src/core/system_parameters/gps_acq_assist.cc @@ -34,7 +34,7 @@ Gps_Acq_Assist::Gps_Acq_Assist() { - i_satellite_PRN = 0; + i_satellite_PRN = 0U; d_TOW = 0.0; d_Doppler0 = 0.0; d_Doppler1 = 0.0; diff --git a/src/core/system_parameters/gps_acq_assist.h b/src/core/system_parameters/gps_acq_assist.h index c84d0b730..5083aca44 100644 --- a/src/core/system_parameters/gps_acq_assist.h +++ b/src/core/system_parameters/gps_acq_assist.h @@ -32,6 +32,7 @@ #ifndef GNSS_SDR_GPS_ACQ_ASSIST_H_ #define GNSS_SDR_GPS_ACQ_ASSIST_H_ +#include /*! * \brief This class is a storage for the GPS GSM RRLL acquisition assistance data as described in @@ -44,17 +45,17 @@ class Gps_Acq_Assist { public: - unsigned int i_satellite_PRN; //!< SV PRN NUMBER - double d_TOW; //!< Time Of Week assigned to the acquisition data - double d_Doppler0; //!< Doppler (0 order term) [Hz] - double d_Doppler1; //!< Doppler (1 order term) [Hz] - double dopplerUncertainty; //!< Doppler Uncertainty [Hz] - double Code_Phase; //!< Code phase [chips] - double Code_Phase_int; //!< Integer Code Phase [1 C/A code period] - double GPS_Bit_Number; //!< GPS Bit Number - double Code_Phase_window; //!< Code Phase search window [chips] - double Azimuth; //!< Satellite Azimuth [deg] - double Elevation; //!< Satellite Elevation [deg] + uint32_t i_satellite_PRN; //!< SV PRN NUMBER + double d_TOW; //!< Time Of Week assigned to the acquisition data + double d_Doppler0; //!< Doppler (0 order term) [Hz] + double d_Doppler1; //!< Doppler (1 order term) [Hz] + double dopplerUncertainty; //!< Doppler Uncertainty [Hz] + double Code_Phase; //!< Code phase [chips] + double Code_Phase_int; //!< Integer Code Phase [1 C/A code period] + double GPS_Bit_Number; //!< GPS Bit Number + double Code_Phase_window; //!< Code Phase search window [chips] + double Azimuth; //!< Satellite Azimuth [deg] + double Elevation; //!< Satellite Elevation [deg] /*! * Default constructor diff --git a/src/core/system_parameters/gps_almanac.cc b/src/core/system_parameters/gps_almanac.cc index 5c7747d0a..987032668 100644 --- a/src/core/system_parameters/gps_almanac.cc +++ b/src/core/system_parameters/gps_almanac.cc @@ -34,9 +34,10 @@ Gps_Almanac::Gps_Almanac() { - i_satellite_PRN = 0; + i_satellite_PRN = 0U; d_Delta_i = 0.0; - d_Toa = 0.0; + i_Toa = 0.0; + i_WNa = 0; d_M_0 = 0.0; d_e_eccentricity = 0.0; d_sqrt_A = 0.0; @@ -44,6 +45,7 @@ Gps_Almanac::Gps_Almanac() d_OMEGA = 0.0; d_OMEGA_DOT = 0.0; i_SV_health = 0; + i_AS_status = 0; d_A_f0 = 0.0; d_A_f1 = 0.0; } diff --git a/src/core/system_parameters/gps_almanac.h b/src/core/system_parameters/gps_almanac.h index d3e31db80..71175a8bd 100644 --- a/src/core/system_parameters/gps_almanac.h +++ b/src/core/system_parameters/gps_almanac.h @@ -32,6 +32,8 @@ #ifndef GNSS_SDR_GPS_ALMANAC_H_ #define GNSS_SDR_GPS_ALMANAC_H_ +#include +#include /*! * \brief This class is a storage for the GPS SV ALMANAC data as described in IS-GPS-200E @@ -41,23 +43,48 @@ class Gps_Almanac { public: - unsigned int i_satellite_PRN; //!< SV PRN NUMBER - double d_Delta_i; - double d_Toa; //!< Almanac data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] - double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles] - double d_e_eccentricity; //!< Eccentricity [dimensionless] - double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)] - double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] - double d_OMEGA; //!< Argument of Perigee [semi-cicles] - double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s] - int i_SV_health; // SV Health - double d_A_f0; //!< Coefficient 0 of code phase offset model [s] - double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s] + uint32_t i_satellite_PRN; //!< SV PRN NUMBER + double d_Delta_i; //!< Inclination Angle at Reference Time (relative to i_0 = 0.30 semi-circles) + int32_t i_Toa; //!< Almanac data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] + int32_t i_WNa; //!< Almanac week number + double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles] + double d_e_eccentricity; //!< Eccentricity [dimensionless] + double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)] + double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] + double d_OMEGA; //!< Argument of Perigee [semi-cicles] + double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s] + int32_t i_SV_health; //!< SV Health + int32_t i_AS_status; //!< Anti-Spoofing Flags and SV Configuration + double d_A_f0; //!< Coefficient 0 of code phase offset model [s] + double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s] /*! * Default constructor */ Gps_Almanac(); + + template + + void serialize(Archive& ar, const unsigned int version) + { + if (version) + { + }; + ar& BOOST_SERIALIZATION_NVP(i_satellite_PRN); + ar& BOOST_SERIALIZATION_NVP(d_Delta_i); + ar& BOOST_SERIALIZATION_NVP(i_Toa); + ar& BOOST_SERIALIZATION_NVP(i_WNa); + ar& BOOST_SERIALIZATION_NVP(d_M_0); + ar& BOOST_SERIALIZATION_NVP(d_e_eccentricity); + ar& BOOST_SERIALIZATION_NVP(d_sqrt_A); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA0); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA); + ar& BOOST_SERIALIZATION_NVP(d_OMEGA_DOT); + ar& BOOST_SERIALIZATION_NVP(i_SV_health); + ar& BOOST_SERIALIZATION_NVP(i_AS_status); + ar& BOOST_SERIALIZATION_NVP(d_A_f0); + ar& BOOST_SERIALIZATION_NVP(d_A_f1); + } }; #endif diff --git a/src/core/system_parameters/gps_cnav_ephemeris.cc b/src/core/system_parameters/gps_cnav_ephemeris.cc index 574196813..41b3dd655 100644 --- a/src/core/system_parameters/gps_cnav_ephemeris.cc +++ b/src/core/system_parameters/gps_cnav_ephemeris.cc @@ -35,34 +35,34 @@ Gps_CNAV_Ephemeris::Gps_CNAV_Ephemeris() { - i_satellite_PRN = 0; + i_satellite_PRN = 0U; - d_Toe1 = -1; - d_Toe2 = -1; + d_Toe1 = -1.0; + d_Toe2 = -1.0; - d_TOW = 0; - d_Crs = 0; - d_M_0 = 0; - d_Cuc = 0; - d_e_eccentricity = 0; - d_Cus = 0; + d_TOW = 0.0; + d_Crs = 0.0; + d_M_0 = 0.0; + d_Cuc = 0.0; + d_e_eccentricity = 0.0; + d_Cus = 0.0; - d_Toc = 0; - d_Cic = 0; - d_OMEGA0 = 0; - d_Cis = 0; - d_i_0 = 0; - d_Crc = 0; - d_OMEGA = 0; - d_IDOT = 0; + d_Toc = 0.0; + d_Cic = 0.0; + d_OMEGA0 = 0.0; + d_Cis = 0.0; + d_i_0 = 0.0; + d_Crc = 0.0; + d_OMEGA = 0.0; + d_IDOT = 0.0; i_GPS_week = 0; - d_TGD = 0; // Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s] + d_TGD = 0.0; // Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s] - d_A_f0 = 0; // Coefficient 0 of code phase offset model [s] - d_A_f1 = 0; // Coefficient 1 of code phase offset model [s/s] - d_A_f2 = 0; // Coefficient 2 of code phase offset model [s/s^2] + d_A_f0 = 0.0; // Coefficient 0 of code phase offset model [s] + d_A_f1 = 0.0; // Coefficient 1 of code phase offset model [s/s] + d_A_f2 = 0.0; // Coefficient 2 of code phase offset model [s/s^2] b_integrity_status_flag = false; b_alert_flag = false; // If true, indicates that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk. @@ -95,6 +95,7 @@ Gps_CNAV_Ephemeris::Gps_CNAV_Ephemeris() b_l2c_phasing_flag = false; } + double Gps_CNAV_Ephemeris::check_t(double time) { double corrTime; @@ -162,7 +163,7 @@ double Gps_CNAV_Ephemeris::sv_clock_relativistic_term(double transmitTime) E = M; // --- Iteratively compute eccentric anomaly ---------------------------- - for (int ii = 1; ii < 20; ii++) + for (int32_t ii = 1; ii < 20; ii++) { E_old = E; E = M + d_e_eccentricity * sin(E); @@ -232,7 +233,7 @@ double Gps_CNAV_Ephemeris::satellitePosition(double transmitTime) E = M; // --- Iteratively compute eccentric anomaly ---------------------------- - for (int ii = 1; ii < 20; ii++) + for (int32_t ii = 1; ii < 20; ii++) { E_old = E; E = M + d_e_eccentricity * sin(E); diff --git a/src/core/system_parameters/gps_cnav_ephemeris.h b/src/core/system_parameters/gps_cnav_ephemeris.h index 97c90a272..158206994 100644 --- a/src/core/system_parameters/gps_cnav_ephemeris.h +++ b/src/core/system_parameters/gps_cnav_ephemeris.h @@ -48,12 +48,12 @@ private: double check_t(double time); public: - unsigned int i_satellite_PRN; // SV PRN NUMBER + uint32_t i_satellite_PRN; // SV PRN NUMBER - //Message Types 10 and 11 Parameters (1 of 2) - int i_GPS_week; //!< GPS week number, aka WN [week] - int i_URA; //!< ED Accuracy Index - int i_signal_health; //!< Signal health (L1/L2/L5) + // Message Types 10 and 11 Parameters (1 of 2) + int32_t i_GPS_week; //!< GPS week number, aka WN [week] + int32_t i_URA; //!< ED Accuracy Index + int32_t i_signal_health; //!< Signal health (L1/L2/L5) double d_Top; //!< Data predict time of week double d_DELTA_A; //!< Semi-major axis difference at reference time double d_A_DOT; //!< Change rate in semi-major axis @@ -75,7 +75,7 @@ public: double d_Cus; //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad] double d_Cuc; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] - //Clock Correction and Accuracy Parameters + // Clock Correction and Accuracy Parameters double d_Toc; //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s] double d_A_f0; //!< Coefficient 0 of code phase offset model [s] double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s] @@ -85,8 +85,7 @@ public: double d_URA1; //! bits, const std::vector> parameter) +bool Gps_CNAV_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) { bool value; @@ -88,18 +88,18 @@ bool Gps_CNAV_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) +uint64_t Gps_CNAV_Navigation_Message::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) { - unsigned long int value = 0; - int num_of_slices = parameter.size(); - for (int i = 0; i < num_of_slices; i++) + uint64_t value = 0ULL; + int32_t num_of_slices = parameter.size(); + for (int32_t i = 0; i < num_of_slices; i++) { - for (int j = 0; j < parameter[i].second; j++) + for (int32_t j = 0; j < parameter[i].second; j++) { - value <<= 1; //shift left + value <<= 1; // shift left if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) { - value += 1; // insert the bit + value += 1ULL; // insert the bit } } } @@ -107,59 +107,30 @@ unsigned long int Gps_CNAV_Navigation_Message::read_navigation_unsigned(std::bit } -signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector> parameter) +int64_t Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector> parameter) { - signed long int value = 0; - int num_of_slices = parameter.size(); - // Discriminate between 64 bits and 32 bits compiler - int long_int_size_bytes = sizeof(signed long int); - if (long_int_size_bytes == 8) // if a long int takes 8 bytes, we are in a 64 bits system - { - // read the MSB and perform the sign extension - if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) - { - value ^= 0xFFFFFFFFFFFFFFFF; //64 bits variable - } - else - { - value &= 0; - } + int64_t value = 0LL; + int32_t num_of_slices = parameter.size(); - for (int i = 0; i < num_of_slices; i++) - { - for (int j = 0; j < parameter[i].second; j++) - { - value <<= 1; //shift left - value &= 0xFFFFFFFFFFFFFFFE; //reset the corresponding bit (for the 64 bits variable) - if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) - { - value += 1; // insert the bit - } - } - } + // read the MSB and perform the sign extension + if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) + { + value ^= 0xFFFFFFFFFFFFFFFFLL; // 64 bits variable } - else // we assume we are in a 32 bits system + else { - // read the MSB and perform the sign extension - if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[0].first] == 1) - { - value ^= 0xFFFFFFFF; - } - else - { - value &= 0; - } + value &= 0LL; + } - for (int i = 0; i < num_of_slices; i++) + for (int32_t i = 0; i < num_of_slices; i++) + { + for (int32_t j = 0; j < parameter[i].second; j++) { - for (int j = 0; j < parameter[i].second; j++) + value <<= 1; // shift left + value &= 0xFFFFFFFFFFFFFFFELL; // reset the corresponding bit (for the 64 bits variable) + if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) { - value <<= 1; //shift left - value &= 0xFFFFFFFE; //reset the corresponding bit - if (bits[GPS_CNAV_DATA_PAGE_BITS - parameter[i].first - j] == 1) - { - value += 1; // insert the bit - } + value += 1LL; // insert the bit } } } @@ -169,13 +140,12 @@ signed long int Gps_CNAV_Navigation_Message::read_navigation_signed(std::bitset< void Gps_CNAV_Navigation_Message::decode_page(std::bitset data_bits) { - int PRN; - int page_type; - + int32_t PRN; + int32_t page_type; bool alert_flag; // common to all messages - PRN = static_cast(read_navigation_unsigned(data_bits, CNAV_PRN)); + PRN = static_cast(read_navigation_unsigned(data_bits, CNAV_PRN)); ephemeris_record.i_satellite_PRN = PRN; d_TOW = static_cast(read_navigation_unsigned(data_bits, CNAV_TOW)); @@ -185,13 +155,13 @@ void Gps_CNAV_Navigation_Message::decode_page(std::bitset(read_navigation_bool(data_bits, CNAV_ALERT_FLAG)); ephemeris_record.b_alert_flag = alert_flag; - page_type = static_cast(read_navigation_unsigned(data_bits, CNAV_MSG_TYPE)); + page_type = static_cast(read_navigation_unsigned(data_bits, CNAV_MSG_TYPE)); switch (page_type) { case 10: // Ephemeris 1/2 - ephemeris_record.i_GPS_week = static_cast(read_navigation_unsigned(data_bits, CNAV_WN)); - ephemeris_record.i_signal_health = static_cast(read_navigation_unsigned(data_bits, CNAV_HEALTH)); + ephemeris_record.i_GPS_week = static_cast(read_navigation_unsigned(data_bits, CNAV_WN)); + ephemeris_record.i_signal_health = static_cast(read_navigation_unsigned(data_bits, CNAV_HEALTH)); ephemeris_record.d_Top = static_cast(read_navigation_unsigned(data_bits, CNAV_TOP1)); ephemeris_record.d_Top *= CNAV_TOP1_LSB; ephemeris_record.d_URA0 = static_cast(read_navigation_signed(data_bits, CNAV_URA)); @@ -256,7 +226,7 @@ void Gps_CNAV_Navigation_Message::decode_page(std::bitset(read_navigation_signed(data_bits, CNAV_AF2)); ephemeris_record.d_A_f2 *= CNAV_AF2_LSB; //group delays - //Check if the grup delay values are not available. See IS-GPS-200, Table 30-IV. + // Check if the grup delay values are not available. See IS-GPS-200, Table 30-IV. //Bit string "1000000000000" is -4096 in 2 complement ephemeris_record.d_TGD = static_cast(read_navigation_signed(data_bits, CNAV_TGD)); if (ephemeris_record.d_TGD < -4095.9) @@ -330,7 +300,6 @@ void Gps_CNAV_Navigation_Message::decode_page(std::bitset(read_navigation_signed(data_bits, CNAV_A2)); utc_model_record.d_A2 = utc_model_record.d_A2 * CNAV_A2_LSB; - utc_model_record.d_DeltaT_LS = static_cast(read_navigation_signed(data_bits, CNAV_DELTA_TLS)); utc_model_record.d_DeltaT_LS = utc_model_record.d_DeltaT_LS * CNAV_DELTA_TLS_LSB; @@ -356,13 +325,13 @@ void Gps_CNAV_Navigation_Message::decode_page(std::bitset +#include #include #include #include @@ -55,9 +56,9 @@ class Gps_CNAV_Navigation_Message { private: - unsigned long int read_navigation_unsigned(std::bitset bits, const std::vector> parameter); - signed long int read_navigation_signed(std::bitset bits, const std::vector> parameter); - bool read_navigation_bool(std::bitset bits, const std::vector> parameter); + uint64_t read_navigation_unsigned(std::bitset bits, const std::vector> parameter); + int64_t read_navigation_signed(std::bitset bits, const std::vector> parameter); + bool read_navigation_bool(std::bitset bits, const std::vector> parameter); Gps_CNAV_Ephemeris ephemeris_record; Gps_CNAV_Iono iono_record; @@ -70,7 +71,7 @@ public: bool b_flag_iono_valid; //!< If set, it indicates that the ionospheric parameters are filled and are not yet read by the get_iono bool b_flag_utc_valid; //!< If set, it indicates that the utc parameters are filled and are not yet read by the get_utc_model - std::map satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus + std::map satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus // satellite positions double d_satpos_X; //!< Earth-fixed coordinate x of the satellite [m]. Intersection of the IERS Reference Meridian (IRM) and the plane passing through the origin and normal to the Z-axis. @@ -78,8 +79,8 @@ public: double d_satpos_Z; //!< Earth-fixed coordinate z of the satellite [m]. The direction of the IERS (International Earth Rotation and Reference Systems Service) Reference Pole (IRP). // satellite identification info - int i_channel_ID; - unsigned int i_satellite_PRN; + int32_t i_channel_ID; + uint32_t i_satellite_PRN; // Satellite velocity double d_satvel_X; //!< Earth-fixed velocity coordinate x of the satellite [m] @@ -90,14 +91,17 @@ public: void reset(); void decode_page(std::bitset data_bits); + /*! * \brief Obtain a GPS SV Ephemeris class filled with current SV data */ Gps_CNAV_Ephemeris get_ephemeris(); + /*! * \brief Check if we have a new iono record stored in the GPS ephemeris class */ bool have_new_iono(); + /*! * \brief Obtain a GPS ionospheric correction parameters class filled with current SV data */ diff --git a/src/core/system_parameters/gps_cnav_utc_model.cc b/src/core/system_parameters/gps_cnav_utc_model.cc index a705566da..90e1a4af2 100644 --- a/src/core/system_parameters/gps_cnav_utc_model.cc +++ b/src/core/system_parameters/gps_cnav_utc_model.cc @@ -34,35 +34,36 @@ Gps_CNAV_Utc_Model::Gps_CNAV_Utc_Model() { valid = false; - d_A2 = 0; - d_A1 = 0; - d_A0 = 0; - d_t_OT = 0; + d_A2 = 0.0; + d_A1 = 0.0; + d_A0 = 0.0; + d_t_OT = 0.0; i_WN_T = 0; - d_DeltaT_LS = 0; + d_DeltaT_LS = 0.0; i_WN_LSF = 0; i_DN = 0; - d_DeltaT_LSF = 0; + d_DeltaT_LSF = 0.0; } -double Gps_CNAV_Utc_Model::utc_time(double gpstime_corrected, int i_GPS_week) + +double Gps_CNAV_Utc_Model::utc_time(double gpstime_corrected, int32_t i_GPS_week) { double t_utc; double t_utc_daytime; double Delta_t_UTC = d_DeltaT_LS + d_A0 + d_A1 * (gpstime_corrected - d_t_OT + 604800 * static_cast(i_GPS_week - i_WN_T)); // Determine if the effectivity time of the leap second event is in the past - int weeksToLeapSecondEvent = i_WN_LSF - i_GPS_week; + int32_t weeksToLeapSecondEvent = i_WN_LSF - i_GPS_week; if (weeksToLeapSecondEvent >= 0) // is not in the past { - //Detect if the effectivity time and user's time is within six hours = 6 * 60 *60 = 21600 s - int secondOfLeapSecondEvent = i_DN * 24 * 60 * 60; + // Detect if the effectivity time and user's time is within six hours = 6 * 60 *60 = 21600 s + int32_t secondOfLeapSecondEvent = i_DN * 24 * 60 * 60; if (weeksToLeapSecondEvent > 0) { t_utc_daytime = fmod(gpstime_corrected - Delta_t_UTC, 86400); } - else //we are in the same week than the leap second event + else // we are in the same week than the leap second event { if (std::abs(gpstime_corrected - secondOfLeapSecondEvent) > 21600) { @@ -83,9 +84,9 @@ double Gps_CNAV_Utc_Model::utc_time(double gpstime_corrected, int i_GPS_week) * proper accommodation of the leap second event with a possible week number * transition is provided by the following expression for UTC: */ - int W = fmod(gpstime_corrected - Delta_t_UTC - 43200, 86400) + 43200; + int32_t W = fmod(gpstime_corrected - Delta_t_UTC - 43200, 86400) + 43200; t_utc_daytime = fmod(W, 86400 + d_DeltaT_LSF - d_DeltaT_LS); - //implement something to handle a leap second event! + // implement something to handle a leap second event! } if ((gpstime_corrected - secondOfLeapSecondEvent) > 21600) { diff --git a/src/core/system_parameters/gps_cnav_utc_model.h b/src/core/system_parameters/gps_cnav_utc_model.h index 42a26839a..b9dba4936 100644 --- a/src/core/system_parameters/gps_cnav_utc_model.h +++ b/src/core/system_parameters/gps_cnav_utc_model.h @@ -34,7 +34,7 @@ #include #include - +#include /*! * \brief This class is a storage for the GPS UTC MODEL data as described in in IS-GPS-200H @@ -50,10 +50,10 @@ public: double d_A1; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200H) [s/s] double d_A0; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200H) [s] double d_t_OT; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200H) [s] - int i_WN_T; //!< UTC reference week number [weeks] + int32_t i_WN_T; //!< UTC reference week number [weeks] double d_DeltaT_LS; //!< delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac. - int i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks] - int i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days] + int32_t i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks] + int32_t i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days] double d_DeltaT_LSF; //!< Scheduled future or recent past (relative to NAV message upload) value of the delta time due to leap seconds [s] /*! @@ -65,13 +65,13 @@ public: * \brief Computes the Coordinated Universal Time (UTC) and * returns it in [s] (IS-GPS-200E, 20.3.3.5.2.4 + 30.3.3.6.2) */ - double utc_time(double gpstime_corrected, int i_GPS_week); + double utc_time(double gpstime_corrected, int32_t i_GPS_week); template /* * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file. */ - inline void serialize(Archive& archive, const unsigned int version) + inline void serialize(Archive& archive, const uint32_t version) { using boost::serialization::make_nvp; if (version) diff --git a/src/core/system_parameters/gps_ephemeris.cc b/src/core/system_parameters/gps_ephemeris.cc index 3ee9ed42a..c7f394efc 100644 --- a/src/core/system_parameters/gps_ephemeris.cc +++ b/src/core/system_parameters/gps_ephemeris.cc @@ -37,43 +37,43 @@ Gps_Ephemeris::Gps_Ephemeris() { - i_satellite_PRN = 0; - d_TOW = 0; - d_Crs = 0; - d_Delta_n = 0; - d_M_0 = 0; - d_Cuc = 0; - d_e_eccentricity = 0; - d_Cus = 0; - d_sqrt_A = 0; - d_Toe = 0; - d_Toc = 0; - d_Cic = 0; - d_OMEGA0 = 0; - d_Cis = 0; - d_i_0 = 0; - d_Crc = 0; - d_OMEGA = 0; - d_OMEGA_DOT = 0; - d_IDOT = 0; + i_satellite_PRN = 0U; + d_TOW = 0.0; + d_Crs = 0.0; + d_Delta_n = 0.0; + d_M_0 = 0.0; + d_Cuc = 0.0; + d_e_eccentricity = 0.0; + d_Cus = 0.0; + d_sqrt_A = 0.0; + d_Toe = 0.0; + d_Toc = 0.0; + d_Cic = 0.0; + d_OMEGA0 = 0.0; + d_Cis = 0.0; + d_i_0 = 0.0; + d_Crc = 0.0; + d_OMEGA = 0.0; + d_OMEGA_DOT = 0.0; + d_IDOT = 0.0; i_code_on_L2 = 0; i_GPS_week = 0; b_L2_P_data_flag = false; i_SV_accuracy = 0; i_SV_health = 0; - d_IODE_SF2 = 0; - d_IODE_SF3 = 0; - d_TGD = 0; // Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s] - d_IODC = 0; // Issue of Data, Clock - i_AODO = 0; // Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] + d_IODE_SF2 = 0.0; + d_IODE_SF3 = 0.0; + d_TGD = 0.0; // Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s] + d_IODC = 0.0; // Issue of Data, Clock + i_AODO = 0; // Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] b_fit_interval_flag = false; // indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours. - d_spare1 = 0; - d_spare2 = 0; + d_spare1 = 0.0; + d_spare2 = 0.0; - d_A_f0 = 0; // Coefficient 0 of code phase offset model [s] - d_A_f1 = 0; // Coefficient 1 of code phase offset model [s/s] - d_A_f2 = 0; // Coefficient 2 of code phase offset model [s/s^2] + d_A_f0 = 0.0; // Coefficient 0 of code phase offset model [s] + d_A_f1 = 0.0; // Coefficient 1 of code phase offset model [s/s] + d_A_f2 = 0.0; // Coefficient 2 of code phase offset model [s/s^2] b_integrity_status_flag = false; b_alert_flag = false; // If true, indicates that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk. @@ -81,7 +81,7 @@ Gps_Ephemeris::Gps_Ephemeris() auto gnss_sat = Gnss_Satellite(); std::string _system("GPS"); - for (unsigned int i = 1; i < 33; i++) + for (uint32_t i = 1; i < 33; i++) { satelliteBlock[i] = gnss_sat.what_block(_system, i); } @@ -120,7 +120,7 @@ double Gps_Ephemeris::sv_clock_drift(double transmitTime) // double dt; // dt = check_t(transmitTime - d_Toc); // - // for (int i = 0; i < 2; i++) + // for (int32_t i = 0; i < 2; i++) // { // dt -= d_A_f0 + d_A_f1 * dt + d_A_f2 * (dt * dt); // } @@ -169,7 +169,7 @@ double Gps_Ephemeris::sv_clock_relativistic_term(double transmitTime) E = M; // --- Iteratively compute eccentric anomaly ---------------------------- - for (int ii = 1; ii < 20; ii++) + for (int32_t ii = 1; ii < 20; ii++) { E_old = E; E = M + d_e_eccentricity * sin(E); @@ -228,7 +228,7 @@ double Gps_Ephemeris::satellitePosition(double transmitTime) E = M; // --- Iteratively compute eccentric anomaly ---------------------------- - for (int ii = 1; ii < 20; ii++) + for (int32_t ii = 1; ii < 20; ii++) { E_old = E; E = M + d_e_eccentricity * sin(E); diff --git a/src/core/system_parameters/gps_ephemeris.h b/src/core/system_parameters/gps_ephemeris.h index d13ad4893..5466b54d9 100644 --- a/src/core/system_parameters/gps_ephemeris.h +++ b/src/core/system_parameters/gps_ephemeris.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -58,35 +59,35 @@ private: double check_t(double time); public: - unsigned int i_satellite_PRN; // SV PRN NUMBER - double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s] - double d_Crs; //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m] - double d_Delta_n; //!< Mean Motion Difference From Computed Value [semi-circles/s] - double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles] - double d_Cuc; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] - double d_e_eccentricity; //!< Eccentricity [dimensionless] - double d_Cus; //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad] - double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)] - double d_Toe; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] - double d_Toc; //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s] - double d_Cic; //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad] - double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] - double d_Cis; //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad] - double d_i_0; //!< Inclination Angle at Reference Time [semi-circles] - double d_Crc; //!< Amplitude of the Cosine Harmonic Correction Term to the Orbit Radius [m] - double d_OMEGA; //!< Argument of Perigee [semi-cicles] - double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s] - double d_IDOT; //!< Rate of Inclination Angle [semi-circles/s] - int i_code_on_L2; //!< If 1, P code ON in L2; if 2, C/A code ON in L2; - int i_GPS_week; //!< GPS week number, aka WN [week] - bool b_L2_P_data_flag; //!< When true, indicates that the NAV data stream was commanded OFF on the P-code of the L2 channel - int i_SV_accuracy; //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200E) - int i_SV_health; + uint32_t i_satellite_PRN; // SV PRN NUMBER + double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s] + double d_Crs; //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m] + double d_Delta_n; //!< Mean Motion Difference From Computed Value [semi-circles/s] + double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles] + double d_Cuc; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] + double d_e_eccentricity; //!< Eccentricity [dimensionless] + double d_Cus; //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad] + double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)] + double d_Toe; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] + double d_Toc; //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s] + double d_Cic; //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad] + double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] + double d_Cis; //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad] + double d_i_0; //!< Inclination Angle at Reference Time [semi-circles] + double d_Crc; //!< Amplitude of the Cosine Harmonic Correction Term to the Orbit Radius [m] + double d_OMEGA; //!< Argument of Perigee [semi-cicles] + double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s] + double d_IDOT; //!< Rate of Inclination Angle [semi-circles/s] + int32_t i_code_on_L2; //!< If 1, P code ON in L2; if 2, C/A code ON in L2; + int32_t i_GPS_week; //!< GPS week number, aka WN [week] + bool b_L2_P_data_flag; //!< When true, indicates that the NAV data stream was commanded OFF on the P-code of the L2 channel + int32_t i_SV_accuracy; //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200E) + int32_t i_SV_health; double d_TGD; //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s] double d_IODC; //!< Issue of Data, Clock double d_IODE_SF2; //!< Issue of Data, Ephemeris (IODE), subframe 2 double d_IODE_SF3; //!< Issue of Data, Ephemeris(IODE), subframe 3 - int i_AODO; //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] + int32_t i_AODO; //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] bool b_fit_interval_flag; //!< indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours. double d_spare1; @@ -133,7 +134,7 @@ public: /*! * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file. */ - inline void serialize(Archive& archive, const unsigned int version) + inline void serialize(Archive& archive, const uint32_t version) { using boost::serialization::make_nvp; if (version) @@ -152,7 +153,7 @@ public: archive& make_nvp("d_Cus", d_Cus); //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad] archive& make_nvp("d_sqrt_A", d_sqrt_A); //!< Square Root of the Semi-Major Axis [sqrt(m)] archive& make_nvp("d_Toe", d_Toe); //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] - archive& make_nvp("d_Toc", d_Toe); //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s] + archive& make_nvp("d_Toc", d_Toc); //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s] archive& make_nvp("d_Cic", d_Cic); //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad] archive& make_nvp("d_OMEGA0", d_OMEGA0); //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] archive& make_nvp("d_Cis", d_Cis); //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad] diff --git a/src/core/system_parameters/gps_navigation_message.cc b/src/core/system_parameters/gps_navigation_message.cc index 7d7fd298f..e4a7f1db1 100644 --- a/src/core/system_parameters/gps_navigation_message.cc +++ b/src/core/system_parameters/gps_navigation_message.cc @@ -40,64 +40,64 @@ void Gps_Navigation_Message::reset() { b_valid_ephemeris_set_flag = false; d_TOW = 0.0; - d_TOW_SF1 = 0; - d_TOW_SF2 = 0; - d_TOW_SF3 = 0; - d_TOW_SF4 = 0; - d_TOW_SF5 = 0; - d_IODE_SF2 = 0; - d_IODE_SF3 = 0; - d_Crs = 0; - d_Delta_n = 0; - d_M_0 = 0; - d_Cuc = 0; - d_e_eccentricity = 0; - d_Cus = 0; - d_sqrt_A = 0; - d_Toe = 0; - d_Toc = 0; - d_Cic = 0; - d_OMEGA0 = 0; - d_Cis = 0; - d_i_0 = 0; - d_Crc = 0; - d_OMEGA = 0; - d_OMEGA_DOT = 0; - d_IDOT = 0; + d_TOW_SF1 = 0.0; + d_TOW_SF2 = 0.0; + d_TOW_SF3 = 0.0; + d_TOW_SF4 = 0.0; + d_TOW_SF5 = 0.0; + d_IODE_SF2 = 0.0; + d_IODE_SF3 = 0.0; + d_Crs = 0.0; + d_Delta_n = 0.0; + d_M_0 = 0.0; + d_Cuc = 0.0; + d_e_eccentricity = 0.0; + d_Cus = 0.0; + d_sqrt_A = 0.0; + d_Toe = 0.0; + d_Toc = 0.0; + d_Cic = 0.0; + d_OMEGA0 = 0.0; + d_Cis = 0.0; + d_i_0 = 0.0; + d_Crc = 0.0; + d_OMEGA = 0.0; + d_OMEGA_DOT = 0.0; + d_IDOT = 0.0; i_code_on_L2 = 0; i_GPS_week = 0; b_L2_P_data_flag = false; i_SV_accuracy = 0; i_SV_health = 0; - d_TGD = 0; + d_TGD = 0.0; d_IODC = -1.0; i_AODO = 0; b_fit_interval_flag = false; - d_spare1 = 0; - d_spare2 = 0; + d_spare1 = 0.0; + d_spare2 = 0.0; - d_A_f0 = 0; - d_A_f1 = 0; - d_A_f2 = 0; + d_A_f0 = 0.0; + d_A_f1 = 0.0; + d_A_f2 = 0.0; //clock terms //d_master_clock=0; - d_dtr = 0; - d_satClkCorr = 0; - d_satClkDrift = 0; + d_dtr = 0.0; + d_satClkCorr = 0.0; + d_satClkDrift = 0.0; // satellite positions - d_satpos_X = 0; - d_satpos_Y = 0; - d_satpos_Z = 0; + d_satpos_X = 0.0; + d_satpos_Y = 0.0; + d_satpos_Z = 0.0; // info i_channel_ID = 0; - i_satellite_PRN = 0; + i_satellite_PRN = 0U; // time synchro - d_subframe_timestamp_ms = 0; + d_subframe_timestamp_ms = 0.0; // flags b_alert_flag = false; @@ -107,39 +107,39 @@ void Gps_Navigation_Message::reset() // Ionosphere and UTC flag_iono_valid = false; flag_utc_model_valid = false; - d_alpha0 = 0; - d_alpha1 = 0; - d_alpha2 = 0; - d_alpha3 = 0; - d_beta0 = 0; - d_beta1 = 0; - d_beta2 = 0; - d_beta3 = 0; - d_A1 = 0; - d_A0 = 0; - d_t_OT = 0; + d_alpha0 = 0.0; + d_alpha1 = 0.0; + d_alpha2 = 0.0; + d_alpha3 = 0.0; + d_beta0 = 0.0; + d_beta1 = 0.0; + d_beta2 = 0.0; + d_beta3 = 0.0; + d_A1 = 0.0; + d_A0 = 0.0; + d_t_OT = 0.0; i_WN_T = 0; - d_DeltaT_LS = 0; + d_DeltaT_LS = 0.0; i_WN_LSF = 0; i_DN = 0; - d_DeltaT_LSF = 0; + d_DeltaT_LSF = 0.0; - //Almanac - d_Toa = 0; + // Almanac + i_Toa = 0; i_WN_A = 0; - for (int i = 1; i < 32; i++) + for (int32_t i = 1; i < 32; i++) { almanacHealth[i] = 0; } // Satellite velocity - d_satvel_X = 0; - d_satvel_Y = 0; - d_satvel_Z = 0; + d_satvel_X = 0.0; + d_satvel_Y = 0.0; + d_satvel_Z = 0.0; auto gnss_sat = Gnss_Satellite(); std::string _system("GPS"); - for (unsigned int i = 1; i < 33; i++) + for (uint32_t i = 1; i < 33; i++) { satelliteBlock[i] = gnss_sat.what_block(_system, i); } @@ -152,7 +152,7 @@ Gps_Navigation_Message::Gps_Navigation_Message() } -void Gps_Navigation_Message::print_gps_word_bytes(unsigned int GPS_word) +void Gps_Navigation_Message::print_gps_word_bytes(uint32_t GPS_word) { std::cout << " Word ="; std::cout << std::bitset<32>(GPS_word); @@ -160,7 +160,7 @@ void Gps_Navigation_Message::print_gps_word_bytes(unsigned int GPS_word) } -bool Gps_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) +bool Gps_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) { bool value; @@ -176,18 +176,18 @@ bool Gps_Navigation_Message::read_navigation_bool(std::bitset } -unsigned long int Gps_Navigation_Message::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) +uint64_t Gps_Navigation_Message::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) { - unsigned long int value = 0; - int num_of_slices = parameter.size(); - for (int i = 0; i < num_of_slices; i++) + uint64_t value = 0ULL; + int32_t num_of_slices = parameter.size(); + for (int32_t i = 0; i < num_of_slices; i++) { - for (int j = 0; j < parameter[i].second; j++) + for (int32_t j = 0; j < parameter[i].second; j++) { - value <<= 1; //shift left + value <<= 1; // shift left if (bits[GPS_SUBFRAME_BITS - parameter[i].first - j] == 1) { - value += 1; // insert the bit + value += 1ULL; // insert the bit } } } @@ -195,198 +195,166 @@ unsigned long int Gps_Navigation_Message::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) +int64_t Gps_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector> parameter) { - signed long int value = 0; - int num_of_slices = parameter.size(); - // Discriminate between 64 bits and 32 bits compiler - int long_int_size_bytes = sizeof(signed long int); - if (long_int_size_bytes == 8) // if a long int takes 8 bytes, we are in a 64 bits system - { - // read the MSB and perform the sign extension - if (bits[GPS_SUBFRAME_BITS - parameter[0].first] == 1) - { - value ^= 0xFFFFFFFFFFFFFFFF; //64 bits variable - } - else - { - value &= 0; - } + int64_t value = 0LL; + int32_t num_of_slices = parameter.size(); - for (int i = 0; i < num_of_slices; i++) - { - for (int j = 0; j < parameter[i].second; j++) - { - value <<= 1; //shift left - value &= 0xFFFFFFFFFFFFFFFE; //reset the corresponding bit (for the 64 bits variable) - if (bits[GPS_SUBFRAME_BITS - parameter[i].first - j] == 1) - { - value += 1; // insert the bit - } - } - } + // read the MSB and perform the sign extension + if (bits[GPS_SUBFRAME_BITS - parameter[0].first] == 1) + { + value ^= 0xFFFFFFFFFFFFFFFFLL; // 64 bits variable } - else // we assume we are in a 32 bits system + else { - // read the MSB and perform the sign extension - if (bits[GPS_SUBFRAME_BITS - parameter[0].first] == 1) - { - value ^= 0xFFFFFFFF; - } - else - { - value &= 0; - } + value &= 0LL; + } - for (int i = 0; i < num_of_slices; i++) + for (int32_t i = 0; i < num_of_slices; i++) + { + for (int32_t j = 0; j < parameter[i].second; j++) { - for (int j = 0; j < parameter[i].second; j++) + value <<= 1; // shift left + value &= 0xFFFFFFFFFFFFFFFELL; // reset the corresponding bit (for the 64 bits variable) + if (bits[GPS_SUBFRAME_BITS - parameter[i].first - j] == 1) { - value <<= 1; //shift left - value &= 0xFFFFFFFE; //reset the corresponding bit - if (bits[GPS_SUBFRAME_BITS - parameter[i].first - j] == 1) - { - value += 1; // insert the bit - } + value += 1LL; // insert the bit } } } return value; } -int Gps_Navigation_Message::subframe_decoder(char *subframe) + +int32_t Gps_Navigation_Message::subframe_decoder(char *subframe) { - int subframe_ID = 0; - - //double tmp_TOW; - - unsigned int gps_word; + int32_t subframe_ID = 0; + uint32_t gps_word; // UNPACK BYTES TO BITS AND REMOVE THE CRC REDUNDANCE std::bitset subframe_bits; std::bitset word_bits; - for (int i = 0; i < 10; i++) + for (int32_t i = 0; i < 10; i++) { memcpy(&gps_word, &subframe[i * 4], sizeof(char) * 4); word_bits = std::bitset<(GPS_WORD_BITS + 2)>(gps_word); - for (int j = 0; j < GPS_WORD_BITS; j++) + for (int32_t j = 0; j < GPS_WORD_BITS; j++) { subframe_bits[GPS_WORD_BITS * (9 - i) + j] = word_bits[j]; } } - subframe_ID = static_cast(read_navigation_unsigned(subframe_bits, SUBFRAME_ID)); + subframe_ID = static_cast(read_navigation_unsigned(subframe_bits, SUBFRAME_ID)); // Decode all 5 sub-frames switch (subframe_ID) - { - //--- Decode the sub-frame id ------------------------------------------ - // ICD (IS-GPS-200E Appendix II). http://www.losangeles.af.mil/shared/media/document/AFD-100813-045.pdf - case 1: - //--- It is subframe 1 ------------------------------------- - // Compute the time of week (TOW) of the first sub-frames in the array ==== - // The transmitted TOW is actual TOW of the next subframe - // (the variable subframe at this point contains bits of the last subframe). - //TOW = bin2dec(subframe(31:47)) * 6; - d_TOW_SF1 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); - //we are in the first subframe (the transmitted TOW is the start time of the next subframe) ! - d_TOW_SF1 = d_TOW_SF1 * 6.0; - d_TOW = d_TOW_SF1; // Set transmission time - b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); - b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); - b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); - i_GPS_week = static_cast(read_navigation_unsigned(subframe_bits, GPS_WEEK)); - i_SV_accuracy = static_cast(read_navigation_unsigned(subframe_bits, SV_ACCURACY)); // (20.3.3.3.1.3) - i_SV_health = static_cast(read_navigation_unsigned(subframe_bits, SV_HEALTH)); - b_L2_P_data_flag = read_navigation_bool(subframe_bits, L2_P_DATA_FLAG); // - i_code_on_L2 = static_cast(read_navigation_unsigned(subframe_bits, CA_OR_P_ON_L2)); - d_TGD = static_cast(read_navigation_signed(subframe_bits, T_GD)); - d_TGD = d_TGD * T_GD_LSB; - d_IODC = static_cast(read_navigation_unsigned(subframe_bits, IODC)); - d_Toc = static_cast(read_navigation_unsigned(subframe_bits, T_OC)); - d_Toc = d_Toc * T_OC_LSB; - d_A_f0 = static_cast(read_navigation_signed(subframe_bits, A_F0)); - d_A_f0 = d_A_f0 * A_F0_LSB; - d_A_f1 = static_cast(read_navigation_signed(subframe_bits, A_F1)); - d_A_f1 = d_A_f1 * A_F1_LSB; - d_A_f2 = static_cast(read_navigation_signed(subframe_bits, A_F2)); - d_A_f2 = d_A_f2 * A_F2_LSB; - + { + //--- Decode the sub-frame id ------------------------------------------ + // ICD (IS-GPS-200E Appendix II). http://www.losangeles.af.mil/shared/media/document/AFD-100813-045.pdf + case 1: + //--- It is subframe 1 ------------------------------------- + // Compute the time of week (TOW) of the first sub-frames in the array ==== + // The transmitted TOW is actual TOW of the next subframe + // (the variable subframe at this point contains bits of the last subframe). + //TOW = bin2dec(subframe(31:47)) * 6; + d_TOW_SF1 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); + //we are in the first subframe (the transmitted TOW is the start time of the next subframe) ! + d_TOW_SF1 = d_TOW_SF1 * 6.0; + d_TOW = d_TOW_SF1; // Set transmission time + b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); + b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); + b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); + i_GPS_week = static_cast(read_navigation_unsigned(subframe_bits, GPS_WEEK)); + i_SV_accuracy = static_cast(read_navigation_unsigned(subframe_bits, SV_ACCURACY)); // (20.3.3.3.1.3) + i_SV_health = static_cast(read_navigation_unsigned(subframe_bits, SV_HEALTH)); + b_L2_P_data_flag = read_navigation_bool(subframe_bits, L2_P_DATA_FLAG); // + i_code_on_L2 = static_cast(read_navigation_unsigned(subframe_bits, CA_OR_P_ON_L2)); + d_TGD = static_cast(read_navigation_signed(subframe_bits, T_GD)); + d_TGD = d_TGD * T_GD_LSB; + d_IODC = static_cast(read_navigation_unsigned(subframe_bits, IODC)); + d_Toc = static_cast(read_navigation_unsigned(subframe_bits, T_OC)); + d_Toc = d_Toc * T_OC_LSB; + d_A_f0 = static_cast(read_navigation_signed(subframe_bits, A_F0)); + d_A_f0 = d_A_f0 * A_F0_LSB; + d_A_f1 = static_cast(read_navigation_signed(subframe_bits, A_F1)); + d_A_f1 = d_A_f1 * A_F1_LSB; + d_A_f2 = static_cast(read_navigation_signed(subframe_bits, A_F2)); + d_A_f2 = d_A_f2 * A_F2_LSB; break; - case 2: //--- It is subframe 2 ------------------- - d_TOW_SF2 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); - d_TOW_SF2 = d_TOW_SF2 * 6.0; - d_TOW = d_TOW_SF2; // Set transmission time - b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); - b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); - b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); - d_IODE_SF2 = static_cast(read_navigation_unsigned(subframe_bits, IODE_SF2)); - d_Crs = static_cast(read_navigation_signed(subframe_bits, C_RS)); - d_Crs = d_Crs * C_RS_LSB; - d_Delta_n = static_cast(read_navigation_signed(subframe_bits, DELTA_N)); - d_Delta_n = d_Delta_n * DELTA_N_LSB; - d_M_0 = static_cast(read_navigation_signed(subframe_bits, M_0)); - d_M_0 = d_M_0 * M_0_LSB; - d_Cuc = static_cast(read_navigation_signed(subframe_bits, C_UC)); - d_Cuc = d_Cuc * C_UC_LSB; - d_e_eccentricity = static_cast(read_navigation_unsigned(subframe_bits, E)); - d_e_eccentricity = d_e_eccentricity * E_LSB; - d_Cus = static_cast(read_navigation_signed(subframe_bits, C_US)); - d_Cus = d_Cus * C_US_LSB; - d_sqrt_A = static_cast(read_navigation_unsigned(subframe_bits, SQRT_A)); - d_sqrt_A = d_sqrt_A * SQRT_A_LSB; - d_Toe = static_cast(read_navigation_unsigned(subframe_bits, T_OE)); - d_Toe = d_Toe * T_OE_LSB; - b_fit_interval_flag = read_navigation_bool(subframe_bits, FIT_INTERVAL_FLAG); - i_AODO = static_cast(read_navigation_unsigned(subframe_bits, AODO)); - i_AODO = i_AODO * AODO_LSB; - + case 2: //--- It is subframe 2 ------------------- + d_TOW_SF2 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); + d_TOW_SF2 = d_TOW_SF2 * 6.0; + d_TOW = d_TOW_SF2; // Set transmission time + b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); + b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); + b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); + d_IODE_SF2 = static_cast(read_navigation_unsigned(subframe_bits, IODE_SF2)); + d_Crs = static_cast(read_navigation_signed(subframe_bits, C_RS)); + d_Crs = d_Crs * C_RS_LSB; + d_Delta_n = static_cast(read_navigation_signed(subframe_bits, DELTA_N)); + d_Delta_n = d_Delta_n * DELTA_N_LSB; + d_M_0 = static_cast(read_navigation_signed(subframe_bits, M_0)); + d_M_0 = d_M_0 * M_0_LSB; + d_Cuc = static_cast(read_navigation_signed(subframe_bits, C_UC)); + d_Cuc = d_Cuc * C_UC_LSB; + d_e_eccentricity = static_cast(read_navigation_unsigned(subframe_bits, E)); + d_e_eccentricity = d_e_eccentricity * E_LSB; + d_Cus = static_cast(read_navigation_signed(subframe_bits, C_US)); + d_Cus = d_Cus * C_US_LSB; + d_sqrt_A = static_cast(read_navigation_unsigned(subframe_bits, SQRT_A)); + d_sqrt_A = d_sqrt_A * SQRT_A_LSB; + d_Toe = static_cast(read_navigation_unsigned(subframe_bits, T_OE)); + d_Toe = d_Toe * T_OE_LSB; + b_fit_interval_flag = read_navigation_bool(subframe_bits, FIT_INTERVAL_FLAG); + i_AODO = static_cast(read_navigation_unsigned(subframe_bits, AODO)); + i_AODO = i_AODO * AODO_LSB; break; - case 3: // --- It is subframe 3 ------------------------------------- - d_TOW_SF3 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); - d_TOW_SF3 = d_TOW_SF3 * 6.0; - d_TOW = d_TOW_SF3; // Set transmission time - b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); - b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); - b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); - d_Cic = static_cast(read_navigation_signed(subframe_bits, C_IC)); - d_Cic = d_Cic * C_IC_LSB; - d_OMEGA0 = static_cast(read_navigation_signed(subframe_bits, OMEGA_0)); - d_OMEGA0 = d_OMEGA0 * OMEGA_0_LSB; - d_Cis = static_cast(read_navigation_signed(subframe_bits, C_IS)); - d_Cis = d_Cis * C_IS_LSB; - d_i_0 = static_cast(read_navigation_signed(subframe_bits, I_0)); - d_i_0 = d_i_0 * I_0_LSB; - d_Crc = static_cast(read_navigation_signed(subframe_bits, C_RC)); - d_Crc = d_Crc * C_RC_LSB; - d_OMEGA = static_cast(read_navigation_signed(subframe_bits, OMEGA)); - d_OMEGA = d_OMEGA * OMEGA_LSB; - d_OMEGA_DOT = static_cast(read_navigation_signed(subframe_bits, OMEGA_DOT)); - d_OMEGA_DOT = d_OMEGA_DOT * OMEGA_DOT_LSB; - d_IODE_SF3 = static_cast(read_navigation_unsigned(subframe_bits, IODE_SF3)); - d_IDOT = static_cast(read_navigation_signed(subframe_bits, I_DOT)); - d_IDOT = d_IDOT * I_DOT_LSB; - + case 3: // --- It is subframe 3 ------------------------------------- + d_TOW_SF3 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); + d_TOW_SF3 = d_TOW_SF3 * 6.0; + d_TOW = d_TOW_SF3; // Set transmission time + b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); + b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); + b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); + d_Cic = static_cast(read_navigation_signed(subframe_bits, C_IC)); + d_Cic = d_Cic * C_IC_LSB; + d_OMEGA0 = static_cast(read_navigation_signed(subframe_bits, OMEGA_0)); + d_OMEGA0 = d_OMEGA0 * OMEGA_0_LSB; + d_Cis = static_cast(read_navigation_signed(subframe_bits, C_IS)); + d_Cis = d_Cis * C_IS_LSB; + d_i_0 = static_cast(read_navigation_signed(subframe_bits, I_0)); + d_i_0 = d_i_0 * I_0_LSB; + d_Crc = static_cast(read_navigation_signed(subframe_bits, C_RC)); + d_Crc = d_Crc * C_RC_LSB; + d_OMEGA = static_cast(read_navigation_signed(subframe_bits, OMEGA)); + d_OMEGA = d_OMEGA * OMEGA_LSB; + d_OMEGA_DOT = static_cast(read_navigation_signed(subframe_bits, OMEGA_DOT)); + d_OMEGA_DOT = d_OMEGA_DOT * OMEGA_DOT_LSB; + d_IODE_SF3 = static_cast(read_navigation_unsigned(subframe_bits, IODE_SF3)); + d_IDOT = static_cast(read_navigation_signed(subframe_bits, I_DOT)); + d_IDOT = d_IDOT * I_DOT_LSB; break; - case 4: // --- It is subframe 4 ---------- Almanac, ionospheric model, UTC parameters, SV health (PRN: 25-32) - int SV_data_ID; - int SV_page; - d_TOW_SF4 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); - d_TOW_SF4 = d_TOW_SF4 * 6.0; - d_TOW = d_TOW_SF4; // Set transmission time - b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); - b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); - b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); - SV_data_ID = static_cast(read_navigation_unsigned(subframe_bits, SV_DATA_ID)); - SV_page = static_cast(read_navigation_unsigned(subframe_bits, SV_PAGE)); - if (SV_page > 24 && SV_page < 33) // Page 4 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110) - { - //! \TODO read almanac - if(SV_data_ID){} - } + case 4: // --- It is subframe 4 ---------- Almanac, ionospheric model, UTC parameters, SV health (PRN: 25-32) + int32_t SV_data_ID; + int32_t SV_page; + d_TOW_SF4 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); + d_TOW_SF4 = d_TOW_SF4 * 6.0; + d_TOW = d_TOW_SF4; // Set transmission time + b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); + b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); + b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); + SV_data_ID = static_cast(read_navigation_unsigned(subframe_bits, SV_DATA_ID)); + SV_page = static_cast(read_navigation_unsigned(subframe_bits, SV_PAGE)); + if (SV_page > 24 && SV_page < 33) // Page 4 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110) + { + //! \TODO read almanac + if (SV_data_ID) + { + } + } if (SV_page == 52) // Page 13 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110) { @@ -418,10 +386,10 @@ int Gps_Navigation_Message::subframe_decoder(char *subframe) d_A0 = d_A0 * A_0_LSB; d_t_OT = static_cast(read_navigation_unsigned(subframe_bits, T_OT)); d_t_OT = d_t_OT * T_OT_LSB; - i_WN_T = static_cast(read_navigation_unsigned(subframe_bits, WN_T)); + i_WN_T = static_cast(read_navigation_unsigned(subframe_bits, WN_T)); d_DeltaT_LS = static_cast(read_navigation_signed(subframe_bits, DELTAT_LS)); - i_WN_LSF = static_cast(read_navigation_unsigned(subframe_bits, WN_LSF)); - i_DN = static_cast(read_navigation_unsigned(subframe_bits, DN)); // Right-justified ? + i_WN_LSF = static_cast(read_navigation_unsigned(subframe_bits, WN_LSF)); + i_DN = static_cast(read_navigation_unsigned(subframe_bits, DN)); // Right-justified ? d_DeltaT_LSF = static_cast(read_navigation_signed(subframe_bits, DELTAT_LSF)); flag_iono_valid = true; flag_utc_model_valid = true; @@ -435,65 +403,66 @@ int Gps_Navigation_Message::subframe_decoder(char *subframe) { // Page 25 Anti-Spoofing, SV config and almanac health (PRN: 25-32) //! \TODO Read Anti-Spoofing, SV config - almanacHealth[25] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV25)); - almanacHealth[26] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV26)); - almanacHealth[27] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV27)); - almanacHealth[28] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV28)); - almanacHealth[29] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV29)); - almanacHealth[30] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV30)); - almanacHealth[31] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV31)); - almanacHealth[32] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV32)); + almanacHealth[25] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV25)); + almanacHealth[26] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV26)); + almanacHealth[27] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV27)); + almanacHealth[28] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV28)); + almanacHealth[29] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV29)); + almanacHealth[30] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV30)); + almanacHealth[31] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV31)); + almanacHealth[32] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV32)); } - break; - case 5://--- It is subframe 5 -----------------almanac health (PRN: 1-24) and Almanac reference week number and time. - int SV_data_ID_5; - int SV_page_5; - d_TOW_SF5 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); - d_TOW_SF5 = d_TOW_SF5 * 6.0; - d_TOW = d_TOW_SF5; // Set transmission time - b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); - b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); - b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); - SV_data_ID_5 = static_cast(read_navigation_unsigned(subframe_bits, SV_DATA_ID)); - SV_page_5 = static_cast(read_navigation_unsigned(subframe_bits, SV_PAGE)); - if (SV_page_5 < 25) - { - //! \TODO read almanac - if(SV_data_ID_5){} - } - if (SV_page_5 == 51) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110) - { - d_Toa = static_cast(read_navigation_unsigned(subframe_bits, T_OA)); - d_Toa = d_Toa * T_OA_LSB; - i_WN_A = static_cast(read_navigation_unsigned(subframe_bits, WN_A)); - almanacHealth[1] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV1)); - almanacHealth[2] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV2)); - almanacHealth[3] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV3)); - almanacHealth[4] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV4)); - almanacHealth[5] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV5)); - almanacHealth[6] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV6)); - almanacHealth[7] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV7)); - almanacHealth[8] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV8)); - almanacHealth[9] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV9)); - almanacHealth[10] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV10)); - almanacHealth[11] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV11)); - almanacHealth[12] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV12)); - almanacHealth[13] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV13)); - almanacHealth[14] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV14)); - almanacHealth[15] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV15)); - almanacHealth[16] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV16)); - almanacHealth[17] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV17)); - almanacHealth[18] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV18)); - almanacHealth[19] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV19)); - almanacHealth[20] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV20)); - almanacHealth[21] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV21)); - almanacHealth[22] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV22)); - almanacHealth[23] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV23)); - almanacHealth[24] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV24)); - } - break; + case 5: //--- It is subframe 5 -----------------almanac health (PRN: 1-24) and Almanac reference week number and time. + int32_t SV_data_ID_5; + int32_t SV_page_5; + d_TOW_SF5 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); + d_TOW_SF5 = d_TOW_SF5 * 6.0; + d_TOW = d_TOW_SF5; // Set transmission time + b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); + b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); + b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); + SV_data_ID_5 = static_cast(read_navigation_unsigned(subframe_bits, SV_DATA_ID)); + SV_page_5 = static_cast(read_navigation_unsigned(subframe_bits, SV_PAGE)); + if (SV_page_5 < 25) + { + //! \TODO read almanac + if (SV_data_ID_5) + { + } + } + if (SV_page_5 == 51) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110) + { + i_Toa = static_cast(read_navigation_unsigned(subframe_bits, T_OA)); + i_Toa = i_Toa * T_OA_LSB; + i_WN_A = static_cast(read_navigation_unsigned(subframe_bits, WN_A)); + almanacHealth[1] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV1)); + almanacHealth[2] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV2)); + almanacHealth[3] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV3)); + almanacHealth[4] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV4)); + almanacHealth[5] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV5)); + almanacHealth[6] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV6)); + almanacHealth[7] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV7)); + almanacHealth[8] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV8)); + almanacHealth[9] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV9)); + almanacHealth[10] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV10)); + almanacHealth[11] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV11)); + almanacHealth[12] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV12)); + almanacHealth[13] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV13)); + almanacHealth[14] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV14)); + almanacHealth[15] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV15)); + almanacHealth[16] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV16)); + almanacHealth[17] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV17)); + almanacHealth[18] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV18)); + almanacHealth[19] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV19)); + almanacHealth[20] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV20)); + almanacHealth[21] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV21)); + almanacHealth[22] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV22)); + almanacHealth[23] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV23)); + almanacHealth[24] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV24)); + } + break; default: break; @@ -510,12 +479,12 @@ double Gps_Navigation_Message::utc_time(const double gpstime_corrected) const double Delta_t_UTC = d_DeltaT_LS + d_A0 + d_A1 * (gpstime_corrected - d_t_OT + 604800 * static_cast((i_GPS_week - i_WN_T))); // Determine if the effectivity time of the leap second event is in the past - int weeksToLeapSecondEvent = i_WN_LSF - i_GPS_week; + int32_t weeksToLeapSecondEvent = i_WN_LSF - i_GPS_week; if ((weeksToLeapSecondEvent) >= 0) // is not in the past { //Detect if the effectivity time and user's time is within six hours = 6 * 60 *60 = 21600 s - int secondOfLeapSecondEvent = i_DN * 24 * 60 * 60; + int32_t secondOfLeapSecondEvent = i_DN * 24 * 60 * 60; if (weeksToLeapSecondEvent > 0) { t_utc_daytime = fmod(gpstime_corrected - Delta_t_UTC, 86400); @@ -541,7 +510,7 @@ double Gps_Navigation_Message::utc_time(const double gpstime_corrected) const * proper accommodation of the leap second event with a possible week number * transition is provided by the following expression for UTC: */ - int W = fmod(gpstime_corrected - Delta_t_UTC - 43200, 86400) + 43200; + int32_t W = fmod(gpstime_corrected - Delta_t_UTC - 43200, 86400) + 43200; t_utc_daytime = fmod(W, 86400 + d_DeltaT_LSF - d_DeltaT_LS); //implement something to handle a leap second event! } @@ -635,7 +604,7 @@ Gps_Iono Gps_Navigation_Message::get_iono() iono.d_beta2 = d_beta2; iono.d_beta3 = d_beta3; iono.valid = flag_iono_valid; - //WARNING: We clear flag_utc_model_valid in order to not re-send the same information to the ionospheric parameters queue + // WARNING: We clear flag_utc_model_valid in order to not re-send the same information to the ionospheric parameters queue flag_iono_valid = false; return iono; } diff --git a/src/core/system_parameters/gps_navigation_message.h b/src/core/system_parameters/gps_navigation_message.h index ba3312efa..595d74d30 100644 --- a/src/core/system_parameters/gps_navigation_message.h +++ b/src/core/system_parameters/gps_navigation_message.h @@ -39,6 +39,7 @@ #include "gps_almanac.h" #include "gps_utc_model.h" #include +#include #include #include #include @@ -53,70 +54,66 @@ class Gps_Navigation_Message { private: - unsigned long int read_navigation_unsigned(std::bitset bits, const std::vector> parameter); - signed long int read_navigation_signed(std::bitset bits, const std::vector> parameter); - bool read_navigation_bool(std::bitset bits, const std::vector> parameter); - void print_gps_word_bytes(unsigned int GPS_word); + uint64_t read_navigation_unsigned(std::bitset bits, const std::vector> parameter); + int64_t read_navigation_signed(std::bitset bits, const std::vector> parameter); + bool read_navigation_bool(std::bitset bits, const std::vector> parameter); + void print_gps_word_bytes(uint32_t GPS_word); public: bool b_valid_ephemeris_set_flag; // flag indicating that this ephemeris set have passed the validation check - //broadcast orbit 1 + // broadcast orbit 1 double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s] double d_TOW_SF1; //!< Time of GPS Week from HOW word of Subframe 1 [s] double d_TOW_SF2; //!< Time of GPS Week from HOW word of Subframe 2 [s] double d_TOW_SF3; //!< Time of GPS Week from HOW word of Subframe 3 [s] double d_TOW_SF4; //!< Time of GPS Week from HOW word of Subframe 4 [s] double d_TOW_SF5; //!< Time of GPS Week from HOW word of Subframe 5 [s] - double d_IODE_SF2; double d_IODE_SF3; double d_Crs; //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m] double d_Delta_n; //!< Mean Motion Difference From Computed Value [semi-circles/s] double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles] - //broadcast orbit 2 + // broadcast orbit 2 double d_Cuc; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] double d_e_eccentricity; //!< Eccentricity [dimensionless] double d_Cus; //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad] double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)] - //broadcast orbit 3 + // broadcast orbit 3 double d_Toe; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] double d_Toc; //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s] double d_Cic; //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad] double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] double d_Cis; //!< Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad] - //broadcast orbit 4 + // broadcast orbit 4 double d_i_0; //!< Inclination Angle at Reference Time [semi-circles] double d_Crc; //!< Amplitude of the Cosine Harmonic Correction Term to the Orbit Radius [m] double d_OMEGA; //!< Argument of Perigee [semi-cicles] double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s] - //broadcast orbit 5 + // broadcast orbit 5 double d_IDOT; //!< Rate of Inclination Angle [semi-circles/s] - int i_code_on_L2; //!< If 1, P code ON in L2; if 2, C/A code ON in L2; - int i_GPS_week; //!< GPS week number, aka WN [week] + int32_t i_code_on_L2; //!< If 1, P code ON in L2; if 2, C/A code ON in L2; + int32_t i_GPS_week; //!< GPS week number, aka WN [week] bool b_L2_P_data_flag; //!< When true, indicates that the NAV data stream was commanded OFF on the P-code of the L2 channel - //broadcast orbit 6 - int i_SV_accuracy; //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200E) - int i_SV_health; + // broadcast orbit 6 + int32_t i_SV_accuracy; //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200E) + int32_t i_SV_health; double d_TGD; //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s] double d_IODC; //!< Issue of Data, Clock - //broadcast orbit 7 - int i_AODO; //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] - + // broadcast orbit 7 + int32_t i_AODO; //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] bool b_fit_interval_flag; //!< indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours. double d_spare1; double d_spare2; - double d_A_f0; //!< Coefficient 0 of code phase offset model [s] double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s] double d_A_f2; //!< Coefficient 2 of code phase offset model [s/s^2] - // Almanac - double d_Toa; //!< Almanac reference time [s] - int i_WN_A; //!< Modulo 256 of the GPS week number to which the almanac reference time (d_Toa) is referenced - std::map almanacHealth; //!< Map that stores the health information stored in the almanac + int32_t i_Toa; //!< Almanac reference time [s] + int32_t i_WN_A; //!< Modulo 256 of the GPS week number to which the almanac reference time (i_Toa) is referenced + std::map almanacHealth; //!< Map that stores the health information stored in the almanac - std::map satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus + std::map satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus // Flags @@ -146,11 +143,11 @@ public: double d_satpos_Z; //!< Earth-fixed coordinate z of the satellite [m]. The direction of the IERS (International Earth Rotation and Reference Systems Service) Reference Pole (IRP). // satellite identification info - int i_channel_ID; - unsigned int i_satellite_PRN; + int32_t i_channel_ID; + uint32_t i_satellite_PRN; // time synchro - double d_subframe_timestamp_ms; //[ms] + double d_subframe_timestamp_ms; // [ms] // Ionospheric parameters bool flag_iono_valid; //!< If set, it indicates that the ionospheric parameters are filled (page 18 has arrived and decoded) @@ -168,10 +165,10 @@ public: double d_A1; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s/s] double d_A0; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s] double d_t_OT; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200E) [s] - int i_WN_T; //!< UTC reference week number [weeks] + int32_t i_WN_T; //!< UTC reference week number [weeks] double d_DeltaT_LS; //!< delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac. - int i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks] - int i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days] + int32_t i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks] + int32_t i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days] double d_DeltaT_LSF; //!< Scheduled future or recent past (relative to NAV message upload) value of the delta time due to leap seconds [s] // Satellite velocity @@ -201,7 +198,7 @@ public: /*! * \brief Decodes the GPS NAV message */ - int subframe_decoder(char *subframe); + int32_t subframe_decoder(char *subframe); /*! * \brief Computes the Coordinated Universal Time (UTC) and diff --git a/src/core/system_parameters/gps_utc_model.cc b/src/core/system_parameters/gps_utc_model.cc index ffe1af6f5..0f9a5744e 100644 --- a/src/core/system_parameters/gps_utc_model.cc +++ b/src/core/system_parameters/gps_utc_model.cc @@ -35,34 +35,35 @@ Gps_Utc_Model::Gps_Utc_Model() { valid = false; - d_A1 = 0; - d_A0 = 0; - d_t_OT = 0; + d_A1 = 0.0; + d_A0 = 0.0; + d_t_OT = 0.0; i_WN_T = 0; - d_DeltaT_LS = 0; + d_DeltaT_LS = 0.0; i_WN_LSF = 0; i_DN = 0; - d_DeltaT_LSF = 0; + d_DeltaT_LSF = 0.0; } -double Gps_Utc_Model::utc_time(double gpstime_corrected, int i_GPS_week) + +double Gps_Utc_Model::utc_time(double gpstime_corrected, int32_t i_GPS_week) { double t_utc; double t_utc_daytime; double Delta_t_UTC = d_DeltaT_LS + d_A0 + d_A1 * (gpstime_corrected - d_t_OT + 604800 * static_cast(i_GPS_week - i_WN_T)); // Determine if the effectivity time of the leap second event is in the past - int weeksToLeapSecondEvent = i_WN_LSF - i_GPS_week; + int32_t weeksToLeapSecondEvent = i_WN_LSF - i_GPS_week; if (weeksToLeapSecondEvent >= 0) // is not in the past { - //Detect if the effectivity time and user's time is within six hours = 6 * 60 *60 = 21600 s - int secondOfLeapSecondEvent = i_DN * 24 * 60 * 60; + // Detect if the effectivity time and user's time is within six hours = 6 * 60 *60 = 21600 s + int32_t secondOfLeapSecondEvent = i_DN * 24 * 60 * 60; if (weeksToLeapSecondEvent > 0) { t_utc_daytime = fmod(gpstime_corrected - Delta_t_UTC, 86400); } - else //we are in the same week than the leap second event + else // we are in the same week than the leap second event { if (std::abs(gpstime_corrected - secondOfLeapSecondEvent) > 21600) { @@ -83,9 +84,9 @@ double Gps_Utc_Model::utc_time(double gpstime_corrected, int i_GPS_week) * proper accommodation of the leap second event with a possible week number * transition is provided by the following expression for UTC: */ - int W = fmod(gpstime_corrected - Delta_t_UTC - 43200, 86400) + 43200; + int32_t W = fmod(gpstime_corrected - Delta_t_UTC - 43200, 86400) + 43200; t_utc_daytime = fmod(W, 86400 + d_DeltaT_LSF - d_DeltaT_LS); - //implement something to handle a leap second event! + // implement something to handle a leap second event! } if ((gpstime_corrected - secondOfLeapSecondEvent) > 21600) { diff --git a/src/core/system_parameters/gps_utc_model.h b/src/core/system_parameters/gps_utc_model.h index ede2c1e67..e037aff99 100644 --- a/src/core/system_parameters/gps_utc_model.h +++ b/src/core/system_parameters/gps_utc_model.h @@ -32,9 +32,8 @@ #ifndef GNSS_SDR_GPS_UTC_MODEL_H_ #define GNSS_SDR_GPS_UTC_MODEL_H_ -#include #include - +#include /*! * \brief This class is a storage for the GPS UTC MODEL data as described in IS-GPS-200E @@ -49,10 +48,10 @@ public: double d_A1; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s/s] double d_A0; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s] double d_t_OT; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200E) [s] - int i_WN_T; //!< UTC reference week number [weeks] + int32_t i_WN_T; //!< UTC reference week number [weeks] double d_DeltaT_LS; //!< delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac. - int i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks] - int i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days] + int32_t i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks] + int32_t i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days] double d_DeltaT_LSF; //!< Scheduled future or recent past (relative to NAV message upload) value of the delta time due to leap seconds [s] /*! @@ -64,7 +63,7 @@ public: /* * \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file. */ - inline void serialize(Archive& archive, const unsigned int version) + inline void serialize(Archive& archive, const uint32_t version) { using boost::serialization::make_nvp; if (version) @@ -85,7 +84,7 @@ public: * \brief Computes the Coordinated Universal Time (UTC) and * returns it in [s] (IS-GPS-200E, 20.3.3.5.2.4) */ - double utc_time(double gpstime_corrected, int i_GPS_week); + double utc_time(double gpstime_corrected, int32_t i_GPS_week); }; #endif diff --git a/src/core/system_parameters/rtcm.cc b/src/core/system_parameters/rtcm.cc index 8f337f802..24d3417ce 100644 --- a/src/core/system_parameters/rtcm.cc +++ b/src/core/system_parameters/rtcm.cc @@ -46,7 +46,7 @@ using google::LogMessage; -Rtcm::Rtcm(unsigned short port) +Rtcm::Rtcm(uint16_t port) { RTCM_port = port; preamble = std::bitset<8>("11010011"); @@ -141,9 +141,9 @@ std::string Rtcm::add_CRC(const std::string& message_without_crc) const { // ****** Computes Qualcomm CRC-24Q ****** boost::crc_optimal<24, 0x1864CFBu, 0x0, 0x0, false, false> CRC_RTCM; - // 1) Converts the string to a vector of unsigned char: - boost::dynamic_bitset frame_bits(message_without_crc); - std::vector bytes; + // 1) Converts the string to a vector of uint8_t: + boost::dynamic_bitset frame_bits(message_without_crc); + std::vector bytes; boost::to_block_range(frame_bits, std::back_inserter(bytes)); std::reverse(bytes.begin(), bytes.end()); @@ -167,8 +167,8 @@ bool Rtcm::check_CRC(const std::string& message) const std::bitset<24> read_crc = std::bitset<24>(crc); std::string msg_without_crc = message_bin.substr(0, message_bin.length() - 24); - boost::dynamic_bitset frame_bits(msg_without_crc); - std::vector bytes; + boost::dynamic_bitset frame_bits(msg_without_crc); + std::vector bytes; boost::to_block_range(frame_bits, std::back_inserter(bytes)); std::reverse(bytes.begin(), bytes.end()); @@ -188,32 +188,34 @@ bool Rtcm::check_CRC(const std::string& message) const std::string Rtcm::bin_to_binary_data(const std::string& s) const { std::string s_aux; - int remainder = static_cast(std::fmod(s.length(), 8)); - unsigned char c[s.length()]; - unsigned int k = 0; + int32_t remainder = static_cast(std::fmod(s.length(), 8)); + std::vector c; + c.reserve(s.length()); + + uint32_t k = 0; if (remainder != 0) { s_aux.assign(s, 0, remainder); boost::dynamic_bitset<> rembits(s_aux); - unsigned long int n = rembits.to_ulong(); - c[0] = static_cast(n); + uint64_t n = rembits.to_ulong(); + c[0] = static_cast(n); k++; } - unsigned int start = std::max(remainder, 0); - for (unsigned int i = start; i < s.length() - 1; i = i + 8) + uint32_t start = std::max(remainder, 0); + for (uint32_t i = start; i < s.length() - 1; i = i + 8) { s_aux.assign(s, i, 4); std::bitset<4> bs(s_aux); - unsigned n = bs.to_ulong(); + uint32_t n = bs.to_ulong(); s_aux.assign(s, i + 4, 4); std::bitset<4> bs2(s_aux); - unsigned n2 = bs2.to_ulong(); - c[k] = static_cast(n * 16) + static_cast(n2); + uint32_t n2 = bs2.to_ulong(); + c[k] = static_cast(n * 16) + static_cast(n2); k++; } - std::string ret(c, c + k / sizeof(c[0])); + std::string ret(c.begin(), c.begin() + k); return ret; } @@ -223,9 +225,9 @@ std::string Rtcm::binary_data_to_bin(const std::string& s) const std::string s_aux; std::stringstream ss; - for (unsigned int i = 0; i < s.length(); i++) + for (uint32_t i = 0; i < s.length(); i++) { - unsigned char val = static_cast(s.at(i)); + uint8_t val = static_cast(s.at(i)); std::bitset<8> bs(val); ss << bs; } @@ -239,22 +241,22 @@ std::string Rtcm::bin_to_hex(const std::string& s) const { std::string s_aux; std::stringstream ss; - int remainder = static_cast(std::fmod(s.length(), 4)); + int32_t remainder = static_cast(std::fmod(s.length(), 4)); if (remainder != 0) { s_aux.assign(s, 0, remainder); boost::dynamic_bitset<> rembits(s_aux); - unsigned n = rembits.to_ulong(); + uint32_t n = rembits.to_ulong(); ss << std::hex << n; } - unsigned int start = std::max(remainder, 0); - for (unsigned int i = start; i < s.length() - 1; i = i + 4) + uint32_t start = std::max(remainder, 0); + for (uint32_t i = start; i < s.length() - 1; i = i + 4) { s_aux.assign(s, i, 4); std::bitset<4> bs(s_aux); - unsigned n = bs.to_ulong(); + uint32_t n = bs.to_ulong(); ss << std::hex << n; } return boost::to_upper_copy(ss.str()); @@ -268,9 +270,9 @@ std::string Rtcm::hex_to_bin(const std::string& s) const std::stringstream ss; ss << s; std::string s_lower = boost::to_upper_copy(ss.str()); - for (unsigned int i = 0; i < s.length(); i++) + for (uint32_t i = 0; i < s.length(); i++) { - unsigned long int n; + uint64_t n; std::istringstream(s_lower.substr(i, 1)) >> std::hex >> n; std::bitset<4> bs(n); s_aux += bs.to_string(); @@ -279,26 +281,26 @@ std::string Rtcm::hex_to_bin(const std::string& s) const } -unsigned long int Rtcm::bin_to_uint(const std::string& s) const +uint32_t Rtcm::bin_to_uint(const std::string& s) const { if (s.length() > 32) { - LOG(WARNING) << "Cannot convert to a unsigned long int"; + LOG(WARNING) << "Cannot convert to a uint32_t"; return 0; } - unsigned long int reading = strtoul(s.c_str(), NULL, 2); + uint32_t reading = strtoul(s.c_str(), NULL, 2); return reading; } -long int Rtcm::bin_to_int(const std::string& s) const +int32_t Rtcm::bin_to_int(const std::string& s) const { if (s.length() > 32) { - LOG(WARNING) << "Cannot convert to a long int"; + LOG(WARNING) << "Cannot convert to a int32_t"; return 0; } - long int reading; + int32_t reading; // Handle negative numbers if (s.substr(0, 1).compare("0")) @@ -316,15 +318,15 @@ long int Rtcm::bin_to_int(const std::string& s) const } -long int Rtcm::bin_to_sint(const std::string& s) const +int32_t Rtcm::bin_to_sint(const std::string& s) const { if (s.length() > 32) { - LOG(WARNING) << "Cannot convert to a long int"; + LOG(WARNING) << "Cannot convert to a int32_t"; return 0; } - long int reading; - long int sign; + int32_t reading; + int32_t sign; // Check for sign bit as defined RTCM doc if (s.substr(0, 1).compare("0") == 0) @@ -343,7 +345,7 @@ long int Rtcm::bin_to_sint(const std::string& s) const } // Find the sign for glonass data fields (neg = 1, pos = 0) -static inline unsigned long glo_sgn(double val) +static inline uint64_t glo_sgn(double val) { if (val < 0) return 1; // If value is negative return 1 if (val == 0) return 0; // Positive or equal to zero return 0 @@ -360,7 +362,7 @@ double Rtcm::bin_to_double(const std::string& s) const return 0; } - long long int reading_int; + int64_t reading_int; // Handle negative numbers if (s.substr(0, 1).compare("0")) @@ -382,36 +384,36 @@ double Rtcm::bin_to_double(const std::string& s) const } -unsigned long int Rtcm::hex_to_uint(const std::string& s) const +uint64_t Rtcm::hex_to_uint(const std::string& s) const { if (s.length() > 32) { - LOG(WARNING) << "Cannot convert to a unsigned long int"; + LOG(WARNING) << "Cannot convert to a uint64_t"; return 0; } - unsigned long int reading = strtoul(s.c_str(), NULL, 16); + uint64_t reading = strtoul(s.c_str(), NULL, 16); return reading; } -long int Rtcm::hex_to_int(const std::string& s) const +int64_t Rtcm::hex_to_int(const std::string& s) const { if (s.length() > 32) { - LOG(WARNING) << "Cannot convert to a long int"; + LOG(WARNING) << "Cannot convert to a int64_t"; return 0; } - long int reading = strtol(s.c_str(), NULL, 16); + int64_t reading = strtol(s.c_str(), NULL, 16); return reading; } std::string Rtcm::build_message(const std::string& data) const { - unsigned int msg_length_bits = data.length(); - unsigned int msg_length_bytes = std::ceil(static_cast(msg_length_bits) / 8.0); + uint32_t msg_length_bits = data.length(); + uint32_t msg_length_bytes = std::ceil(static_cast(msg_length_bits) / 8.0); std::bitset<10> message_length = std::bitset<10>(msg_length_bytes); - unsigned int zeros_to_fill = 8 * msg_length_bytes - msg_length_bits; + uint32_t zeros_to_fill = 8 * msg_length_bytes - msg_length_bits; std::string b(zeros_to_fill, '0'); std::string msg_content = data + b; std::string msg_without_crc = preamble.to_string() + @@ -435,14 +437,14 @@ std::string Rtcm::build_message(const std::string& data) const // // ******************************************************** -std::bitset<64> Rtcm::get_MT1001_4_header(unsigned int msg_number, double obs_time, const std::map& observables, - unsigned int ref_id, unsigned int smooth_int, bool sync_flag, bool divergence_free) +std::bitset<64> Rtcm::get_MT1001_4_header(uint32_t msg_number, double obs_time, const std::map& observables, + uint32_t ref_id, uint32_t smooth_int, bool sync_flag, bool divergence_free) { - unsigned int reference_station_id = ref_id; // Max: 4095 - const std::map observables_ = observables; + uint32_t reference_station_id = ref_id; // Max: 4095 + const std::map observables_ = observables; bool synchronous_GNSS_flag = sync_flag; bool divergence_free_smoothing_indicator = divergence_free; - unsigned int smoothing_interval = smooth_int; + uint32_t smoothing_interval = smooth_int; Rtcm::set_DF002(msg_number); Rtcm::set_DF003(reference_station_id); Rtcm::set_DF004(obs_time); @@ -484,16 +486,16 @@ std::bitset<58> Rtcm::get_MT1001_sat_content(const Gps_Ephemeris& eph, double ob } -std::string Rtcm::print_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables, unsigned short station_id) +std::string Rtcm::print_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables, uint16_t station_id) { - unsigned int ref_id = static_cast(station_id); - unsigned int smooth_int = 0; + uint32_t ref_id = static_cast(station_id); + uint32_t smooth_int = 0; bool sync_flag = false; bool divergence_free = false; //Get a map with GPS L1 only observations - std::map observablesL1; - std::map::const_iterator observables_iter; + std::map observablesL1; + std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); observables_iter != observables.cend(); @@ -503,7 +505,7 @@ std::string Rtcm::print_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, co std::string sig_(observables_iter->second.Signal); if ((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) { - observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); } } @@ -533,16 +535,16 @@ std::string Rtcm::print_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, co // // ******************************************************** -std::string Rtcm::print_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables, unsigned short station_id) +std::string Rtcm::print_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables, uint16_t station_id) { - unsigned int ref_id = static_cast(station_id); - unsigned int smooth_int = 0; + uint32_t ref_id = static_cast(station_id); + uint32_t smooth_int = 0; bool sync_flag = false; bool divergence_free = false; //Get a map with GPS L1 only observations - std::map observablesL1; - std::map::const_iterator observables_iter; + std::map observablesL1; + std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); observables_iter != observables.cend(); @@ -552,7 +554,7 @@ std::string Rtcm::print_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, co std::string sig_(observables_iter->second.Signal); if ((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) { - observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); } } @@ -604,18 +606,18 @@ std::bitset<74> Rtcm::get_MT1002_sat_content(const Gps_Ephemeris& eph, double ob // // ******************************************************** -std::string Rtcm::print_MT1003(const Gps_Ephemeris& ephL1, const Gps_CNAV_Ephemeris& ephL2, double obs_time, const std::map& observables, unsigned short station_id) +std::string Rtcm::print_MT1003(const Gps_Ephemeris& ephL1, const Gps_CNAV_Ephemeris& ephL2, double obs_time, const std::map& observables, uint16_t station_id) { - unsigned int ref_id = static_cast(station_id); - unsigned int smooth_int = 0; + uint32_t ref_id = static_cast(station_id); + uint32_t smooth_int = 0; bool sync_flag = false; bool divergence_free = false; //Get maps with GPS L1 and L2 observations - std::map observablesL1; - std::map observablesL2; - std::map::const_iterator observables_iter; - std::map::const_iterator observables_iter2; + std::map observablesL1; + std::map observablesL2; + std::map::const_iterator observables_iter; + std::map::const_iterator observables_iter2; for (observables_iter = observables.cbegin(); observables_iter != observables.cend(); @@ -625,24 +627,24 @@ std::string Rtcm::print_MT1003(const Gps_Ephemeris& ephL1, const Gps_CNAV_Epheme std::string sig_(observables_iter->second.Signal); if ((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) { - observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) { - observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); } } // Get common observables std::vector > common_observables; std::vector >::const_iterator common_observables_iter; - std::map observablesL1_with_L2; + std::map observablesL1_with_L2; for (observables_iter = observablesL1.cbegin(); observables_iter != observablesL1.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; + uint32_t prn_ = observables_iter->second.PRN; for (observables_iter2 = observablesL2.cbegin(); observables_iter2 != observablesL2.cend(); observables_iter2++) @@ -654,7 +656,7 @@ std::string Rtcm::print_MT1003(const Gps_Ephemeris& ephL1, const Gps_CNAV_Epheme Gnss_Synchro pr2 = observables_iter2->second; p = std::make_pair(pr1, pr2); common_observables.push_back(p); - observablesL1_with_L2.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1_with_L2.insert(std::pair(observables_iter->first, observables_iter->second)); } } } @@ -713,18 +715,18 @@ std::bitset<101> Rtcm::get_MT1003_sat_content(const Gps_Ephemeris& ephL1, const // // ****************************************************************** -std::string Rtcm::print_MT1004(const Gps_Ephemeris& ephL1, const Gps_CNAV_Ephemeris& ephL2, double obs_time, const std::map& observables, unsigned short station_id) +std::string Rtcm::print_MT1004(const Gps_Ephemeris& ephL1, const Gps_CNAV_Ephemeris& ephL2, double obs_time, const std::map& observables, uint16_t station_id) { - unsigned int ref_id = static_cast(station_id); - unsigned int smooth_int = 0; + uint32_t ref_id = static_cast(station_id); + uint32_t smooth_int = 0; bool sync_flag = false; bool divergence_free = false; //Get maps with GPS L1 and L2 observations - std::map observablesL1; - std::map observablesL2; - std::map::const_iterator observables_iter; - std::map::const_iterator observables_iter2; + std::map observablesL1; + std::map observablesL2; + std::map::const_iterator observables_iter; + std::map::const_iterator observables_iter2; for (observables_iter = observables.cbegin(); observables_iter != observables.cend(); @@ -734,24 +736,24 @@ std::string Rtcm::print_MT1004(const Gps_Ephemeris& ephL1, const Gps_CNAV_Epheme std::string sig_(observables_iter->second.Signal); if ((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) { - observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) { - observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); } } // Get common observables std::vector > common_observables; std::vector >::const_iterator common_observables_iter; - std::map observablesL1_with_L2; + std::map observablesL1_with_L2; for (observables_iter = observablesL1.cbegin(); observables_iter != observablesL1.cend(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; + uint32_t prn_ = observables_iter->second.PRN; for (observables_iter2 = observablesL2.cbegin(); observables_iter2 != observablesL2.cend(); observables_iter2++) @@ -763,7 +765,7 @@ std::string Rtcm::print_MT1004(const Gps_Ephemeris& ephL1, const Gps_CNAV_Epheme Gnss_Synchro pr2 = observables_iter2->second; p = std::make_pair(pr1, pr2); common_observables.push_back(p); - observablesL1_with_L2.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1_with_L2.insert(std::pair(observables_iter->first, observables_iter->second)); } } } @@ -840,11 +842,11 @@ std::bitset<125> Rtcm::get_MT1004_sat_content(const Gps_Ephemeris& ephL1, const */ std::bitset<152> Rtcm::get_MT1005_test() { - unsigned int mt1005 = 1005; - unsigned int reference_station_id = 2003; // Max: 4095 - double ECEF_X = 1114104.5999; // units: m - double ECEF_Y = -4850729.7108; // units: m - double ECEF_Z = 3975521.4643; // units: m + uint32_t mt1005 = 1005; + uint32_t reference_station_id = 2003; // Max: 4095 + double ECEF_X = 1114104.5999; // units: m + double ECEF_Y = -4850729.7108; // units: m + double ECEF_Z = 3975521.4643; // units: m std::bitset<1> DF001_; @@ -881,9 +883,9 @@ std::bitset<152> Rtcm::get_MT1005_test() } -std::string Rtcm::print_MT1005(unsigned int ref_id, double ecef_x, double ecef_y, double ecef_z, bool gps, bool glonass, bool galileo, bool non_physical, bool single_oscillator, unsigned int quarter_cycle_indicator) +std::string Rtcm::print_MT1005(uint32_t ref_id, double ecef_x, double ecef_y, double ecef_z, bool gps, bool glonass, bool galileo, bool non_physical, bool single_oscillator, uint32_t quarter_cycle_indicator) { - unsigned int msg_number = 1005; + uint32_t msg_number = 1005; std::bitset<1> DF001_; Rtcm::set_DF002(msg_number); @@ -923,7 +925,7 @@ std::string Rtcm::print_MT1005(unsigned int ref_id, double ecef_x, double ecef_y } -int Rtcm::read_MT1005(const std::string& message, unsigned int& ref_id, double& ecef_x, double& ecef_y, double& ecef_z, bool& gps, bool& glonass, bool& galileo) +int32_t Rtcm::read_MT1005(const std::string& message, uint32_t& ref_id, double& ecef_x, double& ecef_y, double& ecef_z, bool& gps, bool& glonass, bool& galileo) { // Convert message to binary std::string message_bin = Rtcm::binary_data_to_bin(message); @@ -935,11 +937,11 @@ int Rtcm::read_MT1005(const std::string& message, unsigned int& ref_id, double& } // Check than the message number is correct - unsigned int preamble_length = 8; - unsigned int reserved_field_length = 6; - unsigned int index = preamble_length + reserved_field_length; + uint32_t preamble_length = 8; + uint32_t reserved_field_length = 6; + uint32_t index = preamble_length + reserved_field_length; - unsigned int read_message_length = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); + uint32_t read_message_length = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); index += 10; if (read_message_length != 19) { @@ -947,7 +949,7 @@ int Rtcm::read_MT1005(const std::string& message, unsigned int& ref_id, double& return 1; } - unsigned int msg_number = 1005; + uint32_t msg_number = 1005; Rtcm::set_DF002(msg_number); std::bitset<12> read_msg_number(message_bin.substr(index, 12)); index += 12; @@ -1002,9 +1004,9 @@ std::string Rtcm::print_MT1005_test() // // ******************************************************** -std::string Rtcm::print_MT1006(unsigned int ref_id, double ecef_x, double ecef_y, double ecef_z, bool gps, bool glonass, bool galileo, bool non_physical, bool single_oscillator, unsigned int quarter_cycle_indicator, double height) +std::string Rtcm::print_MT1006(uint32_t ref_id, double ecef_x, double ecef_y, double ecef_z, bool gps, bool glonass, bool galileo, bool non_physical, bool single_oscillator, uint32_t quarter_cycle_indicator, double height) { - unsigned int msg_number = 1006; + uint32_t msg_number = 1006; std::bitset<1> DF001_; Rtcm::set_DF002(msg_number); @@ -1051,13 +1053,13 @@ std::string Rtcm::print_MT1006(unsigned int ref_id, double ecef_x, double ecef_y // MESSAGE TYPE 1008 (ANTENNA DESCRIPTOR & SERIAL NUMBER) // // ******************************************************** -std::string Rtcm::print_MT1008(unsigned int ref_id, const std::string& antenna_descriptor, unsigned int antenna_setup_id, const std::string& antenna_serial_number) +std::string Rtcm::print_MT1008(uint32_t ref_id, const std::string& antenna_descriptor, uint32_t antenna_setup_id, const std::string& antenna_serial_number) { - unsigned int msg_number = 1008; + uint32_t msg_number = 1008; std::bitset<12> DF002_ = std::bitset<12>(msg_number); Rtcm::set_DF003(ref_id); std::string ant_descriptor = antenna_descriptor; - unsigned int len = ant_descriptor.length(); + uint32_t len = ant_descriptor.length(); if (len > 31) { ant_descriptor = ant_descriptor.substr(0, 31); @@ -1076,7 +1078,7 @@ std::string Rtcm::print_MT1008(unsigned int ref_id, const std::string& antenna_d Rtcm::set_DF031(antenna_setup_id); std::string ant_sn(antenna_serial_number); - unsigned int len2 = ant_sn.length(); + uint32_t len2 = ant_sn.length(); if (len2 > 31) { ant_sn = ant_sn.substr(0, 31); @@ -1114,14 +1116,14 @@ std::string Rtcm::print_MT1008(unsigned int ref_id, const std::string& antenna_d // MESSAGE TYPE 1009 (GLONASS L1 Basic RTK Observables) // // ******************************************************** -std::bitset<61> Rtcm::get_MT1009_12_header(unsigned int msg_number, double obs_time, const std::map& observables, - unsigned int ref_id, unsigned int smooth_int, bool sync_flag, bool divergence_free) +std::bitset<61> Rtcm::get_MT1009_12_header(uint32_t msg_number, double obs_time, const std::map& observables, + uint32_t ref_id, uint32_t smooth_int, bool sync_flag, bool divergence_free) { - unsigned int reference_station_id = ref_id; // Max: 4095 - const std::map observables_ = observables; + uint32_t reference_station_id = ref_id; // Max: 4095 + const std::map observables_ = observables; bool synchronous_GNSS_flag = sync_flag; bool divergence_free_smoothing_indicator = divergence_free; - unsigned int smoothing_interval = smooth_int; + uint32_t smoothing_interval = smooth_int; Rtcm::set_DF002(msg_number); Rtcm::set_DF003(reference_station_id); Rtcm::set_DF034(obs_time); @@ -1165,16 +1167,16 @@ std::bitset<64> Rtcm::get_MT1009_sat_content(const Glonass_Gnav_Ephemeris& eph, } -std::string Rtcm::print_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables, unsigned short station_id) +std::string Rtcm::print_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables, uint16_t station_id) { - unsigned int ref_id = static_cast(station_id); - unsigned int smooth_int = 0; + uint32_t ref_id = static_cast(station_id); + uint32_t smooth_int = 0; bool sync_flag = false; bool divergence_free = false; //Get a map with GLONASS L1 only observations - std::map observablesL1; - std::map::const_iterator observables_iter; + std::map observablesL1; + std::map::const_iterator observables_iter; for (observables_iter = observables.begin(); observables_iter != observables.end(); @@ -1184,7 +1186,7 @@ std::string Rtcm::print_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, d std::string sig_(observables_iter->second.Signal); if ((system_.compare("R") == 0) && (sig_.compare("1C") == 0)) { - observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); } } @@ -1214,16 +1216,16 @@ std::string Rtcm::print_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, d // // ******************************************************** -std::string Rtcm::print_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables, unsigned short station_id) +std::string Rtcm::print_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables, uint16_t station_id) { - unsigned int ref_id = static_cast(station_id); - unsigned int smooth_int = 0; + uint32_t ref_id = static_cast(station_id); + uint32_t smooth_int = 0; bool sync_flag = false; bool divergence_free = false; //Get a map with GPS L1 only observations - std::map observablesL1; - std::map::const_iterator observables_iter; + std::map observablesL1; + std::map::const_iterator observables_iter; for (observables_iter = observables.begin(); observables_iter != observables.end(); @@ -1233,7 +1235,7 @@ std::string Rtcm::print_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, d std::string sig_(observables_iter->second.Signal); if ((system_.compare("R") == 0) && (sig_.compare("1C") == 0)) { - observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); } } @@ -1289,18 +1291,18 @@ std::bitset<79> Rtcm::get_MT1010_sat_content(const Glonass_Gnav_Ephemeris& eph, // // ******************************************************** -std::string Rtcm::print_MT1011(const Glonass_Gnav_Ephemeris& ephL1, const Glonass_Gnav_Ephemeris& ephL2, double obs_time, const std::map& observables, unsigned short station_id) +std::string Rtcm::print_MT1011(const Glonass_Gnav_Ephemeris& ephL1, const Glonass_Gnav_Ephemeris& ephL2, double obs_time, const std::map& observables, uint16_t station_id) { - unsigned int ref_id = static_cast(station_id); - unsigned int smooth_int = 0; + uint32_t ref_id = static_cast(station_id); + uint32_t smooth_int = 0; bool sync_flag = false; bool divergence_free = false; //Get maps with GPS L1 and L2 observations - std::map observablesL1; - std::map observablesL2; - std::map::const_iterator observables_iter; - std::map::const_iterator observables_iter2; + std::map observablesL1; + std::map observablesL2; + std::map::const_iterator observables_iter; + std::map::const_iterator observables_iter2; for (observables_iter = observables.begin(); observables_iter != observables.end(); @@ -1310,24 +1312,24 @@ std::string Rtcm::print_MT1011(const Glonass_Gnav_Ephemeris& ephL1, const Glonas std::string sig_(observables_iter->second.Signal); if ((system_.compare("R") == 0) && (sig_.compare("1C") == 0)) { - observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("R") == 0) && (sig_.compare("2C") == 0)) { - observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); } } // Get common observables std::vector > common_observables; std::vector >::const_iterator common_observables_iter; - std::map observablesL1_with_L2; + std::map observablesL1_with_L2; for (observables_iter = observablesL1.begin(); observables_iter != observablesL1.end(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; + uint32_t prn_ = observables_iter->second.PRN; for (observables_iter2 = observablesL2.begin(); observables_iter2 != observablesL2.end(); observables_iter2++) @@ -1339,7 +1341,7 @@ std::string Rtcm::print_MT1011(const Glonass_Gnav_Ephemeris& ephL1, const Glonas Gnss_Synchro pr2 = observables_iter2->second; p = std::make_pair(pr1, pr2); common_observables.push_back(p); - observablesL1_with_L2.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1_with_L2.insert(std::pair(observables_iter->first, observables_iter->second)); } } } @@ -1400,18 +1402,18 @@ std::bitset<107> Rtcm::get_MT1011_sat_content(const Glonass_Gnav_Ephemeris& ephL // // ****************************************************************** -std::string Rtcm::print_MT1012(const Glonass_Gnav_Ephemeris& ephL1, const Glonass_Gnav_Ephemeris& ephL2, double obs_time, const std::map& observables, unsigned short station_id) +std::string Rtcm::print_MT1012(const Glonass_Gnav_Ephemeris& ephL1, const Glonass_Gnav_Ephemeris& ephL2, double obs_time, const std::map& observables, uint16_t station_id) { - unsigned int ref_id = static_cast(station_id); - unsigned int smooth_int = 0; + uint32_t ref_id = static_cast(station_id); + uint32_t smooth_int = 0; bool sync_flag = false; bool divergence_free = false; //Get maps with GLONASS L1 and L2 observations - std::map observablesL1; - std::map observablesL2; - std::map::const_iterator observables_iter; - std::map::const_iterator observables_iter2; + std::map observablesL1; + std::map observablesL2; + std::map::const_iterator observables_iter; + std::map::const_iterator observables_iter2; for (observables_iter = observables.begin(); observables_iter != observables.end(); @@ -1421,24 +1423,24 @@ std::string Rtcm::print_MT1012(const Glonass_Gnav_Ephemeris& ephL1, const Glonas std::string sig_(observables_iter->second.Signal); if ((system_.compare("R") == 0) && (sig_.compare("1C") == 0)) { - observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1.insert(std::pair(observables_iter->first, observables_iter->second)); } if ((system_.compare("R") == 0) && (sig_.compare("2C") == 0)) { - observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL2.insert(std::pair(observables_iter->first, observables_iter->second)); } } // Get common observables std::vector > common_observables; std::vector >::const_iterator common_observables_iter; - std::map observablesL1_with_L2; + std::map observablesL1_with_L2; for (observables_iter = observablesL1.begin(); observables_iter != observablesL1.end(); observables_iter++) { - unsigned int prn_ = observables_iter->second.PRN; + uint32_t prn_ = observables_iter->second.PRN; for (observables_iter2 = observablesL2.begin(); observables_iter2 != observablesL2.end(); observables_iter2++) @@ -1450,7 +1452,7 @@ std::string Rtcm::print_MT1012(const Glonass_Gnav_Ephemeris& ephL1, const Glonas Gnss_Synchro pr2 = observables_iter2->second; p = std::make_pair(pr1, pr2); common_observables.push_back(p); - observablesL1_with_L2.insert(std::pair(observables_iter->first, observables_iter->second)); + observablesL1_with_L2.insert(std::pair(observables_iter->first, observables_iter->second)); } } } @@ -1519,7 +1521,7 @@ std::bitset<130> Rtcm::get_MT1012_sat_content(const Glonass_Gnav_Ephemeris& ephL std::string Rtcm::print_MT1019(const Gps_Ephemeris& gps_eph) { - unsigned int msg_number = 1019; + uint32_t msg_number = 1019; Rtcm::set_DF002(msg_number); Rtcm::set_DF009(gps_eph); @@ -1601,7 +1603,7 @@ std::string Rtcm::print_MT1019(const Gps_Ephemeris& gps_eph) } -int Rtcm::read_MT1019(const std::string& message, Gps_Ephemeris& gps_eph) +int32_t Rtcm::read_MT1019(const std::string& message, Gps_Ephemeris& gps_eph) { // Convert message to binary std::string message_bin = Rtcm::binary_data_to_bin(message); @@ -1612,11 +1614,11 @@ int Rtcm::read_MT1019(const std::string& message, Gps_Ephemeris& gps_eph) return 1; } - unsigned int preamble_length = 8; - unsigned int reserved_field_length = 6; - unsigned int index = preamble_length + reserved_field_length; + uint32_t preamble_length = 8; + uint32_t reserved_field_length = 6; + uint32_t index = preamble_length + reserved_field_length; - unsigned int read_message_length = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); + uint32_t read_message_length = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); index += 10; if (read_message_length != 61) @@ -1626,7 +1628,7 @@ int Rtcm::read_MT1019(const std::string& message, Gps_Ephemeris& gps_eph) } // Check than the message number is correct - unsigned int read_msg_number = Rtcm::bin_to_uint(message_bin.substr(index, 12)); + uint32_t read_msg_number = Rtcm::bin_to_uint(message_bin.substr(index, 12)); index += 12; if (1019 != read_msg_number) @@ -1636,16 +1638,16 @@ int Rtcm::read_MT1019(const std::string& message, Gps_Ephemeris& gps_eph) } // Fill Gps Ephemeris with message data content - gps_eph.i_satellite_PRN = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 6))); + gps_eph.i_satellite_PRN = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 6))); index += 6; - gps_eph.i_GPS_week = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); + gps_eph.i_GPS_week = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); index += 10; - gps_eph.i_SV_accuracy = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 4))); + gps_eph.i_SV_accuracy = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 4))); index += 4; - gps_eph.i_code_on_L2 = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 2))); + gps_eph.i_code_on_L2 = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 2))); index += 2; gps_eph.d_IDOT = static_cast(Rtcm::bin_to_int(message_bin.substr(index, 14))) * I_DOT_LSB; @@ -1718,7 +1720,7 @@ int Rtcm::read_MT1019(const std::string& message, Gps_Ephemeris& gps_eph) gps_eph.d_TGD = static_cast(Rtcm::bin_to_int(message_bin.substr(index, 8))) * T_GD_LSB; index += 8; - gps_eph.i_SV_health = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 6))); + gps_eph.i_SV_health = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 6))); index += 6; gps_eph.b_L2_P_data_flag = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); @@ -1738,10 +1740,10 @@ int Rtcm::read_MT1019(const std::string& message, Gps_Ephemeris& gps_eph) std::string Rtcm::print_MT1020(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) { - unsigned int msg_number = 1020; - unsigned int glonass_gnav_alm_health = 0; - unsigned int glonass_gnav_alm_health_ind = 0; - unsigned int fifth_str_additional_data_ind = 1; + uint32_t msg_number = 1020; + uint32_t glonass_gnav_alm_health = 0; + uint32_t glonass_gnav_alm_health_ind = 0; + uint32_t fifth_str_additional_data_ind = 1; Rtcm::set_DF002(msg_number); Rtcm::set_DF038(glonass_gnav_eph); @@ -1834,13 +1836,13 @@ std::string Rtcm::print_MT1020(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, c } -int Rtcm::read_MT1020(const std::string& message, Glonass_Gnav_Ephemeris& glonass_gnav_eph, Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) +int32_t Rtcm::read_MT1020(const std::string& message, Glonass_Gnav_Ephemeris& glonass_gnav_eph, Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) { // Convert message to binary std::string message_bin = Rtcm::binary_data_to_bin(message); - int glonass_gnav_alm_health = 0; - int glonass_gnav_alm_health_ind = 0; - int fifth_str_additional_data_ind = 0; + int32_t glonass_gnav_alm_health = 0; + int32_t glonass_gnav_alm_health_ind = 0; + int32_t fifth_str_additional_data_ind = 0; if (!Rtcm::check_CRC(message)) { @@ -1848,11 +1850,11 @@ int Rtcm::read_MT1020(const std::string& message, Glonass_Gnav_Ephemeris& glonas return 1; } - unsigned int preamble_length = 8; - unsigned int reserved_field_length = 6; - unsigned int index = preamble_length + reserved_field_length; + uint32_t preamble_length = 8; + uint32_t reserved_field_length = 6; + uint32_t index = preamble_length + reserved_field_length; - unsigned int read_message_length = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); + uint32_t read_message_length = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); index += 10; if (read_message_length != 45) // 360 bits = 45 bytes @@ -1862,7 +1864,7 @@ int Rtcm::read_MT1020(const std::string& message, Glonass_Gnav_Ephemeris& glonas } // Check than the message number is correct - unsigned int read_msg_number = Rtcm::bin_to_uint(message_bin.substr(index, 12)); + uint32_t read_msg_number = Rtcm::bin_to_uint(message_bin.substr(index, 12)); index += 12; if (1020 != read_msg_number) @@ -1872,19 +1874,19 @@ int Rtcm::read_MT1020(const std::string& message, Glonass_Gnav_Ephemeris& glonas } // Fill Gps Ephemeris with message data content - glonass_gnav_eph.i_satellite_slot_number = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 6))); + glonass_gnav_eph.i_satellite_slot_number = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 6))); index += 6; - glonass_gnav_eph.i_satellite_freq_channel = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 5)) - 7.0); + glonass_gnav_eph.i_satellite_freq_channel = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 5)) - 7.0); index += 5; - glonass_gnav_alm_health = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + glonass_gnav_alm_health = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); index += 1; if (glonass_gnav_alm_health) { } //Avoid comiler warning - glonass_gnav_alm_health_ind = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + glonass_gnav_alm_health_ind = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); index += 1; if (glonass_gnav_alm_health_ind) { @@ -1988,7 +1990,7 @@ int Rtcm::read_MT1020(const std::string& message, Glonass_Gnav_Ephemeris& glonas glonass_gnav_utc_model.d_tau_gps = static_cast(Rtcm::bin_to_sint(message_bin.substr(index, 22))) * TWO_N30; index += 22; - glonass_gnav_eph.d_l5th_n = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); + glonass_gnav_eph.d_l5th_n = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); } return 0; @@ -2001,16 +2003,16 @@ int Rtcm::read_MT1020(const std::string& message, Glonass_Gnav_Ephemeris& glonas // // ******************************************************** -std::string Rtcm::print_MT1029(unsigned int ref_id, const Gps_Ephemeris& gps_eph, double obs_time, const std::string& message) +std::string Rtcm::print_MT1029(uint32_t ref_id, const Gps_Ephemeris& gps_eph, double obs_time, const std::string& message) { - unsigned int msg_number = 1029; + uint32_t msg_number = 1029; Rtcm::set_DF002(msg_number); Rtcm::set_DF003(ref_id); Rtcm::set_DF051(gps_eph, obs_time); Rtcm::set_DF052(gps_eph, obs_time); - unsigned int i = 0; + uint32_t i = 0; bool first = true; std::string text_binary; for (auto it = message.cbegin(); it != message.cend(); it++) @@ -2070,7 +2072,7 @@ std::string Rtcm::print_MT1029(unsigned int ref_id, const Gps_Ephemeris& gps_eph std::string Rtcm::print_MT1045(const Galileo_Ephemeris& gal_eph) { - unsigned int msg_number = 1045; + uint32_t msg_number = 1045; Rtcm::set_DF002(msg_number); Rtcm::set_DF252(gal_eph); @@ -2099,7 +2101,7 @@ std::string Rtcm::print_MT1045(const Galileo_Ephemeris& gal_eph) Rtcm::set_DF312(gal_eph); Rtcm::set_DF314(gal_eph); Rtcm::set_DF315(gal_eph); - unsigned int seven_zero = 0; + uint32_t seven_zero = 0; std::bitset<7> DF001_ = std::bitset<7>(seven_zero); std::string data; @@ -2148,7 +2150,7 @@ std::string Rtcm::print_MT1045(const Galileo_Ephemeris& gal_eph) } -int Rtcm::read_MT1045(const std::string& message, Galileo_Ephemeris& gal_eph) +int32_t Rtcm::read_MT1045(const std::string& message, Galileo_Ephemeris& gal_eph) { // Convert message to binary std::string message_bin = Rtcm::binary_data_to_bin(message); @@ -2159,11 +2161,11 @@ int Rtcm::read_MT1045(const std::string& message, Galileo_Ephemeris& gal_eph) return 1; } - unsigned int preamble_length = 8; - unsigned int reserved_field_length = 6; - unsigned int index = preamble_length + reserved_field_length; + uint32_t preamble_length = 8; + uint32_t reserved_field_length = 6; + uint32_t index = preamble_length + reserved_field_length; - unsigned int read_message_length = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); + uint32_t read_message_length = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); index += 10; if (read_message_length != 62) @@ -2173,7 +2175,7 @@ int Rtcm::read_MT1045(const std::string& message, Galileo_Ephemeris& gal_eph) } // Check than the message number is correct - unsigned int read_msg_number = Rtcm::bin_to_uint(message_bin.substr(index, 12)); + uint32_t read_msg_number = Rtcm::bin_to_uint(message_bin.substr(index, 12)); index += 12; if (1045 != read_msg_number) @@ -2183,13 +2185,13 @@ int Rtcm::read_MT1045(const std::string& message, Galileo_Ephemeris& gal_eph) } // Fill Galileo Ephemeris with message data content - gal_eph.i_satellite_PRN = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 6))); + gal_eph.i_satellite_PRN = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 6))); index += 6; gal_eph.WN_5 = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 12))); index += 12; - gal_eph.IOD_nav_1 = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); + gal_eph.IOD_nav_1 = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 10))); index += 10; gal_eph.SISA_3 = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 8))); @@ -2258,7 +2260,7 @@ int Rtcm::read_MT1045(const std::string& message, Galileo_Ephemeris& gal_eph) gal_eph.BGD_E1E5a_5 = static_cast(Rtcm::bin_to_int(message_bin.substr(index, 10))); index += 10; - gal_eph.E5a_HS = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 2))); + gal_eph.E5a_HS = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 2))); index += 2; gal_eph.E5a_DVS = static_cast(Rtcm::bin_to_uint(message_bin.substr(index, 1))); @@ -2278,15 +2280,15 @@ std::string Rtcm::print_MSM_1(const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages) { - unsigned int msg_number = 0; + uint32_t msg_number = 0; if (gps_eph.i_satellite_PRN != 0) msg_number = 1071; if (gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1071; if (glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1081; @@ -2326,18 +2328,18 @@ std::string Rtcm::print_MSM_1(const Gps_Ephemeris& gps_eph, } -std::string Rtcm::get_MSM_header(unsigned int msg_number, +std::string Rtcm::get_MSM_header(uint32_t msg_number, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages) { // Find first element in observables block and define type of message - std::map::const_iterator observables_iter = observables.begin(); + std::map::const_iterator observables_iter = observables.begin(); std::string sys(observables_iter->second.System, 1); Rtcm::set_DF002(msg_number); @@ -2383,18 +2385,18 @@ std::string Rtcm::get_MSM_header(unsigned int msg_number, } -std::string Rtcm::get_MSM_1_content_sat_data(const std::map& observables) +std::string Rtcm::get_MSM_1_content_sat_data(const std::map& observables) { std::string sat_data; sat_data.clear(); Rtcm::set_DF394(observables); - unsigned int num_satellites = DF394.count(); + uint32_t num_satellites = DF394.count(); - std::vector > observables_vector; - std::map::const_iterator gnss_synchro_iter; - std::vector pos; - std::vector::iterator it; + std::vector > observables_vector; + std::map::const_iterator gnss_synchro_iter; + std::vector pos; + std::vector::iterator it; for (gnss_synchro_iter = observables.cbegin(); gnss_synchro_iter != observables.cend(); @@ -2408,9 +2410,9 @@ std::string Rtcm::get_MSM_1_content_sat_data(const std::map& } } - std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(observables_vector); + std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(observables_vector); - for (unsigned int nsat = 0; nsat < num_satellites; nsat++) + for (uint32_t nsat = 0; nsat < num_satellites; nsat++) { Rtcm::set_DF398(ordered_by_PRN_pos.at(nsat).second); sat_data += DF398.to_string(); @@ -2420,14 +2422,14 @@ std::string Rtcm::get_MSM_1_content_sat_data(const std::map& } -std::string Rtcm::get_MSM_1_content_signal_data(const std::map& observables) +std::string Rtcm::get_MSM_1_content_signal_data(const std::map& observables) { std::string signal_data; signal_data.clear(); - unsigned int Ncells = observables.size(); + uint32_t Ncells = observables.size(); - std::vector > observables_vector; - std::map::const_iterator map_iter; + std::vector > observables_vector; + std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); map_iter != observables.cend(); @@ -2436,11 +2438,11 @@ std::string Rtcm::get_MSM_1_content_signal_data(const std::map > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); + std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::reverse(ordered_by_signal.begin(), ordered_by_signal.end()); - std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); + std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); - for (unsigned int cell = 0; cell < Ncells; cell++) + for (uint32_t cell = 0; cell < Ncells; cell++) { Rtcm::set_DF400(ordered_by_PRN_pos.at(cell).second); signal_data += DF400.to_string(); @@ -2461,15 +2463,15 @@ std::string Rtcm::print_MSM_2(const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages) { - unsigned int msg_number = 0; + uint32_t msg_number = 0; if (gps_eph.i_satellite_PRN != 0) msg_number = 1072; if (gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1072; if (glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1082; @@ -2513,17 +2515,17 @@ std::string Rtcm::get_MSM_2_content_signal_data(const Gps_Ephemeris& ephNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, - const std::map& observables) + const std::map& observables) { std::string signal_data; std::string first_data_type; std::string second_data_type; std::string third_data_type; - unsigned int Ncells = observables.size(); + uint32_t Ncells = observables.size(); - std::vector > observables_vector; - std::map::const_iterator map_iter; + std::vector > observables_vector; + std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); map_iter != observables.cend(); @@ -2532,11 +2534,11 @@ std::string Rtcm::get_MSM_2_content_signal_data(const Gps_Ephemeris& ephNAV, observables_vector.push_back(*map_iter); } - std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); + std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::reverse(ordered_by_signal.begin(), ordered_by_signal.end()); - std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); + std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); - for (unsigned int cell = 0; cell < Ncells; cell++) + for (uint32_t cell = 0; cell < Ncells; cell++) { Rtcm::set_DF401(ordered_by_PRN_pos.at(cell).second); Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, ephGNAV, obs_time, ordered_by_PRN_pos.at(cell).second); @@ -2562,15 +2564,15 @@ std::string Rtcm::print_MSM_3(const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages) { - unsigned int msg_number = 0; + uint32_t msg_number = 0; if (gps_eph.i_satellite_PRN != 0) msg_number = 1073; if (gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1073; if (glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1083; @@ -2614,7 +2616,7 @@ std::string Rtcm::get_MSM_3_content_signal_data(const Gps_Ephemeris& ephNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, - const std::map& observables) + const std::map& observables) { std::string signal_data; std::string first_data_type; @@ -2622,10 +2624,10 @@ std::string Rtcm::get_MSM_3_content_signal_data(const Gps_Ephemeris& ephNAV, std::string third_data_type; std::string fourth_data_type; - unsigned int Ncells = observables.size(); + uint32_t Ncells = observables.size(); - std::vector > observables_vector; - std::map::const_iterator map_iter; + std::vector > observables_vector; + std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); map_iter != observables.cend(); @@ -2634,11 +2636,11 @@ std::string Rtcm::get_MSM_3_content_signal_data(const Gps_Ephemeris& ephNAV, observables_vector.push_back(*map_iter); } - std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); + std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::reverse(ordered_by_signal.begin(), ordered_by_signal.end()); - std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); + std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); - for (unsigned int cell = 0; cell < Ncells; cell++) + for (uint32_t cell = 0; cell < Ncells; cell++) { Rtcm::set_DF400(ordered_by_PRN_pos.at(cell).second); Rtcm::set_DF401(ordered_by_PRN_pos.at(cell).second); @@ -2666,15 +2668,15 @@ std::string Rtcm::print_MSM_4(const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages) { - unsigned int msg_number = 0; + uint32_t msg_number = 0; if (gps_eph.i_satellite_PRN != 0) msg_number = 1074; if (gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1074; if (glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1084; @@ -2713,19 +2715,19 @@ std::string Rtcm::print_MSM_4(const Gps_Ephemeris& gps_eph, } -std::string Rtcm::get_MSM_4_content_sat_data(const std::map& observables) +std::string Rtcm::get_MSM_4_content_sat_data(const std::map& observables) { std::string sat_data; std::string first_data_type; std::string second_data_type; Rtcm::set_DF394(observables); - unsigned int num_satellites = DF394.count(); + uint32_t num_satellites = DF394.count(); - std::vector > observables_vector; - std::map::const_iterator gnss_synchro_iter; - std::vector pos; - std::vector::iterator it; + std::vector > observables_vector; + std::map::const_iterator gnss_synchro_iter; + std::vector pos; + std::vector::iterator it; for (gnss_synchro_iter = observables.cbegin(); gnss_synchro_iter != observables.cend(); @@ -2739,9 +2741,9 @@ std::string Rtcm::get_MSM_4_content_sat_data(const std::map& } } - std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(observables_vector); + std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(observables_vector); - for (unsigned int nsat = 0; nsat < num_satellites; nsat++) + for (uint32_t nsat = 0; nsat < num_satellites; nsat++) { Rtcm::set_DF397(ordered_by_PRN_pos.at(nsat).second); Rtcm::set_DF398(ordered_by_PRN_pos.at(nsat).second); @@ -2758,7 +2760,7 @@ std::string Rtcm::get_MSM_4_content_signal_data(const Gps_Ephemeris& ephNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, - const std::map& observables) + const std::map& observables) { std::string signal_data; std::string first_data_type; @@ -2767,10 +2769,10 @@ std::string Rtcm::get_MSM_4_content_signal_data(const Gps_Ephemeris& ephNAV, std::string fourth_data_type; std::string fifth_data_type; - unsigned int Ncells = observables.size(); + uint32_t Ncells = observables.size(); - std::vector > observables_vector; - std::map::const_iterator map_iter; + std::vector > observables_vector; + std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); map_iter != observables.cend(); @@ -2779,11 +2781,11 @@ std::string Rtcm::get_MSM_4_content_signal_data(const Gps_Ephemeris& ephNAV, observables_vector.push_back(*map_iter); } - std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); + std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::reverse(ordered_by_signal.begin(), ordered_by_signal.end()); - std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); + std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); - for (unsigned int cell = 0; cell < Ncells; cell++) + for (uint32_t cell = 0; cell < Ncells; cell++) { Rtcm::set_DF400(ordered_by_PRN_pos.at(cell).second); Rtcm::set_DF401(ordered_by_PRN_pos.at(cell).second); @@ -2813,15 +2815,15 @@ std::string Rtcm::print_MSM_5(const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages) { - unsigned int msg_number = 0; + uint32_t msg_number = 0; if (gps_eph.i_satellite_PRN != 0) msg_number = 1075; if (gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1075; if (glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1085; @@ -2860,7 +2862,7 @@ std::string Rtcm::print_MSM_5(const Gps_Ephemeris& gps_eph, } -std::string Rtcm::get_MSM_5_content_sat_data(const std::map& observables) +std::string Rtcm::get_MSM_5_content_sat_data(const std::map& observables) { std::string sat_data; std::string first_data_type; @@ -2869,12 +2871,12 @@ std::string Rtcm::get_MSM_5_content_sat_data(const std::map& std::string fourth_data_type; Rtcm::set_DF394(observables); - unsigned int num_satellites = DF394.count(); + uint32_t num_satellites = DF394.count(); - std::vector > observables_vector; - std::map::const_iterator gnss_synchro_iter; - std::vector pos; - std::vector::iterator it; + std::vector > observables_vector; + std::map::const_iterator gnss_synchro_iter; + std::vector pos; + std::vector::iterator it; for (gnss_synchro_iter = observables.cbegin(); gnss_synchro_iter != observables.cend(); @@ -2888,9 +2890,9 @@ std::string Rtcm::get_MSM_5_content_sat_data(const std::map& } } - std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(observables_vector); + std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(observables_vector); - for (unsigned int nsat = 0; nsat < num_satellites; nsat++) + for (uint32_t nsat = 0; nsat < num_satellites; nsat++) { Rtcm::set_DF397(ordered_by_PRN_pos.at(nsat).second); Rtcm::set_DF398(ordered_by_PRN_pos.at(nsat).second); @@ -2911,7 +2913,7 @@ std::string Rtcm::get_MSM_5_content_signal_data(const Gps_Ephemeris& ephNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, - const std::map& observables) + const std::map& observables) { std::string signal_data; std::string first_data_type; @@ -2921,10 +2923,10 @@ std::string Rtcm::get_MSM_5_content_signal_data(const Gps_Ephemeris& ephNAV, std::string fifth_data_type; std::string sixth_data_type; - unsigned int Ncells = observables.size(); + uint32_t Ncells = observables.size(); - std::vector > observables_vector; - std::map::const_iterator map_iter; + std::vector > observables_vector; + std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); map_iter != observables.cend(); @@ -2933,11 +2935,11 @@ std::string Rtcm::get_MSM_5_content_signal_data(const Gps_Ephemeris& ephNAV, observables_vector.push_back(*map_iter); } - std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); + std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::reverse(ordered_by_signal.begin(), ordered_by_signal.end()); - std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); + std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); - for (unsigned int cell = 0; cell < Ncells; cell++) + for (uint32_t cell = 0; cell < Ncells; cell++) { Rtcm::set_DF400(ordered_by_PRN_pos.at(cell).second); Rtcm::set_DF401(ordered_by_PRN_pos.at(cell).second); @@ -2969,15 +2971,15 @@ std::string Rtcm::print_MSM_6(const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages) { - unsigned int msg_number = 0; + uint32_t msg_number = 0; if (gps_eph.i_satellite_PRN != 0) msg_number = 1076; if (gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1076; if (glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1086; @@ -3021,7 +3023,7 @@ std::string Rtcm::get_MSM_6_content_signal_data(const Gps_Ephemeris& ephNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, - const std::map& observables) + const std::map& observables) { std::string signal_data; std::string first_data_type; @@ -3030,10 +3032,10 @@ std::string Rtcm::get_MSM_6_content_signal_data(const Gps_Ephemeris& ephNAV, std::string fourth_data_type; std::string fifth_data_type; - unsigned int Ncells = observables.size(); + uint32_t Ncells = observables.size(); - std::vector > observables_vector; - std::map::const_iterator map_iter; + std::vector > observables_vector; + std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); map_iter != observables.cend(); @@ -3042,11 +3044,11 @@ std::string Rtcm::get_MSM_6_content_signal_data(const Gps_Ephemeris& ephNAV, observables_vector.push_back(*map_iter); } - std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); + std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::reverse(ordered_by_signal.begin(), ordered_by_signal.end()); - std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); + std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); - for (unsigned int cell = 0; cell < Ncells; cell++) + for (uint32_t cell = 0; cell < Ncells; cell++) { Rtcm::set_DF405(ordered_by_PRN_pos.at(cell).second); Rtcm::set_DF406(ordered_by_PRN_pos.at(cell).second); @@ -3076,15 +3078,15 @@ std::string Rtcm::print_MSM_7(const Gps_Ephemeris& gps_eph, const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages) { - unsigned int msg_number = 0; + uint32_t msg_number = 0; if (gps_eph.i_satellite_PRN != 0) msg_number = 1077; if (gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1077; if (glo_gnav_eph.i_satellite_PRN != 0) msg_number = 1087; @@ -3128,7 +3130,7 @@ std::string Rtcm::get_MSM_7_content_signal_data(const Gps_Ephemeris& ephNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, - const std::map& observables) + const std::map& observables) { std::string signal_data; std::string first_data_type; @@ -3138,10 +3140,10 @@ std::string Rtcm::get_MSM_7_content_signal_data(const Gps_Ephemeris& ephNAV, std::string fifth_data_type; std::string sixth_data_type; - unsigned int Ncells = observables.size(); + uint32_t Ncells = observables.size(); - std::vector > observables_vector; - std::map::const_iterator map_iter; + std::vector > observables_vector; + std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); map_iter != observables.cend(); @@ -3150,11 +3152,11 @@ std::string Rtcm::get_MSM_7_content_signal_data(const Gps_Ephemeris& ephNAV, observables_vector.push_back(*map_iter); } - std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); + std::vector > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::reverse(ordered_by_signal.begin(), ordered_by_signal.end()); - std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); + std::vector > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal); - for (unsigned int cell = 0; cell < Ncells; cell++) + for (uint32_t cell = 0; cell < Ncells; cell++) { Rtcm::set_DF405(ordered_by_PRN_pos.at(cell).second); Rtcm::set_DF406(ordered_by_PRN_pos.at(cell).second); @@ -3179,16 +3181,16 @@ std::string Rtcm::get_MSM_7_content_signal_data(const Gps_Ephemeris& ephNAV, // Some utilities // ***************************************************************************************************** -std::vector > Rtcm::sort_by_PRN_mask(const std::vector >& synchro_map) const +std::vector > Rtcm::sort_by_PRN_mask(const std::vector >& synchro_map) const { - std::vector >::const_iterator synchro_map_iter; - std::vector > my_vec; + std::vector >::const_iterator synchro_map_iter; + std::vector > my_vec; struct { - bool operator()(const std::pair& a, const std::pair& b) + bool operator()(const std::pair& a, const std::pair& b) { - unsigned int value_a = 64 - a.second.PRN; - unsigned int value_b = 64 - b.second.PRN; + uint32_t value_a = 64 - a.second.PRN; + uint32_t value_b = 64 - b.second.PRN; return value_a < value_b; } } has_lower_pos; @@ -3198,7 +3200,7 @@ std::vector > Rtcm::sort_by_PRN_mask(const std::vec synchro_map_iter++) { - std::pair p(synchro_map_iter->first, synchro_map_iter->second); + std::pair p(synchro_map_iter->first, synchro_map_iter->second); my_vec.push_back(p); } @@ -3208,17 +3210,17 @@ std::vector > Rtcm::sort_by_PRN_mask(const std::vec } -std::vector > Rtcm::sort_by_signal(const std::vector >& synchro_map) const +std::vector > Rtcm::sort_by_signal(const std::vector >& synchro_map) const { - std::vector >::const_iterator synchro_map_iter; - std::vector > my_vec; + std::vector >::const_iterator synchro_map_iter; + std::vector > my_vec; struct { - bool operator()(const std::pair& a, const std::pair& b) + bool operator()(const std::pair& a, const std::pair& b) { - unsigned int value_a = 0; - unsigned int value_b = 0; + uint32_t value_a = 0; + uint32_t value_b = 0; std::string system_a(&a.second.System, 1); std::string system_b(&b.second.System, 1); std::string sig_a_(a.second.Signal); @@ -3256,7 +3258,7 @@ std::vector > Rtcm::sort_by_signal(const std::vecto synchro_map_iter++) { - std::pair p(synchro_map_iter->first, synchro_map_iter->second); + std::pair p(synchro_map_iter->first, synchro_map_iter->second); my_vec.push_back(p); } @@ -3344,9 +3346,9 @@ boost::posix_time::ptime Rtcm::compute_GLONASS_time(const Glonass_Gnav_Ephemeris } -unsigned int Rtcm::lock_time(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +uint32_t Rtcm::lock_time(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { - unsigned int lock_time_in_seconds; + uint32_t lock_time_in_seconds; boost::posix_time::ptime current_time = Rtcm::compute_GPS_time(eph, obs_time); boost::posix_time::ptime last_lock_time = Rtcm::gps_L1_last_lock_time[65 - gnss_synchro.PRN]; if (last_lock_time.is_not_a_date_time()) // || CHECK LLI!!......) @@ -3354,16 +3356,16 @@ unsigned int Rtcm::lock_time(const Gps_Ephemeris& eph, double obs_time, const Gn Rtcm::gps_L1_last_lock_time[65 - gnss_synchro.PRN] = current_time; } boost::posix_time::time_duration lock_duration = current_time - Rtcm::gps_L1_last_lock_time[65 - gnss_synchro.PRN]; - lock_time_in_seconds = static_cast(lock_duration.total_seconds()); + lock_time_in_seconds = static_cast(lock_duration.total_seconds()); // Debug: // std::cout << "lock time PRN " << gnss_synchro.PRN << ": " << lock_time_in_seconds << " current time: " << current_time << std::endl; return lock_time_in_seconds; } -unsigned int Rtcm::lock_time(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +uint32_t Rtcm::lock_time(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { - unsigned int lock_time_in_seconds; + uint32_t lock_time_in_seconds; boost::posix_time::ptime current_time = Rtcm::compute_GPS_time(eph, obs_time); boost::posix_time::ptime last_lock_time = Rtcm::gps_L2_last_lock_time[65 - gnss_synchro.PRN]; if (last_lock_time.is_not_a_date_time()) // || CHECK LLI!!......) @@ -3371,14 +3373,14 @@ unsigned int Rtcm::lock_time(const Gps_CNAV_Ephemeris& eph, double obs_time, con Rtcm::gps_L2_last_lock_time[65 - gnss_synchro.PRN] = current_time; } boost::posix_time::time_duration lock_duration = current_time - Rtcm::gps_L2_last_lock_time[65 - gnss_synchro.PRN]; - lock_time_in_seconds = static_cast(lock_duration.total_seconds()); + lock_time_in_seconds = static_cast(lock_duration.total_seconds()); return lock_time_in_seconds; } -unsigned int Rtcm::lock_time(const Galileo_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +uint32_t Rtcm::lock_time(const Galileo_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { - unsigned int lock_time_in_seconds; + uint32_t lock_time_in_seconds; boost::posix_time::ptime current_time = Rtcm::compute_Galileo_time(eph, obs_time); boost::posix_time::ptime last_lock_time; @@ -3414,14 +3416,14 @@ unsigned int Rtcm::lock_time(const Galileo_Ephemeris& eph, double obs_time, cons lock_duration = current_time - Rtcm::gal_E5_last_lock_time[65 - gnss_synchro.PRN]; } - lock_time_in_seconds = static_cast(lock_duration.total_seconds()); + lock_time_in_seconds = static_cast(lock_duration.total_seconds()); return lock_time_in_seconds; } -unsigned int Rtcm::lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +uint32_t Rtcm::lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { - unsigned int lock_time_in_seconds; + uint32_t lock_time_in_seconds; boost::posix_time::ptime current_time = Rtcm::compute_GLONASS_time(eph, obs_time); boost::posix_time::ptime last_lock_time; @@ -3457,12 +3459,12 @@ unsigned int Rtcm::lock_time(const Glonass_Gnav_Ephemeris& eph, double obs_time, lock_duration = current_time - Rtcm::glo_L2_last_lock_time[65 - gnss_synchro.PRN]; } - lock_time_in_seconds = static_cast(lock_duration.total_seconds()); + lock_time_in_seconds = static_cast(lock_duration.total_seconds()); return lock_time_in_seconds; } -unsigned int Rtcm::lock_time_indicator(unsigned int lock_time_period_s) +uint32_t Rtcm::lock_time_indicator(uint32_t lock_time_period_s) { // Table 3.4-2 if (lock_time_period_s <= 0) return 0; @@ -3476,7 +3478,7 @@ unsigned int Rtcm::lock_time_indicator(unsigned int lock_time_period_s) } -unsigned int Rtcm::msm_lock_time_indicator(unsigned int lock_time_period_s) +uint32_t Rtcm::msm_lock_time_indicator(uint32_t lock_time_period_s) { // Table 3.5-74 if (lock_time_period_s < 32) return 0; @@ -3499,7 +3501,7 @@ unsigned int Rtcm::msm_lock_time_indicator(unsigned int lock_time_period_s) // clang-format off -unsigned int Rtcm::msm_extended_lock_time_indicator(unsigned int lock_time_period_s) +uint32_t Rtcm::msm_extended_lock_time_indicator(uint32_t lock_time_period_s) { // Table 3.5-75 if( lock_time_period_s < 64 ) return ( lock_time_period_s ); @@ -3534,7 +3536,7 @@ unsigned int Rtcm::msm_extended_lock_time_indicator(unsigned int lock_time_perio // // ***************************************************************************************************** -int Rtcm::set_DF002(unsigned int message_number) +int32_t Rtcm::set_DF002(uint32_t message_number) { if (message_number > 4095) { @@ -3545,9 +3547,9 @@ int Rtcm::set_DF002(unsigned int message_number) } -int Rtcm::set_DF003(unsigned int ref_station_ID) +int32_t Rtcm::set_DF003(uint32_t ref_station_ID) { - //unsigned int station_ID = ref_station_ID; + //uint32_t station_ID = ref_station_ID; if (ref_station_ID > 4095) { LOG(WARNING) << "RTCM reference station ID must be between 0 and 4095, but it has been set to " << ref_station_ID; @@ -3557,10 +3559,10 @@ int Rtcm::set_DF003(unsigned int ref_station_ID) } -int Rtcm::set_DF004(double obs_time) +int32_t Rtcm::set_DF004(double obs_time) { // TOW in milliseconds from the beginning of the GPS week, measured in GPS time - unsigned long int tow = static_cast(std::round(obs_time * 1000)); + uint64_t tow = static_cast(std::round(obs_time * 1000)); if (tow > 604799999) { LOG(WARNING) << "To large TOW! Set to the last millisecond of the week"; @@ -3571,7 +3573,7 @@ int Rtcm::set_DF004(double obs_time) } -int Rtcm::set_DF005(bool sync_flag) +int32_t Rtcm::set_DF005(bool sync_flag) { // 0 - No further GNSS observables referenced to the same Epoch Time will be transmitted. This enables the receiver to begin processing // the data immediately after decoding the message. @@ -3581,11 +3583,11 @@ int Rtcm::set_DF005(bool sync_flag) } -int Rtcm::set_DF006(const std::map& observables) +int32_t Rtcm::set_DF006(const std::map& observables) { //Number of satellites observed in current epoch - unsigned short int nsats = 0; - std::map::const_iterator observables_iter; + uint16_t nsats = 0; + std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); observables_iter != observables.cend(); observables_iter++) @@ -3602,7 +3604,7 @@ int Rtcm::set_DF006(const std::map& observables) } -int Rtcm::set_DF007(bool divergence_free_smoothing_indicator) +int32_t Rtcm::set_DF007(bool divergence_free_smoothing_indicator) { // 0 - Divergence-free smoothing not used 1 - Divergence-free smoothing used DF007 = std::bitset<1>(divergence_free_smoothing_indicator); @@ -3610,16 +3612,16 @@ int Rtcm::set_DF007(bool divergence_free_smoothing_indicator) } -int Rtcm::set_DF008(short int smoothing_interval) +int32_t Rtcm::set_DF008(int16_t smoothing_interval) { DF008 = std::bitset<3>(smoothing_interval); return 0; } -int Rtcm::set_DF009(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF009(const Gnss_Synchro& gnss_synchro) { - unsigned int prn_ = gnss_synchro.PRN; + uint32_t prn_ = gnss_synchro.PRN; if (prn_ > 32) { LOG(WARNING) << "GPS satellite ID must be between 1 and 32, but PRN " << prn_ << " was found"; @@ -3629,9 +3631,9 @@ int Rtcm::set_DF009(const Gnss_Synchro& gnss_synchro) } -int Rtcm::set_DF009(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF009(const Gps_Ephemeris& gps_eph) { - unsigned int prn_ = gps_eph.i_satellite_PRN; + uint32_t prn_ = gps_eph.i_satellite_PRN; if (prn_ > 32) { LOG(WARNING) << "GPS satellite ID must be between 1 and 32, but PRN " << prn_ << " was found"; @@ -3641,23 +3643,23 @@ int Rtcm::set_DF009(const Gps_Ephemeris& gps_eph) } -int Rtcm::set_DF010(bool code_indicator) +int32_t Rtcm::set_DF010(bool code_indicator) { DF010 = std::bitset<1>(code_indicator); return 0; } -int Rtcm::set_DF011(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF011(const Gnss_Synchro& gnss_synchro) { double ambiguity = std::floor(gnss_synchro.Pseudorange_m / 299792.458); - unsigned long int gps_L1_pseudorange = static_cast(std::round((gnss_synchro.Pseudorange_m - ambiguity * 299792.458) / 0.02)); + uint64_t gps_L1_pseudorange = static_cast(std::round((gnss_synchro.Pseudorange_m - ambiguity * 299792.458) / 0.02)); DF011 = std::bitset<24>(gps_L1_pseudorange); return 0; } -int Rtcm::set_DF012(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF012(const Gnss_Synchro& gnss_synchro) { const double lambda = GPS_C_m_s / GPS_L1_FREQ_HZ; double ambiguity = std::floor(gnss_synchro.Pseudorange_m / 299792.458); @@ -3665,64 +3667,64 @@ int Rtcm::set_DF012(const Gnss_Synchro& gnss_synchro) double gps_L1_pseudorange_c = gps_L1_pseudorange * 0.02 + ambiguity * 299792.458; double L1_phaserange_c = gnss_synchro.Carrier_phase_rads / GPS_TWO_PI; double L1_phaserange_c_r = std::fmod(L1_phaserange_c - gps_L1_pseudorange_c / lambda + 1500.0, 3000.0) - 1500.0; - long int gps_L1_phaserange_minus_L1_pseudorange = static_cast(std::round(L1_phaserange_c_r * lambda / 0.0005)); + int64_t gps_L1_phaserange_minus_L1_pseudorange = static_cast(std::round(L1_phaserange_c_r * lambda / 0.0005)); DF012 = std::bitset<20>(gps_L1_phaserange_minus_L1_pseudorange); return 0; } -int Rtcm::set_DF013(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF013(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { - unsigned int lock_time_indicator; - unsigned int lock_time_period_s = Rtcm::lock_time(eph, obs_time, gnss_synchro); + uint32_t lock_time_indicator; + uint32_t lock_time_period_s = Rtcm::lock_time(eph, obs_time, gnss_synchro); lock_time_indicator = Rtcm::lock_time_indicator(lock_time_period_s); DF013 = std::bitset<7>(lock_time_indicator); return 0; } -int Rtcm::set_DF014(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF014(const Gnss_Synchro& gnss_synchro) { - unsigned int gps_L1_pseudorange_ambiguity = static_cast(std::floor(gnss_synchro.Pseudorange_m / 299792.458)); + uint32_t gps_L1_pseudorange_ambiguity = static_cast(std::floor(gnss_synchro.Pseudorange_m / 299792.458)); DF014 = std::bitset<8>(gps_L1_pseudorange_ambiguity); return 0; } -int Rtcm::set_DF015(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF015(const Gnss_Synchro& gnss_synchro) { double CN0_dB_Hz_est = gnss_synchro.CN0_dB_hz; if (CN0_dB_Hz_est > 63.75) { CN0_dB_Hz_est = 63.75; } - unsigned int CN0_dB_Hz = static_cast(std::round(CN0_dB_Hz_est / 0.25)); + uint32_t CN0_dB_Hz = static_cast(std::round(CN0_dB_Hz_est / 0.25)); DF015 = std::bitset<8>(CN0_dB_Hz); return 0; } -int Rtcm::set_DF017(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2) +int32_t Rtcm::set_DF017(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2) { double ambiguity = std::floor(gnss_synchroL1.Pseudorange_m / 299792.458); double gps_L1_pseudorange = std::round((gnss_synchroL1.Pseudorange_m - ambiguity * 299792.458) / 0.02); double gps_L1_pseudorange_c = gps_L1_pseudorange * 0.02 + ambiguity * 299792.458; double l2_l1_pseudorange = gnss_synchroL2.Pseudorange_m - gps_L1_pseudorange_c; - int pseudorange_difference = 0xFFFFE000; // invalid value; + int32_t pseudorange_difference = 0xFFFFE000; // invalid value; if (std::fabs(l2_l1_pseudorange) <= 163.82) { - pseudorange_difference = static_cast(std::round(l2_l1_pseudorange / 0.02)); + pseudorange_difference = static_cast(std::round(l2_l1_pseudorange / 0.02)); } DF017 = std::bitset<14>(pseudorange_difference); return 0; } -int Rtcm::set_DF018(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2) +int32_t Rtcm::set_DF018(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2) { const double lambda2 = GPS_C_m_s / GPS_L2_FREQ_HZ; - int l2_phaserange_minus_l1_pseudorange = 0xFFF80000; + int32_t l2_phaserange_minus_l1_pseudorange = 0xFFF80000; double ambiguity = std::floor(gnss_synchroL1.Pseudorange_m / 299792.458); double gps_L1_pseudorange = std::round((gnss_synchroL1.Pseudorange_m - ambiguity * 299792.458) / 0.02); double gps_L1_pseudorange_c = gps_L1_pseudorange * 0.02 + ambiguity * 299792.458; @@ -3731,7 +3733,7 @@ int Rtcm::set_DF018(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss if (std::fabs(L1_phaserange_c_r * lambda2) <= 262.1435) { - l2_phaserange_minus_l1_pseudorange = static_cast(std::round(L1_phaserange_c_r * lambda2 / 0.0005)); + l2_phaserange_minus_l1_pseudorange = static_cast(std::round(L1_phaserange_c_r * lambda2 / 0.0005)); } DF018 = std::bitset<20>(l2_phaserange_minus_l1_pseudorange); @@ -3739,100 +3741,100 @@ int Rtcm::set_DF018(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss } -int Rtcm::set_DF019(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF019(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { - unsigned int lock_time_indicator; - unsigned int lock_time_period_s = Rtcm::lock_time(eph, obs_time, gnss_synchro); + uint32_t lock_time_indicator; + uint32_t lock_time_period_s = Rtcm::lock_time(eph, obs_time, gnss_synchro); lock_time_indicator = Rtcm::lock_time_indicator(lock_time_period_s); DF019 = std::bitset<7>(lock_time_indicator); return 0; } -int Rtcm::set_DF020(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF020(const Gnss_Synchro& gnss_synchro) { double CN0_dB_Hz_est = gnss_synchro.CN0_dB_hz; if (CN0_dB_Hz_est > 63.75) { CN0_dB_Hz_est = 63.75; } - unsigned int CN0_dB_Hz = static_cast(std::round(CN0_dB_Hz_est / 0.25)); + uint32_t CN0_dB_Hz = static_cast(std::round(CN0_dB_Hz_est / 0.25)); DF020 = std::bitset<8>(CN0_dB_Hz); return 0; } -int Rtcm::set_DF021() +int32_t Rtcm::set_DF021() { - unsigned short int itfr_year = 0; + uint16_t itfr_year = 0; DF021 = std::bitset<6>(itfr_year); return 0; } -int Rtcm::set_DF022(bool gps_indicator) +int32_t Rtcm::set_DF022(bool gps_indicator) { DF022 = std::bitset<1>(gps_indicator); return 0; } -int Rtcm::set_DF023(bool glonass_indicator) +int32_t Rtcm::set_DF023(bool glonass_indicator) { DF023 = std::bitset<1>(glonass_indicator); return 0; } -int Rtcm::set_DF024(bool galileo_indicator) +int32_t Rtcm::set_DF024(bool galileo_indicator) { DF024 = std::bitset<1>(galileo_indicator); return 0; } -int Rtcm::set_DF025(double antenna_ECEF_X_m) +int32_t Rtcm::set_DF025(double antenna_ECEF_X_m) { - long long int ant_ref_x = static_cast(std::round(antenna_ECEF_X_m * 10000)); + int64_t ant_ref_x = static_cast(std::round(antenna_ECEF_X_m * 10000)); DF025 = std::bitset<38>(ant_ref_x); return 0; } -int Rtcm::set_DF026(double antenna_ECEF_Y_m) +int32_t Rtcm::set_DF026(double antenna_ECEF_Y_m) { - long long int ant_ref_y = static_cast(std::round(antenna_ECEF_Y_m * 10000)); + int64_t ant_ref_y = static_cast(std::round(antenna_ECEF_Y_m * 10000)); DF026 = std::bitset<38>(ant_ref_y); return 0; } -int Rtcm::set_DF027(double antenna_ECEF_Z_m) +int32_t Rtcm::set_DF027(double antenna_ECEF_Z_m) { - long long int ant_ref_z = static_cast(std::round(antenna_ECEF_Z_m * 10000)); + int64_t ant_ref_z = static_cast(std::round(antenna_ECEF_Z_m * 10000)); DF027 = std::bitset<38>(ant_ref_z); return 0; } -int Rtcm::set_DF028(double height) +int32_t Rtcm::set_DF028(double height) { - unsigned int h_ = static_cast(std::round(height * 10000)); + uint32_t h_ = static_cast(std::round(height * 10000)); DF028 = std::bitset<16>(h_); return 0; } -int Rtcm::set_DF031(unsigned int antenna_setup_id) +int32_t Rtcm::set_DF031(uint32_t antenna_setup_id) { DF031 = std::bitset<8>(antenna_setup_id); return 0; } -int Rtcm::set_DF034(double obs_time) +int32_t Rtcm::set_DF034(double obs_time) { // TOW in milliseconds from the beginning of the GLONASS day, measured in GLONASS time - unsigned long int tk = static_cast(std::round(obs_time * 1000)); + uint64_t tk = static_cast(std::round(obs_time * 1000)); if (tk > 86400999) { LOG(WARNING) << "To large GLONASS Epoch Time (tk)! Set to the last millisecond of the day"; @@ -3843,11 +3845,11 @@ int Rtcm::set_DF034(double obs_time) } -int Rtcm::set_DF035(const std::map& observables) +int32_t Rtcm::set_DF035(const std::map& observables) { //Number of satellites observed in current epoch - unsigned short int nsats = 0; - std::map::const_iterator observables_iter; + uint16_t nsats = 0; + std::map::const_iterator observables_iter; for (observables_iter = observables.begin(); observables_iter != observables.end(); observables_iter++) @@ -3864,7 +3866,7 @@ int Rtcm::set_DF035(const std::map& observables) } -int Rtcm::set_DF036(bool divergence_free_smoothing_indicator) +int32_t Rtcm::set_DF036(bool divergence_free_smoothing_indicator) { // 0 - Divergence-free smoothing not used 1 - Divergence-free smoothing used DF036 = std::bitset<1>(divergence_free_smoothing_indicator); @@ -3872,16 +3874,16 @@ int Rtcm::set_DF036(bool divergence_free_smoothing_indicator) } -int Rtcm::set_DF037(short int smoothing_interval) +int32_t Rtcm::set_DF037(int16_t smoothing_interval) { DF037 = std::bitset<3>(smoothing_interval); return 0; } -int Rtcm::set_DF038(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF038(const Gnss_Synchro& gnss_synchro) { - unsigned int prn_ = gnss_synchro.PRN; + uint32_t prn_ = gnss_synchro.PRN; if (prn_ > 24) { LOG(WARNING) << "GLONASS satellite ID (Slot Number) must be between 1 and 24, but PRN " << prn_ << " was found"; @@ -3891,9 +3893,9 @@ int Rtcm::set_DF038(const Gnss_Synchro& gnss_synchro) } -int Rtcm::set_DF038(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF038(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int prn_ = glonass_gnav_eph.i_satellite_slot_number; + uint32_t prn_ = glonass_gnav_eph.i_satellite_slot_number; if (prn_ > 24) { LOG(WARNING) << "GLONASS satellite ID (Slot Number) must be between 0 and 24, but PRN " << prn_ << " was found"; @@ -3903,16 +3905,16 @@ int Rtcm::set_DF038(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF039(bool code_indicator) +int32_t Rtcm::set_DF039(bool code_indicator) { DF039 = std::bitset<1>(code_indicator); return 0; } -int Rtcm::set_DF040(int frequency_channel_number) +int32_t Rtcm::set_DF040(int32_t frequency_channel_number) { - unsigned int freq_ = frequency_channel_number + 7; + uint32_t freq_ = frequency_channel_number + 7; if (freq_ > 20) { LOG(WARNING) << "GLONASS Satellite Frequency Number Conversion Error." @@ -3925,9 +3927,9 @@ int Rtcm::set_DF040(int frequency_channel_number) } -int Rtcm::set_DF040(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF040(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int freq_ = glonass_gnav_eph.i_satellite_freq_channel + 7; + uint32_t freq_ = glonass_gnav_eph.i_satellite_freq_channel + 7; if (freq_ > 20) { LOG(WARNING) << "GLONASS Satellite Frequency Number Conversion Error." @@ -3940,16 +3942,16 @@ int Rtcm::set_DF040(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF041(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF041(const Gnss_Synchro& gnss_synchro) { double ambiguity = std::floor(gnss_synchro.Pseudorange_m / 599584.92); - unsigned long int glonass_L1_pseudorange = static_cast(std::round((gnss_synchro.Pseudorange_m - ambiguity * 599584.92) / 0.02)); + uint64_t glonass_L1_pseudorange = static_cast(std::round((gnss_synchro.Pseudorange_m - ambiguity * 599584.92) / 0.02)); DF041 = std::bitset<25>(glonass_L1_pseudorange); return 0; } -int Rtcm::set_DF042(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF042(const Gnss_Synchro& gnss_synchro) { const double lambda = GLONASS_C_m_s / (GLONASS_L1_CA_FREQ_HZ + (GLONASS_L1_CA_DFREQ_HZ * GLONASS_PRN.at(gnss_synchro.PRN))); double ambiguity = std::floor(gnss_synchro.Pseudorange_m / 599584.92); @@ -3957,31 +3959,31 @@ int Rtcm::set_DF042(const Gnss_Synchro& gnss_synchro) double glonass_L1_pseudorange_c = glonass_L1_pseudorange * 0.02 + ambiguity * 299792.458; double L1_phaserange_c = gnss_synchro.Carrier_phase_rads / GLONASS_TWO_PI; double L1_phaserange_c_r = std::fmod(L1_phaserange_c - glonass_L1_pseudorange_c / lambda + 1500.0, 3000.0) - 1500.0; - long int glonass_L1_phaserange_minus_L1_pseudorange = static_cast(std::round(L1_phaserange_c_r * lambda / 0.0005)); + int64_t glonass_L1_phaserange_minus_L1_pseudorange = static_cast(std::round(L1_phaserange_c_r * lambda / 0.0005)); DF042 = std::bitset<20>(glonass_L1_phaserange_minus_L1_pseudorange); return 0; } -int Rtcm::set_DF043(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF043(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { - unsigned int lock_time_indicator; - unsigned int lock_time_period_s = Rtcm::lock_time(eph, obs_time, gnss_synchro); + uint32_t lock_time_indicator; + uint32_t lock_time_period_s = Rtcm::lock_time(eph, obs_time, gnss_synchro); lock_time_indicator = Rtcm::lock_time_indicator(lock_time_period_s); DF043 = std::bitset<7>(lock_time_indicator); return 0; } -int Rtcm::set_DF044(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF044(const Gnss_Synchro& gnss_synchro) { - unsigned int glonass_L1_pseudorange_ambiguity = static_cast(std::floor(gnss_synchro.Pseudorange_m / 599584.916)); + uint32_t glonass_L1_pseudorange_ambiguity = static_cast(std::floor(gnss_synchro.Pseudorange_m / 599584.916)); DF044 = std::bitset<7>(glonass_L1_pseudorange_ambiguity); return 0; } -int Rtcm::set_DF045(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF045(const Gnss_Synchro& gnss_synchro) { double CN0_dB_Hz_est = gnss_synchro.CN0_dB_hz; if (CN0_dB_Hz_est > 63.75) @@ -3989,33 +3991,33 @@ int Rtcm::set_DF045(const Gnss_Synchro& gnss_synchro) LOG(WARNING) << "GLONASS L1 CNR must be between 0 and 63.75, but CNR " << CN0_dB_Hz_est << " was found. Setting to 63.75 dB-Hz"; CN0_dB_Hz_est = 63.75; } - unsigned int CN0_dB_Hz = static_cast(std::round(CN0_dB_Hz_est / 0.25)); + uint32_t CN0_dB_Hz = static_cast(std::round(CN0_dB_Hz_est / 0.25)); DF045 = std::bitset<8>(CN0_dB_Hz); return 0; } -int Rtcm::set_DF047(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2) +int32_t Rtcm::set_DF047(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2) { double ambiguity = std::floor(gnss_synchroL1.Pseudorange_m / 599584.92); double glonass_L1_pseudorange = std::round((gnss_synchroL1.Pseudorange_m - ambiguity * 599584.92) / 0.02); double glonass_L1_pseudorange_c = glonass_L1_pseudorange * 0.02 + ambiguity * 599584.92; double l2_l1_pseudorange = gnss_synchroL2.Pseudorange_m - glonass_L1_pseudorange_c; - int pseudorange_difference = 0xFFFFE000; // invalid value; + int32_t pseudorange_difference = 0xFFFFE000; // invalid value; if (std::fabs(l2_l1_pseudorange) <= 163.82) { - pseudorange_difference = static_cast(std::round(l2_l1_pseudorange / 0.02)); + pseudorange_difference = static_cast(std::round(l2_l1_pseudorange / 0.02)); } DF047 = std::bitset<14>(pseudorange_difference); return 0; } //TODO Need to consider frequency channel in this fields -int Rtcm::set_DF048(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2) +int32_t Rtcm::set_DF048(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2) { const double lambda2 = GLONASS_C_m_s / GLONASS_L2_CA_FREQ_HZ; - int l2_phaserange_minus_l1_pseudorange = 0xFFF80000; + int32_t l2_phaserange_minus_l1_pseudorange = 0xFFF80000; double ambiguity = std::floor(gnss_synchroL1.Pseudorange_m / 599584.92); double glonass_L1_pseudorange = std::round((gnss_synchroL1.Pseudorange_m - ambiguity * 599584.92) / 0.02); double glonass_L1_pseudorange_c = glonass_L1_pseudorange * 0.02 + ambiguity * 599584.92; @@ -4024,7 +4026,7 @@ int Rtcm::set_DF048(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss if (std::fabs(L1_phaserange_c_r * lambda2) <= 262.1435) { - l2_phaserange_minus_l1_pseudorange = static_cast(std::round(L1_phaserange_c_r * lambda2 / 0.0005)); + l2_phaserange_minus_l1_pseudorange = static_cast(std::round(L1_phaserange_c_r * lambda2 / 0.0005)); } DF048 = std::bitset<20>(l2_phaserange_minus_l1_pseudorange); @@ -4032,319 +4034,319 @@ int Rtcm::set_DF048(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss } -int Rtcm::set_DF049(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF049(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro) { - unsigned int lock_time_indicator; - unsigned int lock_time_period_s = Rtcm::lock_time(eph, obs_time, gnss_synchro); + uint32_t lock_time_indicator; + uint32_t lock_time_period_s = Rtcm::lock_time(eph, obs_time, gnss_synchro); lock_time_indicator = Rtcm::lock_time_indicator(lock_time_period_s); DF049 = std::bitset<7>(lock_time_indicator); return 0; } -int Rtcm::set_DF050(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF050(const Gnss_Synchro& gnss_synchro) { double CN0_dB_Hz_est = gnss_synchro.CN0_dB_hz; if (CN0_dB_Hz_est > 63.75) { CN0_dB_Hz_est = 63.75; } - unsigned int CN0_dB_Hz = static_cast(std::round(CN0_dB_Hz_est / 0.25)); + uint32_t CN0_dB_Hz = static_cast(std::round(CN0_dB_Hz_est / 0.25)); DF050 = std::bitset<8>(CN0_dB_Hz); return 0; } -int Rtcm::set_DF051(const Gps_Ephemeris& gps_eph, double obs_time) +int32_t Rtcm::set_DF051(const Gps_Ephemeris& gps_eph, double obs_time) { const double gps_t = obs_time; - boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((gps_t + 604800 * static_cast(gps_eph.i_GPS_week % 1024)) * 1000)); + boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((gps_t + 604800 * static_cast(gps_eph.i_GPS_week % 1024)) * 1000)); boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); std::string now_ptime = to_iso_string(p_time); std::string today_ptime = now_ptime.substr(0, 8); boost::gregorian::date d(boost::gregorian::from_undelimited_string(today_ptime)); - unsigned int mjd = d.modjulian_day(); + uint32_t mjd = d.modjulian_day(); DF051 = std::bitset<16>(mjd); return 0; } -int Rtcm::set_DF052(const Gps_Ephemeris& gps_eph, double obs_time) +int32_t Rtcm::set_DF052(const Gps_Ephemeris& gps_eph, double obs_time) { const double gps_t = obs_time; - boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((gps_t + 604800 * static_cast(gps_eph.i_GPS_week % 1024)) * 1000)); + boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast((gps_t + 604800 * static_cast(gps_eph.i_GPS_week % 1024)) * 1000)); boost::posix_time::ptime p_time(boost::gregorian::date(1999, 8, 22), t); std::string now_ptime = to_iso_string(p_time); std::string hours = now_ptime.substr(9, 2); std::string minutes = now_ptime.substr(11, 2); std::string seconds = now_ptime.substr(13, 8); //boost::gregorian::date d(boost::gregorian::from_undelimited_string(today_ptime)); - long unsigned int seconds_of_day = boost::lexical_cast(hours) * 60 * 60 + boost::lexical_cast(minutes) * 60 + boost::lexical_cast(seconds); + uint32_t seconds_of_day = boost::lexical_cast(hours) * 60 * 60 + boost::lexical_cast(minutes) * 60 + boost::lexical_cast(seconds); DF052 = std::bitset<17>(seconds_of_day); return 0; } -int Rtcm::set_DF071(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF071(const Gps_Ephemeris& gps_eph) { - unsigned int iode = static_cast(gps_eph.d_IODE_SF2); + uint32_t iode = static_cast(gps_eph.d_IODE_SF2); DF071 = std::bitset<8>(iode); return 0; } -int Rtcm::set_DF076(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF076(const Gps_Ephemeris& gps_eph) { - unsigned int week_number = static_cast(gps_eph.i_GPS_week); + uint32_t week_number = static_cast(gps_eph.i_GPS_week); DF076 = std::bitset<10>(week_number); return 0; } -int Rtcm::set_DF077(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF077(const Gps_Ephemeris& gps_eph) { - unsigned short int ura = static_cast(gps_eph.i_SV_accuracy); + uint16_t ura = static_cast(gps_eph.i_SV_accuracy); DF077 = std::bitset<4>(ura); return 0; } -int Rtcm::set_DF078(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF078(const Gps_Ephemeris& gps_eph) { - unsigned short int code_on_L2 = static_cast(gps_eph.i_code_on_L2); + uint16_t code_on_L2 = static_cast(gps_eph.i_code_on_L2); DF078 = std::bitset<2>(code_on_L2); return 0; } -int Rtcm::set_DF079(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF079(const Gps_Ephemeris& gps_eph) { - unsigned int idot = static_cast(std::round(gps_eph.d_IDOT / I_DOT_LSB)); + uint32_t idot = static_cast(std::round(gps_eph.d_IDOT / I_DOT_LSB)); DF079 = std::bitset<14>(idot); return 0; } -int Rtcm::set_DF080(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF080(const Gps_Ephemeris& gps_eph) { - unsigned short int iode = static_cast(gps_eph.d_IODE_SF2); + uint16_t iode = static_cast(gps_eph.d_IODE_SF2); DF080 = std::bitset<8>(iode); return 0; } -int Rtcm::set_DF081(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF081(const Gps_Ephemeris& gps_eph) { - unsigned int toc = static_cast(std::round(gps_eph.d_Toc / T_OC_LSB)); + uint32_t toc = static_cast(std::round(gps_eph.d_Toc / T_OC_LSB)); DF081 = std::bitset<16>(toc); return 0; } -int Rtcm::set_DF082(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF082(const Gps_Ephemeris& gps_eph) { - short int af2 = static_cast(std::round(gps_eph.d_A_f2 / A_F2_LSB)); + int16_t af2 = static_cast(std::round(gps_eph.d_A_f2 / A_F2_LSB)); DF082 = std::bitset<8>(af2); return 0; } -int Rtcm::set_DF083(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF083(const Gps_Ephemeris& gps_eph) { - int af1 = static_cast(std::round(gps_eph.d_A_f1 / A_F1_LSB)); + int32_t af1 = static_cast(std::round(gps_eph.d_A_f1 / A_F1_LSB)); DF083 = std::bitset<16>(af1); return 0; } -int Rtcm::set_DF084(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF084(const Gps_Ephemeris& gps_eph) { - long int af0 = static_cast(std::round(gps_eph.d_A_f0 / A_F0_LSB)); + int64_t af0 = static_cast(std::round(gps_eph.d_A_f0 / A_F0_LSB)); DF084 = std::bitset<22>(af0); return 0; } -int Rtcm::set_DF085(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF085(const Gps_Ephemeris& gps_eph) { - unsigned int iodc = static_cast(gps_eph.d_IODC); + uint32_t iodc = static_cast(gps_eph.d_IODC); DF085 = std::bitset<10>(iodc); return 0; } -int Rtcm::set_DF086(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF086(const Gps_Ephemeris& gps_eph) { - int crs = static_cast(std::round(gps_eph.d_Crs / C_RS_LSB)); + int32_t crs = static_cast(std::round(gps_eph.d_Crs / C_RS_LSB)); DF086 = std::bitset<16>(crs); return 0; } -int Rtcm::set_DF087(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF087(const Gps_Ephemeris& gps_eph) { - int delta_n = static_cast(std::round(gps_eph.d_Delta_n / DELTA_N_LSB)); + int32_t delta_n = static_cast(std::round(gps_eph.d_Delta_n / DELTA_N_LSB)); DF087 = std::bitset<16>(delta_n); return 0; } -int Rtcm::set_DF088(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF088(const Gps_Ephemeris& gps_eph) { - long int m0 = static_cast(std::round(gps_eph.d_M_0 / M_0_LSB)); + int64_t m0 = static_cast(std::round(gps_eph.d_M_0 / M_0_LSB)); DF088 = std::bitset<32>(m0); return 0; } -int Rtcm::set_DF089(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF089(const Gps_Ephemeris& gps_eph) { - int cuc = static_cast(std::round(gps_eph.d_Cuc / C_UC_LSB)); + int32_t cuc = static_cast(std::round(gps_eph.d_Cuc / C_UC_LSB)); DF089 = std::bitset<16>(cuc); return 0; } -int Rtcm::set_DF090(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF090(const Gps_Ephemeris& gps_eph) { - unsigned long int ecc = static_cast(std::round(gps_eph.d_e_eccentricity / E_LSB)); + uint64_t ecc = static_cast(std::round(gps_eph.d_e_eccentricity / E_LSB)); DF090 = std::bitset<32>(ecc); return 0; } -int Rtcm::set_DF091(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF091(const Gps_Ephemeris& gps_eph) { - int cus = static_cast(std::round(gps_eph.d_Cus / C_US_LSB)); + int32_t cus = static_cast(std::round(gps_eph.d_Cus / C_US_LSB)); DF091 = std::bitset<16>(cus); return 0; } -int Rtcm::set_DF092(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF092(const Gps_Ephemeris& gps_eph) { - unsigned long int sqr_a = static_cast(std::round(gps_eph.d_sqrt_A / SQRT_A_LSB)); + uint64_t sqr_a = static_cast(std::round(gps_eph.d_sqrt_A / SQRT_A_LSB)); DF092 = std::bitset<32>(sqr_a); return 0; } -int Rtcm::set_DF093(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF093(const Gps_Ephemeris& gps_eph) { - unsigned int toe = static_cast(std::round(gps_eph.d_Toe / T_OE_LSB)); + uint32_t toe = static_cast(std::round(gps_eph.d_Toe / T_OE_LSB)); DF093 = std::bitset<16>(toe); return 0; } -int Rtcm::set_DF094(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF094(const Gps_Ephemeris& gps_eph) { - int cic = static_cast(std::round(gps_eph.d_Cic / C_IC_LSB)); + int32_t cic = static_cast(std::round(gps_eph.d_Cic / C_IC_LSB)); DF094 = std::bitset<16>(cic); return 0; } -int Rtcm::set_DF095(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF095(const Gps_Ephemeris& gps_eph) { - long int Omega0 = static_cast(std::round(gps_eph.d_OMEGA0 / OMEGA_0_LSB)); + int64_t Omega0 = static_cast(std::round(gps_eph.d_OMEGA0 / OMEGA_0_LSB)); DF095 = std::bitset<32>(Omega0); return 0; } -int Rtcm::set_DF096(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF096(const Gps_Ephemeris& gps_eph) { - int cis = static_cast(std::round(gps_eph.d_Cis / C_IS_LSB)); + int32_t cis = static_cast(std::round(gps_eph.d_Cis / C_IS_LSB)); DF096 = std::bitset<16>(cis); return 0; } -int Rtcm::set_DF097(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF097(const Gps_Ephemeris& gps_eph) { - long int i0 = static_cast(std::round(gps_eph.d_i_0 / I_0_LSB)); + int64_t i0 = static_cast(std::round(gps_eph.d_i_0 / I_0_LSB)); DF097 = std::bitset<32>(i0); return 0; } -int Rtcm::set_DF098(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF098(const Gps_Ephemeris& gps_eph) { - int crc = static_cast(std::round(gps_eph.d_Crc / C_RC_LSB)); + int32_t crc = static_cast(std::round(gps_eph.d_Crc / C_RC_LSB)); DF098 = std::bitset<16>(crc); return 0; } -int Rtcm::set_DF099(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF099(const Gps_Ephemeris& gps_eph) { - long int omega = static_cast(std::round(gps_eph.d_OMEGA / OMEGA_LSB)); + int64_t omega = static_cast(std::round(gps_eph.d_OMEGA / OMEGA_LSB)); DF099 = std::bitset<32>(omega); return 0; } -int Rtcm::set_DF100(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF100(const Gps_Ephemeris& gps_eph) { - long int omegadot = static_cast(std::round(gps_eph.d_OMEGA_DOT / OMEGA_DOT_LSB)); + int64_t omegadot = static_cast(std::round(gps_eph.d_OMEGA_DOT / OMEGA_DOT_LSB)); DF100 = std::bitset<24>(omegadot); return 0; } -int Rtcm::set_DF101(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF101(const Gps_Ephemeris& gps_eph) { - short int tgd = static_cast(std::round(gps_eph.d_TGD / T_GD_LSB)); + int16_t tgd = static_cast(std::round(gps_eph.d_TGD / T_GD_LSB)); DF101 = std::bitset<8>(tgd); return 0; } -int Rtcm::set_DF102(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF102(const Gps_Ephemeris& gps_eph) { - unsigned short int sv_heath = static_cast(gps_eph.i_SV_health); + uint16_t sv_heath = static_cast(gps_eph.i_SV_health); DF102 = std::bitset<6>(sv_heath); return 0; } -int Rtcm::set_DF103(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF103(const Gps_Ephemeris& gps_eph) { DF103 = std::bitset<1>(gps_eph.b_L2_P_data_flag); return 0; } -int Rtcm::set_DF104(unsigned int glonass_gnav_alm_health) +int32_t Rtcm::set_DF104(uint32_t glonass_gnav_alm_health) { DF104 = std::bitset<1>(glonass_gnav_alm_health); return 0; } -int Rtcm::set_DF105(unsigned int glonass_gnav_alm_health_ind) +int32_t Rtcm::set_DF105(uint32_t glonass_gnav_alm_health_ind) { DF105 = std::bitset<1>(glonass_gnav_alm_health_ind); return 0; } -int Rtcm::set_DF106(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF106(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { // Convert the value from (15, 30, 45, 60) to (00, 01, 10, 11) - unsigned int P_1 = static_cast(std::round(glonass_gnav_eph.d_P_1 / 15.0 - 1.0)); + uint32_t P_1 = static_cast(std::round(glonass_gnav_eph.d_P_1 / 15.0 - 1.0)); DF106 = std::bitset<2>(P_1); return 0; } -int Rtcm::set_DF107(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF107(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int hrs = 0; - unsigned int min = 0; - unsigned int sec = 0; - unsigned int tk = 0; - tk = static_cast(glonass_gnav_eph.d_t_k); + uint32_t hrs = 0; + uint32_t min = 0; + uint32_t sec = 0; + uint32_t tk = 0; + tk = static_cast(glonass_gnav_eph.d_t_k); hrs = tk / 3600; min = (tk - hrs * 3600) / 60; sec = (tk - hrs * 3600 - min * 60) / 60; @@ -4360,32 +4362,32 @@ int Rtcm::set_DF107(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF108(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF108(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { DF108 = std::bitset<1>(glonass_gnav_eph.d_B_n); return 0; } -int Rtcm::set_DF109(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF109(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { DF109 = std::bitset<1>(glonass_gnav_eph.d_P_2); return 0; } -int Rtcm::set_DF110(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF110(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int t_b = static_cast(std::round(glonass_gnav_eph.d_t_b / (15 * 60))); + uint32_t t_b = static_cast(std::round(glonass_gnav_eph.d_t_b / (15 * 60))); DF110 = std::bitset<7>(t_b); return 0; } -int Rtcm::set_DF111(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF111(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int VXn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_VXn / TWO_N20))); - unsigned int VXn_sgn = glo_sgn(glonass_gnav_eph.d_VXn); + int32_t VXn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_VXn / TWO_N20))); + uint32_t VXn_sgn = glo_sgn(glonass_gnav_eph.d_VXn); DF111 = std::bitset<24>(VXn_mag); DF111.set(23, VXn_sgn); @@ -4393,10 +4395,10 @@ int Rtcm::set_DF111(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF112(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF112(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int Xn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Xn / TWO_N11))); - unsigned int Xn_sgn = glo_sgn(glonass_gnav_eph.d_Xn); + int32_t Xn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Xn / TWO_N11))); + uint32_t Xn_sgn = glo_sgn(glonass_gnav_eph.d_Xn); DF112 = std::bitset<27>(Xn_mag); DF112.set(26, Xn_sgn); @@ -4404,10 +4406,10 @@ int Rtcm::set_DF112(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF113(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF113(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int AXn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_AXn / TWO_N30))); - unsigned int AXn_sgn = glo_sgn(glonass_gnav_eph.d_AXn); + int32_t AXn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_AXn / TWO_N30))); + uint32_t AXn_sgn = glo_sgn(glonass_gnav_eph.d_AXn); DF113 = std::bitset<5>(AXn_mag); DF113.set(4, AXn_sgn); @@ -4415,10 +4417,10 @@ int Rtcm::set_DF113(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF114(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF114(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int VYn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_VYn / TWO_N20))); - unsigned int VYn_sgn = glo_sgn(glonass_gnav_eph.d_VYn); + int32_t VYn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_VYn / TWO_N20))); + uint32_t VYn_sgn = glo_sgn(glonass_gnav_eph.d_VYn); DF114 = std::bitset<24>(VYn_mag); DF114.set(23, VYn_sgn); @@ -4426,10 +4428,10 @@ int Rtcm::set_DF114(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF115(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF115(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int Yn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Yn / TWO_N11))); - unsigned int Yn_sgn = glo_sgn(glonass_gnav_eph.d_Yn); + int32_t Yn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Yn / TWO_N11))); + uint32_t Yn_sgn = glo_sgn(glonass_gnav_eph.d_Yn); DF115 = std::bitset<27>(Yn_mag); DF115.set(26, Yn_sgn); @@ -4437,10 +4439,10 @@ int Rtcm::set_DF115(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF116(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF116(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int AYn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_AYn / TWO_N30))); - unsigned int AYn_sgn = glo_sgn(glonass_gnav_eph.d_AYn); + int32_t AYn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_AYn / TWO_N30))); + uint32_t AYn_sgn = glo_sgn(glonass_gnav_eph.d_AYn); DF116 = std::bitset<5>(AYn_mag); DF116.set(4, AYn_sgn); @@ -4448,10 +4450,10 @@ int Rtcm::set_DF116(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF117(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF117(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int VZn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_VZn / TWO_N20))); - unsigned int VZn_sgn = glo_sgn(glonass_gnav_eph.d_VZn); + int32_t VZn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_VZn / TWO_N20))); + uint32_t VZn_sgn = glo_sgn(glonass_gnav_eph.d_VZn); DF117 = std::bitset<24>(VZn_mag); DF117.set(23, VZn_sgn); @@ -4459,10 +4461,10 @@ int Rtcm::set_DF117(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF118(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF118(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int Zn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Zn / TWO_N11))); - unsigned int Zn_sgn = glo_sgn(glonass_gnav_eph.d_Zn); + int32_t Zn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Zn / TWO_N11))); + uint32_t Zn_sgn = glo_sgn(glonass_gnav_eph.d_Zn); DF118 = std::bitset<27>(Zn_mag); DF118.set(26, Zn_sgn); @@ -4470,10 +4472,10 @@ int Rtcm::set_DF118(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF119(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF119(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int AZn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_AZn / TWO_N30))); - unsigned int AZn_sgn = glo_sgn(glonass_gnav_eph.d_AZn); + int32_t AZn_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_AZn / TWO_N30))); + uint32_t AZn_sgn = glo_sgn(glonass_gnav_eph.d_AZn); DF119 = std::bitset<5>(AZn_mag); DF119.set(4, AZn_sgn); @@ -4481,18 +4483,18 @@ int Rtcm::set_DF119(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF120(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF120(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int P3 = static_cast(std::round(glonass_gnav_eph.d_P_3)); + uint32_t P3 = static_cast(std::round(glonass_gnav_eph.d_P_3)); DF120 = std::bitset<1>(P3); return 0; } -int Rtcm::set_DF121(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF121(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int gamma_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_gamma_n / TWO_N40))); - unsigned int gamma_sgn = glo_sgn(glonass_gnav_eph.d_gamma_n); + int32_t gamma_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_gamma_n / TWO_N40))); + uint32_t gamma_sgn = glo_sgn(glonass_gnav_eph.d_gamma_n); DF121 = std::bitset<11>(gamma_mag); DF121.set(10, gamma_sgn); @@ -4500,26 +4502,26 @@ int Rtcm::set_DF121(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF122(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF122(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int P = static_cast(std::round(glonass_gnav_eph.d_P)); + uint32_t P = static_cast(std::round(glonass_gnav_eph.d_P)); DF122 = std::bitset<2>(P); return 0; } -int Rtcm::set_DF123(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF123(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int ln = static_cast((glonass_gnav_eph.d_l3rd_n)); + uint32_t ln = static_cast((glonass_gnav_eph.d_l3rd_n)); DF123 = std::bitset<1>(ln); return 0; } -int Rtcm::set_DF124(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF124(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int tau_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_tau_n / TWO_N30))); - unsigned int tau_sgn = glo_sgn(glonass_gnav_eph.d_tau_n); + int32_t tau_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_tau_n / TWO_N30))); + uint32_t tau_sgn = glo_sgn(glonass_gnav_eph.d_tau_n); DF124 = std::bitset<22>(tau_mag); DF124.set(21, tau_sgn); @@ -4527,10 +4529,10 @@ int Rtcm::set_DF124(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF125(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF125(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - int delta_tau_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Delta_tau_n / TWO_N30))); - unsigned int delta_tau_sgn = glo_sgn(glonass_gnav_eph.d_Delta_tau_n); + int32_t delta_tau_mag = static_cast(std::round(fabs(glonass_gnav_eph.d_Delta_tau_n / TWO_N30))); + uint32_t delta_tau_sgn = glo_sgn(glonass_gnav_eph.d_Delta_tau_n); DF125 = std::bitset<5>(delta_tau_mag); DF125.set(4, delta_tau_sgn); @@ -4538,105 +4540,105 @@ int Rtcm::set_DF125(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) } -int Rtcm::set_DF126(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF126(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int ecc = static_cast(std::round(glonass_gnav_eph.d_E_n)); + uint32_t ecc = static_cast(std::round(glonass_gnav_eph.d_E_n)); DF126 = std::bitset<5>(ecc); return 0; } -int Rtcm::set_DF127(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF127(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int P4 = static_cast(std::round(glonass_gnav_eph.d_P_4)); + uint32_t P4 = static_cast(std::round(glonass_gnav_eph.d_P_4)); DF127 = std::bitset<1>(P4); return 0; } -int Rtcm::set_DF128(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF128(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int F_t = static_cast(std::round(glonass_gnav_eph.d_F_T)); + uint32_t F_t = static_cast(std::round(glonass_gnav_eph.d_F_T)); DF128 = std::bitset<4>(F_t); return 0; } -int Rtcm::set_DF129(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF129(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int N_t = static_cast(std::round(glonass_gnav_eph.d_N_T)); + uint32_t N_t = static_cast(std::round(glonass_gnav_eph.d_N_T)); DF129 = std::bitset<11>(N_t); return 0; } -int Rtcm::set_DF130(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF130(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int M = static_cast(std::round(glonass_gnav_eph.d_M)); + uint32_t M = static_cast(std::round(glonass_gnav_eph.d_M)); DF130 = std::bitset<2>(M); return 0; } -int Rtcm::set_DF131(unsigned int fifth_str_additional_data_ind) +int32_t Rtcm::set_DF131(uint32_t fifth_str_additional_data_ind) { - unsigned int fith_str_data = static_cast(fifth_str_additional_data_ind); + uint32_t fith_str_data = static_cast(fifth_str_additional_data_ind); DF131 = std::bitset<1>(fith_str_data); return 0; } -int Rtcm::set_DF132(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) +int32_t Rtcm::set_DF132(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) { - unsigned int N_A = static_cast(std::round(glonass_gnav_utc_model.d_N_A)); + uint32_t N_A = static_cast(std::round(glonass_gnav_utc_model.d_N_A)); DF132 = std::bitset<11>(N_A); return 0; } -int Rtcm::set_DF133(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) +int32_t Rtcm::set_DF133(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) { - int tau_c = static_cast(std::round(glonass_gnav_utc_model.d_tau_c / TWO_N31)); + int32_t tau_c = static_cast(std::round(glonass_gnav_utc_model.d_tau_c / TWO_N31)); DF133 = std::bitset<32>(tau_c); return 0; } -int Rtcm::set_DF134(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) +int32_t Rtcm::set_DF134(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) { - unsigned int N_4 = static_cast(std::round(glonass_gnav_utc_model.d_N_4)); + uint32_t N_4 = static_cast(std::round(glonass_gnav_utc_model.d_N_4)); DF134 = std::bitset<5>(N_4); return 0; } -int Rtcm::set_DF135(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) +int32_t Rtcm::set_DF135(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model) { - int tau_gps = static_cast(std::round(glonass_gnav_utc_model.d_tau_gps) / TWO_N30); + int32_t tau_gps = static_cast(std::round(glonass_gnav_utc_model.d_tau_gps) / TWO_N30); DF135 = std::bitset<22>(tau_gps); return 0; } -int Rtcm::set_DF136(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) +int32_t Rtcm::set_DF136(const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - unsigned int l_n = static_cast(std::round(glonass_gnav_eph.d_l5th_n)); + uint32_t l_n = static_cast(std::round(glonass_gnav_eph.d_l5th_n)); DF136 = std::bitset<1>(l_n); return 0; } -int Rtcm::set_DF137(const Gps_Ephemeris& gps_eph) +int32_t Rtcm::set_DF137(const Gps_Ephemeris& gps_eph) { DF137 = std::bitset<1>(gps_eph.b_fit_interval_flag); return 0; } -int Rtcm::set_DF248(double obs_time) +int32_t Rtcm::set_DF248(double obs_time) { // TOW in milliseconds from the beginning of the Galileo week, measured in Galileo time - unsigned long int tow = static_cast(std::round(obs_time * 1000)); + uint64_t tow = static_cast(std::round(obs_time * 1000)); if (tow > 604799999) { LOG(WARNING) << "To large TOW! Set to the last millisecond of the week"; @@ -4647,9 +4649,9 @@ int Rtcm::set_DF248(double obs_time) } -int Rtcm::set_DF252(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF252(const Galileo_Ephemeris& gal_eph) { - unsigned int prn_ = gal_eph.i_satellite_PRN; + uint32_t prn_ = gal_eph.i_satellite_PRN; if (prn_ > 63) { LOG(WARNING) << "Galileo satellite ID must be between 0 and 63, but PRN " << prn_ << " was found"; @@ -4659,9 +4661,9 @@ int Rtcm::set_DF252(const Galileo_Ephemeris& gal_eph) } -int Rtcm::set_DF289(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF289(const Galileo_Ephemeris& gal_eph) { - unsigned int galileo_week_number = static_cast(gal_eph.WN_5); + uint32_t galileo_week_number = static_cast(gal_eph.WN_5); if (galileo_week_number > 4095) { LOG(WARNING) << "Error decoding Galileo week number (it has a 4096 roll-off, but " << galileo_week_number << " was detected)"; @@ -4671,9 +4673,9 @@ int Rtcm::set_DF289(const Galileo_Ephemeris& gal_eph) } -int Rtcm::set_DF290(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF290(const Galileo_Ephemeris& gal_eph) { - unsigned int iod_nav = static_cast(gal_eph.IOD_nav_1); + uint32_t iod_nav = static_cast(gal_eph.IOD_nav_1); if (iod_nav > 1023) { LOG(WARNING) << "Error decoding Galileo IODnav (it has a max of 1023, but " << iod_nav << " was detected)"; @@ -4683,26 +4685,26 @@ int Rtcm::set_DF290(const Galileo_Ephemeris& gal_eph) } -int Rtcm::set_DF291(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF291(const Galileo_Ephemeris& gal_eph) { - unsigned short int SISA = static_cast(gal_eph.SISA_3); + uint16_t SISA = static_cast(gal_eph.SISA_3); //SISA = 0; // SIS Accuracy, data content definition not given in Galileo OS SIS ICD, Issue 1.1, Sept 2010 DF291 = std::bitset<8>(SISA); return 0; } -int Rtcm::set_DF292(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF292(const Galileo_Ephemeris& gal_eph) { - int idot = static_cast(std::round(gal_eph.iDot_2 / FNAV_idot_2_LSB)); + int32_t idot = static_cast(std::round(gal_eph.iDot_2 / FNAV_idot_2_LSB)); DF292 = std::bitset<14>(idot); return 0; } -int Rtcm::set_DF293(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF293(const Galileo_Ephemeris& gal_eph) { - unsigned int toc = static_cast(gal_eph.t0c_4); + uint32_t toc = static_cast(gal_eph.t0c_4); if (toc > 604740) { LOG(WARNING) << "Error decoding Galileo ephemeris time (max of 604740, but " << toc << " was detected)"; @@ -4712,193 +4714,193 @@ int Rtcm::set_DF293(const Galileo_Ephemeris& gal_eph) } -int Rtcm::set_DF294(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF294(const Galileo_Ephemeris& gal_eph) { - short int af2 = static_cast(std::round(gal_eph.af2_4 / FNAV_af2_1_LSB)); + int16_t af2 = static_cast(std::round(gal_eph.af2_4 / FNAV_af2_1_LSB)); DF294 = std::bitset<6>(af2); return 0; } -int Rtcm::set_DF295(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF295(const Galileo_Ephemeris& gal_eph) { - long int af1 = static_cast(std::round(gal_eph.af1_4 / FNAV_af1_1_LSB)); + int64_t af1 = static_cast(std::round(gal_eph.af1_4 / FNAV_af1_1_LSB)); DF295 = std::bitset<21>(af1); return 0; } -int Rtcm::set_DF296(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF296(const Galileo_Ephemeris& gal_eph) { - long int af0 = static_cast(std::round(gal_eph.af0_4 / FNAV_af0_1_LSB)); + int64_t af0 = static_cast(std::round(gal_eph.af0_4 / FNAV_af0_1_LSB)); DF296 = std::bitset<31>(af0); return 0; } -int Rtcm::set_DF297(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF297(const Galileo_Ephemeris& gal_eph) { - int crs = static_cast(std::round(gal_eph.C_rs_3 / FNAV_Crs_3_LSB)); + int32_t crs = static_cast(std::round(gal_eph.C_rs_3 / FNAV_Crs_3_LSB)); DF297 = std::bitset<16>(crs); return 0; } -int Rtcm::set_DF298(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF298(const Galileo_Ephemeris& gal_eph) { - int delta_n = static_cast(std::round(gal_eph.delta_n_3 / FNAV_deltan_3_LSB)); + int32_t delta_n = static_cast(std::round(gal_eph.delta_n_3 / FNAV_deltan_3_LSB)); DF298 = std::bitset<16>(delta_n); return 0; } -int Rtcm::set_DF299(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF299(const Galileo_Ephemeris& gal_eph) { - long int m0 = static_cast(std::round(gal_eph.M0_1 / FNAV_M0_2_LSB)); + int64_t m0 = static_cast(std::round(gal_eph.M0_1 / FNAV_M0_2_LSB)); DF299 = std::bitset<32>(m0); return 0; } -int Rtcm::set_DF300(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF300(const Galileo_Ephemeris& gal_eph) { - int cuc = static_cast(std::round(gal_eph.C_uc_3 / FNAV_Cuc_3_LSB)); + int32_t cuc = static_cast(std::round(gal_eph.C_uc_3 / FNAV_Cuc_3_LSB)); DF300 = std::bitset<16>(cuc); return 0; } -int Rtcm::set_DF301(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF301(const Galileo_Ephemeris& gal_eph) { - unsigned long int ecc = static_cast(std::round(gal_eph.e_1 / FNAV_e_2_LSB)); + uint64_t ecc = static_cast(std::round(gal_eph.e_1 / FNAV_e_2_LSB)); DF301 = std::bitset<32>(ecc); return 0; } -int Rtcm::set_DF302(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF302(const Galileo_Ephemeris& gal_eph) { - int cus = static_cast(std::round(gal_eph.C_us_3 / FNAV_Cus_3_LSB)); + int32_t cus = static_cast(std::round(gal_eph.C_us_3 / FNAV_Cus_3_LSB)); DF302 = std::bitset<16>(cus); return 0; } -int Rtcm::set_DF303(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF303(const Galileo_Ephemeris& gal_eph) { - unsigned long int sqr_a = static_cast(std::round(gal_eph.A_1 / FNAV_a12_2_LSB)); + uint64_t sqr_a = static_cast(std::round(gal_eph.A_1 / FNAV_a12_2_LSB)); DF303 = std::bitset<32>(sqr_a); return 0; } -int Rtcm::set_DF304(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF304(const Galileo_Ephemeris& gal_eph) { - unsigned int toe = static_cast(std::round(gal_eph.t0e_1 / FNAV_t0e_3_LSB)); + uint32_t toe = static_cast(std::round(gal_eph.t0e_1 / FNAV_t0e_3_LSB)); DF304 = std::bitset<14>(toe); return 0; } -int Rtcm::set_DF305(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF305(const Galileo_Ephemeris& gal_eph) { - int cic = static_cast(std::round(gal_eph.C_ic_4 / FNAV_Cic_4_LSB)); + int32_t cic = static_cast(std::round(gal_eph.C_ic_4 / FNAV_Cic_4_LSB)); DF305 = std::bitset<16>(cic); return 0; } -int Rtcm::set_DF306(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF306(const Galileo_Ephemeris& gal_eph) { - long int Omega0 = static_cast(std::round(gal_eph.OMEGA_0_2 / FNAV_omega0_2_LSB)); + int64_t Omega0 = static_cast(std::round(gal_eph.OMEGA_0_2 / FNAV_omega0_2_LSB)); DF306 = std::bitset<32>(Omega0); return 0; } -int Rtcm::set_DF307(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF307(const Galileo_Ephemeris& gal_eph) { - int cis = static_cast(std::round(gal_eph.C_is_4 / FNAV_Cis_4_LSB)); + int32_t cis = static_cast(std::round(gal_eph.C_is_4 / FNAV_Cis_4_LSB)); DF307 = std::bitset<16>(cis); return 0; } -int Rtcm::set_DF308(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF308(const Galileo_Ephemeris& gal_eph) { - long int i0 = static_cast(std::round(gal_eph.i_0_2 / FNAV_i0_3_LSB)); + int64_t i0 = static_cast(std::round(gal_eph.i_0_2 / FNAV_i0_3_LSB)); DF308 = std::bitset<32>(i0); return 0; } -int Rtcm::set_DF309(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF309(const Galileo_Ephemeris& gal_eph) { - int crc = static_cast(std::round(gal_eph.C_rc_3 / FNAV_Crc_3_LSB)); + int32_t crc = static_cast(std::round(gal_eph.C_rc_3 / FNAV_Crc_3_LSB)); DF309 = std::bitset<16>(crc); return 0; } -int Rtcm::set_DF310(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF310(const Galileo_Ephemeris& gal_eph) { - int omega = static_cast(std::round(gal_eph.omega_2 / FNAV_omega0_2_LSB)); + int32_t omega = static_cast(std::round(gal_eph.omega_2 / FNAV_omega0_2_LSB)); DF310 = std::bitset<32>(omega); return 0; } -int Rtcm::set_DF311(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF311(const Galileo_Ephemeris& gal_eph) { - long int Omegadot = static_cast(std::round(gal_eph.OMEGA_dot_3 / FNAV_omegadot_2_LSB)); + int64_t Omegadot = static_cast(std::round(gal_eph.OMEGA_dot_3 / FNAV_omegadot_2_LSB)); DF311 = std::bitset<24>(Omegadot); return 0; } -int Rtcm::set_DF312(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF312(const Galileo_Ephemeris& gal_eph) { - int bdg_E1_E5a = static_cast(std::round(gal_eph.BGD_E1E5a_5 / FNAV_BGD_1_LSB)); + int32_t bdg_E1_E5a = static_cast(std::round(gal_eph.BGD_E1E5a_5 / FNAV_BGD_1_LSB)); DF312 = std::bitset<10>(bdg_E1_E5a); return 0; } -int Rtcm::set_DF313(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF313(const Galileo_Ephemeris& gal_eph) { - unsigned int bdg_E5b_E1 = static_cast(std::round(gal_eph.BGD_E1E5b_5)); + uint32_t bdg_E5b_E1 = static_cast(std::round(gal_eph.BGD_E1E5b_5)); //bdg_E5b_E1 = 0; //reserved DF313 = std::bitset<10>(bdg_E5b_E1); return 0; } -int Rtcm::set_DF314(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF314(const Galileo_Ephemeris& gal_eph) { DF314 = std::bitset<2>(gal_eph.E5a_HS); return 0; } -int Rtcm::set_DF315(const Galileo_Ephemeris& gal_eph) +int32_t Rtcm::set_DF315(const Galileo_Ephemeris& gal_eph) { DF315 = std::bitset<1>(gal_eph.E5a_DVS); return 0; } -int Rtcm::set_DF393(bool more_messages) +int32_t Rtcm::set_DF393(bool more_messages) { DF393 = std::bitset<1>(more_messages); return 0; } -int Rtcm::set_DF394(const std::map& gnss_synchro) +int32_t Rtcm::set_DF394(const std::map& gnss_synchro) { DF394.reset(); - std::map::const_iterator gnss_synchro_iter; - unsigned int mask_position; + std::map::const_iterator gnss_synchro_iter; + uint32_t mask_position; for (gnss_synchro_iter = gnss_synchro.cbegin(); gnss_synchro_iter != gnss_synchro.cend(); gnss_synchro_iter++) @@ -4910,16 +4912,16 @@ int Rtcm::set_DF394(const std::map& gnss_synchro) } -int Rtcm::set_DF395(const std::map& gnss_synchro) +int32_t Rtcm::set_DF395(const std::map& gnss_synchro) { DF395.reset(); if (gnss_synchro.size() == 0) { return 1; } - std::map::const_iterator gnss_synchro_iter; + std::map::const_iterator gnss_synchro_iter; std::string sig; - unsigned int mask_position; + uint32_t mask_position; for (gnss_synchro_iter = gnss_synchro.cbegin(); gnss_synchro_iter != gnss_synchro.cend(); gnss_synchro_iter++) @@ -4977,14 +4979,14 @@ int Rtcm::set_DF395(const std::map& gnss_synchro) } -std::string Rtcm::set_DF396(const std::map& observables) +std::string Rtcm::set_DF396(const std::map& observables) { std::string DF396; - std::map::const_iterator observables_iter; + std::map::const_iterator observables_iter; Rtcm::set_DF394(observables); Rtcm::set_DF395(observables); - unsigned int num_signals = DF395.count(); - unsigned int num_satellites = DF394.count(); + uint32_t num_signals = DF395.count(); + uint32_t num_satellites = DF394.count(); if ((num_signals == 0) || (num_satellites == 0)) { @@ -4994,7 +4996,7 @@ std::string Rtcm::set_DF396(const std::map& observables) std::vector > matrix(num_signals, std::vector()); std::string sig; - std::vector list_of_sats; + std::vector list_of_sats; std::vector list_of_signals; for (observables_iter = observables.cbegin(); @@ -5046,9 +5048,9 @@ std::string Rtcm::set_DF396(const std::map& observables) // fill the matrix bool value; - for (unsigned int row = 0; row < num_signals; row++) + for (uint32_t row = 0; row < num_signals; row++) { - for (unsigned int sat = 0; sat < num_satellites; sat++) + for (uint32_t sat = 0; sat < num_satellites; sat++) { value = false; for (observables_iter = observables.cbegin(); @@ -5095,9 +5097,9 @@ std::string Rtcm::set_DF396(const std::map& observables) // write the matrix column-wise DF396.clear(); - for (unsigned int col = 0; col < num_satellites; col++) + for (uint32_t col = 0; col < num_satellites; col++) { - for (unsigned int row = 0; row < num_signals; row++) + for (uint32_t row = 0; row < num_signals; row++) { std::string ss; if (matrix[row].at(col)) @@ -5115,12 +5117,12 @@ std::string Rtcm::set_DF396(const std::map& observables) } -int Rtcm::set_DF397(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF397(const Gnss_Synchro& gnss_synchro) { double meters_to_miliseconds = GPS_C_m_s * 0.001; double rough_range_s = std::round(gnss_synchro.Pseudorange_m / meters_to_miliseconds / TWO_N10) * meters_to_miliseconds * TWO_N10; - unsigned int int_ms = 0; + uint32_t int_ms = 0; if (rough_range_s == 0.0) { @@ -5132,7 +5134,7 @@ int Rtcm::set_DF397(const Gnss_Synchro& gnss_synchro) } else { - int_ms = static_cast(std::floor(rough_range_s / meters_to_miliseconds / TWO_N10) + 0.5) >> 10; + int_ms = static_cast(std::floor(rough_range_s / meters_to_miliseconds / TWO_N10) + 0.5) >> 10; } DF397 = std::bitset<8>(int_ms); @@ -5140,25 +5142,25 @@ int Rtcm::set_DF397(const Gnss_Synchro& gnss_synchro) } -int Rtcm::set_DF398(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF398(const Gnss_Synchro& gnss_synchro) { double meters_to_miliseconds = GPS_C_m_s * 0.001; double rough_range_m = std::round(gnss_synchro.Pseudorange_m / meters_to_miliseconds / TWO_N10) * meters_to_miliseconds * TWO_N10; - unsigned int rr_mod_ms; + uint32_t rr_mod_ms; if ((rough_range_m <= 0.0) || (rough_range_m > meters_to_miliseconds * 255.0)) { rr_mod_ms = 0; } else { - rr_mod_ms = static_cast(std::floor(rough_range_m / meters_to_miliseconds / TWO_N10) + 0.5) & 0x3FFu; + rr_mod_ms = static_cast(std::floor(rough_range_m / meters_to_miliseconds / TWO_N10) + 0.5) & 0x3FFu; } DF398 = std::bitset<10>(rr_mod_ms); return 0; } -int Rtcm::set_DF399(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF399(const Gnss_Synchro& gnss_synchro) { double lambda = 0.0; std::string sig_(gnss_synchro.Signal); @@ -5189,17 +5191,17 @@ int Rtcm::set_DF399(const Gnss_Synchro& gnss_synchro) if (rough_phase_range_rate_ms < -8191) rough_phase_range_rate_ms = -8192; if (rough_phase_range_rate_ms > 8191) rough_phase_range_rate_ms = -8192; - DF399 = std::bitset<14>(static_cast(rough_phase_range_rate_ms)); + DF399 = std::bitset<14>(static_cast(rough_phase_range_rate_ms)); return 0; } -int Rtcm::set_DF400(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF400(const Gnss_Synchro& gnss_synchro) { double meters_to_miliseconds = GPS_C_m_s * 0.001; double rough_range_m = std::round(gnss_synchro.Pseudorange_m / meters_to_miliseconds / TWO_N10) * meters_to_miliseconds * TWO_N10; double psrng_s; - int fine_pseudorange; + int32_t fine_pseudorange; psrng_s = gnss_synchro.Pseudorange_m - rough_range_m; @@ -5213,7 +5215,7 @@ int Rtcm::set_DF400(const Gnss_Synchro& gnss_synchro) } else { - fine_pseudorange = static_cast(std::round(psrng_s / meters_to_miliseconds / TWO_N24)); + fine_pseudorange = static_cast(std::round(psrng_s / meters_to_miliseconds / TWO_N24)); } DF400 = std::bitset<15>(fine_pseudorange); @@ -5221,12 +5223,12 @@ int Rtcm::set_DF400(const Gnss_Synchro& gnss_synchro) } -int Rtcm::set_DF401(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF401(const Gnss_Synchro& gnss_synchro) { double meters_to_miliseconds = GPS_C_m_s * 0.001; double rough_range_m = std::round(gnss_synchro.Pseudorange_m / meters_to_miliseconds / TWO_N10) * meters_to_miliseconds * TWO_N10; double phrng_m; - long int fine_phaserange; + int64_t fine_phaserange; double lambda = 0.0; std::string sig_(gnss_synchro.Signal); @@ -5284,7 +5286,7 @@ int Rtcm::set_DF401(const Gnss_Synchro& gnss_synchro) } else { - fine_phaserange = static_cast(std::round(phrng_m / meters_to_miliseconds / TWO_N29)); + fine_phaserange = static_cast(std::round(phrng_m / meters_to_miliseconds / TWO_N29)); } DF401 = std::bitset<22>(fine_phaserange); @@ -5292,10 +5294,10 @@ int Rtcm::set_DF401(const Gnss_Synchro& gnss_synchro) } -int Rtcm::set_DF402(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF402(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const Gnss_Synchro& gnss_synchro) { - unsigned int lock_time_period_s = 0; - unsigned int lock_time_indicator; + uint32_t lock_time_period_s = 0; + uint32_t lock_time_indicator; std::string sig_(gnss_synchro.Signal); std::string sys(&gnss_synchro.System, 1); if ((sig_.compare("1C") == 0) && (sys.compare("G") == 0)) @@ -5325,21 +5327,21 @@ int Rtcm::set_DF402(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCN } -int Rtcm::set_DF403(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF403(const Gnss_Synchro& gnss_synchro) { - unsigned int cnr_dB_Hz; - cnr_dB_Hz = static_cast(std::round(gnss_synchro.CN0_dB_hz)); + uint32_t cnr_dB_Hz; + cnr_dB_Hz = static_cast(std::round(gnss_synchro.CN0_dB_hz)); DF403 = std::bitset<6>(cnr_dB_Hz); return 0; } -int Rtcm::set_DF404(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF404(const Gnss_Synchro& gnss_synchro) { double lambda = 0.0; std::string sig_(gnss_synchro.Signal); std::string sig = sig_.substr(0, 2); - int fine_phaserange_rate; + int32_t fine_phaserange_rate; std::string sys_(&gnss_synchro.System, 1); if ((sig_.compare("1C") == 0) && (sys_.compare("G") == 0)) @@ -5384,7 +5386,7 @@ int Rtcm::set_DF404(const Gnss_Synchro& gnss_synchro) } else { - fine_phaserange_rate = static_cast(std::round(phrr / 0.0001)); + fine_phaserange_rate = static_cast(std::round(phrr / 0.0001)); } DF404 = std::bitset<15>(fine_phaserange_rate); @@ -5392,12 +5394,12 @@ int Rtcm::set_DF404(const Gnss_Synchro& gnss_synchro) } -int Rtcm::set_DF405(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF405(const Gnss_Synchro& gnss_synchro) { double meters_to_miliseconds = GPS_C_m_s * 0.001; double rough_range_m = std::round(gnss_synchro.Pseudorange_m / meters_to_miliseconds / TWO_N10) * meters_to_miliseconds * TWO_N10; double psrng_s; - long int fine_pseudorange; + int64_t fine_pseudorange; psrng_s = gnss_synchro.Pseudorange_m - rough_range_m; @@ -5411,16 +5413,16 @@ int Rtcm::set_DF405(const Gnss_Synchro& gnss_synchro) } else { - fine_pseudorange = static_cast(std::round(psrng_s / meters_to_miliseconds / TWO_N29)); + fine_pseudorange = static_cast(std::round(psrng_s / meters_to_miliseconds / TWO_N29)); } DF405 = std::bitset<20>(fine_pseudorange); return 0; } -int Rtcm::set_DF406(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF406(const Gnss_Synchro& gnss_synchro) { - long int fine_phaserange_ex; + int64_t fine_phaserange_ex; double meters_to_miliseconds = GPS_C_m_s * 0.001; double rough_range_m = std::round(gnss_synchro.Pseudorange_m / meters_to_miliseconds / TWO_N10) * meters_to_miliseconds * TWO_N10; double phrng_m; @@ -5479,7 +5481,7 @@ int Rtcm::set_DF406(const Gnss_Synchro& gnss_synchro) } else { - fine_phaserange_ex = static_cast(std::round(phrng_m / meters_to_miliseconds / TWO_N31)); + fine_phaserange_ex = static_cast(std::round(phrng_m / meters_to_miliseconds / TWO_N31)); } DF406 = std::bitset<24>(fine_phaserange_ex); @@ -5487,10 +5489,10 @@ int Rtcm::set_DF406(const Gnss_Synchro& gnss_synchro) } -int Rtcm::set_DF407(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF407(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const Gnss_Synchro& gnss_synchro) { - unsigned int lock_time_indicator; - unsigned int lock_time_period_s = 0; + uint32_t lock_time_indicator; + uint32_t lock_time_period_s = 0; std::string sig_(gnss_synchro.Signal); std::string sys_(&gnss_synchro.System, 1); @@ -5520,44 +5522,44 @@ int Rtcm::set_DF407(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCN } -int Rtcm::set_DF408(const Gnss_Synchro& gnss_synchro) +int32_t Rtcm::set_DF408(const Gnss_Synchro& gnss_synchro) { - unsigned int cnr_dB_Hz; - cnr_dB_Hz = static_cast(std::round(gnss_synchro.CN0_dB_hz / 0.0625)); + uint32_t cnr_dB_Hz; + cnr_dB_Hz = static_cast(std::round(gnss_synchro.CN0_dB_hz / 0.0625)); DF408 = std::bitset<10>(cnr_dB_Hz); return 0; } -int Rtcm::set_DF409(unsigned int iods) +int32_t Rtcm::set_DF409(uint32_t iods) { DF409 = std::bitset<3>(iods); return 0; } -int Rtcm::set_DF411(unsigned int clock_steering_indicator) +int32_t Rtcm::set_DF411(uint32_t clock_steering_indicator) { DF411 = std::bitset<2>(clock_steering_indicator); return 0; } -int Rtcm::set_DF412(unsigned int external_clock_indicator) +int32_t Rtcm::set_DF412(uint32_t external_clock_indicator) { DF412 = std::bitset<2>(external_clock_indicator); return 0; } -int Rtcm::set_DF417(bool using_divergence_free_smoothing) +int32_t Rtcm::set_DF417(bool using_divergence_free_smoothing) { DF417 = std::bitset<1>(using_divergence_free_smoothing); return 0; } -int Rtcm::set_DF418(int carrier_smoothing_interval_s) +int32_t Rtcm::set_DF418(int32_t carrier_smoothing_interval_s) { if (carrier_smoothing_interval_s < 0) { @@ -5598,7 +5600,7 @@ int Rtcm::set_DF418(int carrier_smoothing_interval_s) } -int Rtcm::set_DF420(const Gnss_Synchro& gnss_synchro __attribute__((unused))) +int32_t Rtcm::set_DF420(const Gnss_Synchro& gnss_synchro __attribute__((unused))) { // todo: read the value from gnss_synchro bool half_cycle_ambiguity_indicator = true; diff --git a/src/core/system_parameters/rtcm.h b/src/core/system_parameters/rtcm.h index d97ed6e24..f450dae05 100644 --- a/src/core/system_parameters/rtcm.h +++ b/src/core/system_parameters/rtcm.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -85,50 +86,50 @@ class Rtcm { public: - Rtcm(unsigned short port = 2101); //& observables, unsigned short station_id); + std::string print_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables, uint16_t station_id); /*! * \brief Prints message type 1002 (Extended L1-Only GPS RTK Observables) */ - std::string print_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables, unsigned short station_id); + std::string print_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, const std::map& observables, uint16_t station_id); /*! * \brief Prints message type 1003 (L1 & L2 GPS RTK Observables) */ - std::string print_MT1003(const Gps_Ephemeris& ephL1, const Gps_CNAV_Ephemeris& ephL2, double obs_time, const std::map& observables, unsigned short station_id); + std::string print_MT1003(const Gps_Ephemeris& ephL1, const Gps_CNAV_Ephemeris& ephL2, double obs_time, const std::map& observables, uint16_t station_id); /*! * \brief Prints message type 1004 (Extended L1 & L2 GPS RTK Observables) */ - std::string print_MT1004(const Gps_Ephemeris& ephL1, const Gps_CNAV_Ephemeris& ephL2, double obs_time, const std::map& observables, unsigned short station_id); + std::string print_MT1004(const Gps_Ephemeris& ephL1, const Gps_CNAV_Ephemeris& ephL2, double obs_time, const std::map& observables, uint16_t station_id); /*! * \brief Prints message type 1005 (Stationary Antenna Reference Point) */ - std::string print_MT1005(unsigned int ref_id, double ecef_x, double ecef_y, double ecef_z, bool gps, bool glonass, bool galileo, bool non_physical, bool single_oscillator, unsigned int quarter_cycle_indicator); + std::string print_MT1005(uint32_t ref_id, double ecef_x, double ecef_y, double ecef_z, bool gps, bool glonass, bool galileo, bool non_physical, bool single_oscillator, uint32_t quarter_cycle_indicator); /*! * \brief Verifies and reads messages of type 1005 (Stationary Antenna Reference Point). Returns 1 if anything goes wrong, 0 otherwise. */ - int read_MT1005(const std::string& message, unsigned int& ref_id, double& ecef_x, double& ecef_y, double& ecef_z, bool& gps, bool& glonass, bool& galileo); + int32_t read_MT1005(const std::string& message, uint32_t& ref_id, double& ecef_x, double& ecef_y, double& ecef_z, bool& gps, bool& glonass, bool& galileo); /*! * \brief Prints message type 1006 (Stationary Antenna Reference Point, with Height Information) */ - std::string print_MT1006(unsigned int ref_id, double ecef_x, double ecef_y, double ecef_z, bool gps, bool glonass, bool galileo, bool non_physical, bool single_oscillator, unsigned int quarter_cycle_indicator, double height); + std::string print_MT1006(uint32_t ref_id, double ecef_x, double ecef_y, double ecef_z, bool gps, bool glonass, bool galileo, bool non_physical, bool single_oscillator, uint32_t quarter_cycle_indicator, double height); std::string print_MT1005_test(); //& observables, unsigned short station_id); + std::string print_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables, uint16_t station_id); /*! * \brief Prints Extended L1-Only GLONASS RTK Observables * \details This GLONASS message type is used when only L1 data is present and bandwidth is very tight, often 1012 is used in such cases. @@ -149,7 +150,7 @@ public: * \param observables Set of observables as defined by the platform * \return string with message contents */ - std::string print_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables, unsigned short station_id); + std::string print_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double obs_time, const std::map& observables, uint16_t station_id); /*! * \brief Prints L1&L2 GLONASS RTK Observables * \details This GLONASS message type is not generally used or supported; type 1012 is to be preferred @@ -159,7 +160,7 @@ public: * \param observables Set of observables as defined by the platform * \return string with message contents */ - std::string print_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables, unsigned short station_id); + std::string print_MT1011(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables, uint16_t station_id); /*! * \brief Prints Extended L1&L2 GLONASS RTK Observables * \details This GLONASS message type is the most common observational message type, with L1/L2/SNR content. This is one of the most common messages found. @@ -169,7 +170,7 @@ public: * \param observables Set of observables as defined by the platform * \return string with message contents */ - std::string print_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables, unsigned short station_id); + std::string print_MT1012(const Glonass_Gnav_Ephemeris& glonass_gnav_ephL1, const Glonass_Gnav_Ephemeris& glonass_gnav_ephL2, double obs_time, const std::map& observables, uint16_t station_id); /*! * \brief Prints message type 1019 (GPS Ephemeris), should be broadcast in the event that @@ -180,7 +181,7 @@ public: /*! * \brief Verifies and reads messages of type 1019 (GPS Ephemeris). Returns 1 if anything goes wrong, 0 otherwise. */ - int read_MT1019(const std::string& message, Gps_Ephemeris& gps_eph); + int32_t read_MT1019(const std::string& message, Gps_Ephemeris& gps_eph); /*! * \brief Prints message type 1020 (GLONASS Ephemeris). @@ -199,12 +200,12 @@ public: * \param glonass_gnav_utc_model GLONASS GNAV Clock Information * \return Returns 1 if anything goes wrong, 0 otherwise. */ - int read_MT1020(const std::string& message, Glonass_Gnav_Ephemeris& glonass_gnav_eph, Glonass_Gnav_Utc_Model& glonass_gnav_utc_model); + int32_t read_MT1020(const std::string& message, Glonass_Gnav_Ephemeris& glonass_gnav_eph, Glonass_Gnav_Utc_Model& glonass_gnav_utc_model); /*! * \brief Prints message type 1029 (Unicode Text String) */ - std::string print_MT1029(unsigned int ref_id, const Gps_Ephemeris& gps_eph, double obs_time, const std::string& message); + std::string print_MT1029(uint32_t ref_id, const Gps_Ephemeris& gps_eph, double obs_time, const std::string& message); /*! * \brief Prints message type 1045 (Galileo Ephemeris), should be broadcast every 2 minutes @@ -214,7 +215,7 @@ public: /*! * \brief Verifies and reads messages of type 1045 (Galileo Ephemeris). Returns 1 if anything goes wrong, 0 otherwise. */ - int read_MT1045(const std::string& message, Galileo_Ephemeris& gal_eph); + int32_t read_MT1045(const std::string& message, Galileo_Ephemeris& gal_eph); /*! * \brief Prints messages of type MSM1 (Compact GNSS observables) @@ -224,11 +225,11 @@ public: const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages); @@ -240,11 +241,11 @@ public: const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages); @@ -256,11 +257,11 @@ public: const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages); @@ -272,11 +273,11 @@ public: const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages); @@ -288,11 +289,11 @@ public: const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages); @@ -304,11 +305,11 @@ public: const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages); @@ -320,17 +321,17 @@ public: const Galileo_Ephemeris& gal_eph, const Glonass_Gnav_Ephemeris& glo_gnav_eph, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages); - unsigned int lock_time(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro); // get_MT1001_4_header(unsigned int msg_number, + std::bitset<64> get_MT1001_4_header(uint32_t msg_number, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t smooth_int, bool sync_flag, bool divergence_free); @@ -400,11 +401,11 @@ private: * \param divergence_free * \return Returns the message header content as set of bits */ - std::bitset<61> get_MT1009_12_header(unsigned int msg_number, + std::bitset<61> get_MT1009_12_header(uint32_t msg_number, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t smooth_int, bool sync_flag, bool divergence_free); @@ -453,35 +454,35 @@ private: */ std::bitset<130> get_MT1012_sat_content(const Glonass_Gnav_Ephemeris& ephGNAVL1, const Glonass_Gnav_Ephemeris& ephGNAVL2, double obs_time, const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2); - std::string get_MSM_header(unsigned int msg_number, + std::string get_MSM_header(uint32_t msg_number, double obs_time, - const std::map& observables, - unsigned int ref_id, - unsigned int clock_steering_indicator, - unsigned int external_clock_indicator, - int smooth_int, + const std::map& observables, + uint32_t ref_id, + uint32_t clock_steering_indicator, + uint32_t external_clock_indicator, + int32_t smooth_int, bool divergence_free, bool more_messages); - std::string get_MSM_1_content_sat_data(const std::map& observables); - std::string get_MSM_4_content_sat_data(const std::map& observables); - std::string get_MSM_5_content_sat_data(const std::map& observables); + std::string get_MSM_1_content_sat_data(const std::map& observables); + std::string get_MSM_4_content_sat_data(const std::map& observables); + std::string get_MSM_5_content_sat_data(const std::map& observables); - std::string get_MSM_1_content_signal_data(const std::map& observables); - std::string get_MSM_2_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); - std::string get_MSM_3_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); - std::string get_MSM_4_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); - std::string get_MSM_5_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); - std::string get_MSM_6_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); - std::string get_MSM_7_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); + std::string get_MSM_1_content_signal_data(const std::map& observables); + std::string get_MSM_2_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); + std::string get_MSM_3_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); + std::string get_MSM_4_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); + std::string get_MSM_5_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); + std::string get_MSM_6_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); + std::string get_MSM_7_content_signal_data(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const std::map& observables); // // Utilities // static std::map galileo_signal_map; static std::map gps_signal_map; - std::vector > sort_by_signal(const std::vector >& synchro_map) const; - std::vector > sort_by_PRN_mask(const std::vector >& synchro_map) const; + std::vector > sort_by_signal(const std::vector >& synchro_map) const; + std::vector > sort_by_PRN_mask(const std::vector >& synchro_map) const; boost::posix_time::ptime compute_GPS_time(const Gps_Ephemeris& eph, double obs_time) const; boost::posix_time::ptime compute_GPS_time(const Gps_CNAV_Ephemeris& eph, double obs_time) const; boost::posix_time::ptime compute_Galileo_time(const Galileo_Ephemeris& eph, double obs_time) const; @@ -492,15 +493,15 @@ private: boost::posix_time::ptime gal_E5_last_lock_time[64]; boost::posix_time::ptime glo_L1_last_lock_time[64]; boost::posix_time::ptime glo_L2_last_lock_time[64]; - unsigned int lock_time_indicator(unsigned int lock_time_period_s); - unsigned int msm_lock_time_indicator(unsigned int lock_time_period_s); - unsigned int msm_extended_lock_time_indicator(unsigned int lock_time_period_s); + uint32_t lock_time_indicator(uint32_t lock_time_period_s); + uint32_t msm_lock_time_indicator(uint32_t lock_time_period_s); + uint32_t msm_extended_lock_time_indicator(uint32_t lock_time_period_s); // // Classes for TCP communication // - unsigned short RTCM_port; - //unsigned short RTCM_Station_ID; + uint16_t RTCM_port; + //uint16_t RTCM_Station_ID; class Rtcm_Message { public: @@ -837,7 +838,7 @@ private: class Queue_Reader { public: - Queue_Reader(boost::asio::io_service& io_context, std::shared_ptr >& queue, int port) : queue_(queue) + Queue_Reader(boost::asio::io_service& io_context, std::shared_ptr >& queue, int32_t port) : queue_(queue) { boost::asio::ip::tcp::resolver resolver(io_context); std::string host("localhost"); @@ -955,88 +956,88 @@ private: // Data Fields // std::bitset<12> DF002; - int set_DF002(unsigned int message_number); + int32_t set_DF002(uint32_t message_number); std::bitset<12> DF003; - int set_DF003(unsigned int ref_station_ID); + int32_t set_DF003(uint32_t ref_station_ID); std::bitset<30> DF004; - int set_DF004(double obs_time); + int32_t set_DF004(double obs_time); std::bitset<1> DF005; - int set_DF005(bool sync_flag); + int32_t set_DF005(bool sync_flag); std::bitset<5> DF006; - int set_DF006(const std::map& observables); + int32_t set_DF006(const std::map& observables); std::bitset<1> DF007; - int set_DF007(bool divergence_free_smoothing_indicator); // 0 - Divergence-free smoothing not used 1 - Divergence-free smoothing used + int32_t set_DF007(bool divergence_free_smoothing_indicator); // 0 - Divergence-free smoothing not used 1 - Divergence-free smoothing used std::bitset<3> DF008; - int set_DF008(short int smoothing_interval); + int32_t set_DF008(int16_t smoothing_interval); std::bitset<6> DF009; - int set_DF009(const Gnss_Synchro& gnss_synchro); - int set_DF009(const Gps_Ephemeris& gps_eph); + int32_t set_DF009(const Gnss_Synchro& gnss_synchro); + int32_t set_DF009(const Gps_Ephemeris& gps_eph); std::bitset<1> DF010; - int set_DF010(bool code_indicator); + int32_t set_DF010(bool code_indicator); std::bitset<24> DF011; - int set_DF011(const Gnss_Synchro& gnss_synchro); + int32_t set_DF011(const Gnss_Synchro& gnss_synchro); std::bitset<20> DF012; - int set_DF012(const Gnss_Synchro& gnss_synchro); + int32_t set_DF012(const Gnss_Synchro& gnss_synchro); std::bitset<7> DF013; - int set_DF013(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro); + int32_t set_DF013(const Gps_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro); std::bitset<8> DF014; - int set_DF014(const Gnss_Synchro& gnss_synchro); + int32_t set_DF014(const Gnss_Synchro& gnss_synchro); std::bitset<8> DF015; - int set_DF015(const Gnss_Synchro& gnss_synchro); + int32_t set_DF015(const Gnss_Synchro& gnss_synchro); std::bitset<14> DF017; - int set_DF017(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2); + int32_t set_DF017(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2); std::bitset<20> DF018; - int set_DF018(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2); + int32_t set_DF018(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2); std::bitset<7> DF019; - int set_DF019(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro); + int32_t set_DF019(const Gps_CNAV_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro); std::bitset<8> DF020; - int set_DF020(const Gnss_Synchro& gnss_synchro); + int32_t set_DF020(const Gnss_Synchro& gnss_synchro); std::bitset<6> DF021; - int set_DF021(); + int32_t set_DF021(); std::bitset<1> DF022; - int set_DF022(bool gps_indicator); + int32_t set_DF022(bool gps_indicator); std::bitset<1> DF023; - int set_DF023(bool glonass_indicator); + int32_t set_DF023(bool glonass_indicator); std::bitset<1> DF024; - int set_DF024(bool galileo_indicator); + int32_t set_DF024(bool galileo_indicator); std::bitset<38> DF025; - int set_DF025(double antenna_ECEF_X_m); + int32_t set_DF025(double antenna_ECEF_X_m); std::bitset<38> DF026; - int set_DF026(double antenna_ECEF_Y_m); + int32_t set_DF026(double antenna_ECEF_Y_m); std::bitset<38> DF027; - int set_DF027(double antenna_ECEF_Z_m); + int32_t set_DF027(double antenna_ECEF_Z_m); std::bitset<16> DF028; - int set_DF028(double height); + int32_t set_DF028(double height); std::bitset<8> DF029; std::bitset<8> DF031; - int set_DF031(unsigned int antenna_setup_id); + int32_t set_DF031(uint32_t antenna_setup_id); std::bitset<8> DF032; @@ -1046,417 +1047,417 @@ private: * \param obs_time Time of observation at the moment of printing * \return returns 0 upon success */ - int set_DF034(double obs_time); + int32_t set_DF034(double obs_time); std::bitset<27> DF034; //!< GLONASS Epoch Time (tk) std::bitset<5> DF035; //!< No. of GLONASS Satellite Signals Processed - int set_DF035(const std::map& observables); + int32_t set_DF035(const std::map& observables); std::bitset<1> DF036; //!< GLONASS Divergence-free Smoothing Indicator - int set_DF036(bool divergence_free_smoothing_indicator); + int32_t set_DF036(bool divergence_free_smoothing_indicator); std::bitset<3> DF037; //!< GLONASS Smoothing Interval - int set_DF037(short int smoothing_interval); + int32_t set_DF037(int16_t smoothing_interval); std::bitset<6> DF038; //!< GLONASS Satellite ID (Satellite Slot Number) - int set_DF038(const Gnss_Synchro& gnss_synchro); - int set_DF038(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF038(const Gnss_Synchro& gnss_synchro); + int32_t set_DF038(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<1> DF039; //!< GLONASS L1 Code Indicator - int set_DF039(bool code_indicator); + int32_t set_DF039(bool code_indicator); std::bitset<5> DF040; //!< GLONASS Satellite Frequency Number - int set_DF040(int frequency_channel_number); - int set_DF040(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF040(int32_t frequency_channel_number); + int32_t set_DF040(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<25> DF041; //!< GLONASS L1 Pseudorange - int set_DF041(const Gnss_Synchro& gnss_synchro); + int32_t set_DF041(const Gnss_Synchro& gnss_synchro); std::bitset<20> DF042; //!< GLONASS L1 PhaseRange - L1 Pseudorange - int set_DF042(const Gnss_Synchro& gnss_synchro); + int32_t set_DF042(const Gnss_Synchro& gnss_synchro); std::bitset<7> DF043; //!< GLONASS L1 Lock Time Indicator - int set_DF043(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro); + int32_t set_DF043(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro); std::bitset<7> DF044; //!< GLONASS Integer L1 Pseudorange Modulus Ambiguity - int set_DF044(const Gnss_Synchro& gnss_synchro); + int32_t set_DF044(const Gnss_Synchro& gnss_synchro); std::bitset<8> DF045; //!< GLONASS L1 CNR - int set_DF045(const Gnss_Synchro& gnss_synchro); + int32_t set_DF045(const Gnss_Synchro& gnss_synchro); std::bitset<2> DF046; //!< GLONASS L2 code indicator - int set_DF046(unsigned short code_indicator); + int32_t set_DF046(uint16_t code_indicator); std::bitset<14> DF047; //!< GLONASS L2 - L1 Pseudorange Difference - int set_DF047(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2); + int32_t set_DF047(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2); std::bitset<20> DF048; //!< GLONASS L2 PhaseRange - L1 Pseudorange - int set_DF048(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2); + int32_t set_DF048(const Gnss_Synchro& gnss_synchroL1, const Gnss_Synchro& gnss_synchroL2); std::bitset<7> DF049; //!< GLONASS L2 Lock Time Indicator - int set_DF049(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro); + int32_t set_DF049(const Glonass_Gnav_Ephemeris& eph, double obs_time, const Gnss_Synchro& gnss_synchro); std::bitset<8> DF050; //!< GLONASS L2 CNR - int set_DF050(const Gnss_Synchro& gnss_synchro); + int32_t set_DF050(const Gnss_Synchro& gnss_synchro); std::bitset<16> DF051; - int set_DF051(const Gps_Ephemeris& gps_eph, double obs_time); + int32_t set_DF051(const Gps_Ephemeris& gps_eph, double obs_time); std::bitset<17> DF052; - int set_DF052(const Gps_Ephemeris& gps_eph, double obs_time); + int32_t set_DF052(const Gps_Ephemeris& gps_eph, double obs_time); // Contents of GPS Satellite Ephemeris Data, Message Type 1019 std::bitset<8> DF071; - int set_DF071(const Gps_Ephemeris& gps_eph); + int32_t set_DF071(const Gps_Ephemeris& gps_eph); std::bitset<10> DF076; - int set_DF076(const Gps_Ephemeris& gps_eph); + int32_t set_DF076(const Gps_Ephemeris& gps_eph); std::bitset<4> DF077; - int set_DF077(const Gps_Ephemeris& gps_eph); + int32_t set_DF077(const Gps_Ephemeris& gps_eph); std::bitset<2> DF078; - int set_DF078(const Gps_Ephemeris& gps_eph); + int32_t set_DF078(const Gps_Ephemeris& gps_eph); std::bitset<14> DF079; - int set_DF079(const Gps_Ephemeris& gps_eph); + int32_t set_DF079(const Gps_Ephemeris& gps_eph); std::bitset<8> DF080; - int set_DF080(const Gps_Ephemeris& gps_eph); + int32_t set_DF080(const Gps_Ephemeris& gps_eph); std::bitset<16> DF081; - int set_DF081(const Gps_Ephemeris& gps_eph); + int32_t set_DF081(const Gps_Ephemeris& gps_eph); std::bitset<8> DF082; - int set_DF082(const Gps_Ephemeris& gps_eph); + int32_t set_DF082(const Gps_Ephemeris& gps_eph); std::bitset<16> DF083; - int set_DF083(const Gps_Ephemeris& gps_eph); + int32_t set_DF083(const Gps_Ephemeris& gps_eph); std::bitset<22> DF084; - int set_DF084(const Gps_Ephemeris& gps_eph); + int32_t set_DF084(const Gps_Ephemeris& gps_eph); std::bitset<10> DF085; - int set_DF085(const Gps_Ephemeris& gps_eph); + int32_t set_DF085(const Gps_Ephemeris& gps_eph); std::bitset<16> DF086; - int set_DF086(const Gps_Ephemeris& gps_eph); + int32_t set_DF086(const Gps_Ephemeris& gps_eph); std::bitset<16> DF087; - int set_DF087(const Gps_Ephemeris& gps_eph); + int32_t set_DF087(const Gps_Ephemeris& gps_eph); std::bitset<32> DF088; - int set_DF088(const Gps_Ephemeris& gps_eph); + int32_t set_DF088(const Gps_Ephemeris& gps_eph); std::bitset<16> DF089; - int set_DF089(const Gps_Ephemeris& gps_eph); + int32_t set_DF089(const Gps_Ephemeris& gps_eph); std::bitset<32> DF090; - int set_DF090(const Gps_Ephemeris& gps_eph); + int32_t set_DF090(const Gps_Ephemeris& gps_eph); std::bitset<16> DF091; - int set_DF091(const Gps_Ephemeris& gps_eph); + int32_t set_DF091(const Gps_Ephemeris& gps_eph); std::bitset<32> DF092; - int set_DF092(const Gps_Ephemeris& gps_eph); + int32_t set_DF092(const Gps_Ephemeris& gps_eph); std::bitset<16> DF093; - int set_DF093(const Gps_Ephemeris& gps_eph); + int32_t set_DF093(const Gps_Ephemeris& gps_eph); std::bitset<16> DF094; - int set_DF094(const Gps_Ephemeris& gps_eph); + int32_t set_DF094(const Gps_Ephemeris& gps_eph); std::bitset<32> DF095; - int set_DF095(const Gps_Ephemeris& gps_eph); + int32_t set_DF095(const Gps_Ephemeris& gps_eph); std::bitset<16> DF096; - int set_DF096(const Gps_Ephemeris& gps_eph); + int32_t set_DF096(const Gps_Ephemeris& gps_eph); std::bitset<32> DF097; - int set_DF097(const Gps_Ephemeris& gps_eph); + int32_t set_DF097(const Gps_Ephemeris& gps_eph); std::bitset<16> DF098; - int set_DF098(const Gps_Ephemeris& gps_eph); + int32_t set_DF098(const Gps_Ephemeris& gps_eph); std::bitset<32> DF099; - int set_DF099(const Gps_Ephemeris& gps_eph); + int32_t set_DF099(const Gps_Ephemeris& gps_eph); std::bitset<24> DF100; - int set_DF100(const Gps_Ephemeris& gps_eph); + int32_t set_DF100(const Gps_Ephemeris& gps_eph); std::bitset<8> DF101; - int set_DF101(const Gps_Ephemeris& gps_eph); + int32_t set_DF101(const Gps_Ephemeris& gps_eph); std::bitset<6> DF102; - int set_DF102(const Gps_Ephemeris& gps_eph); + int32_t set_DF102(const Gps_Ephemeris& gps_eph); std::bitset<1> DF103; - int set_DF103(const Gps_Ephemeris& gps_eph); + int32_t set_DF103(const Gps_Ephemeris& gps_eph); std::bitset<1> DF104; //!< GLONASS Almanac Health - int set_DF104(unsigned int glonass_gnav_alm_health); + int32_t set_DF104(uint32_t glonass_gnav_alm_health); std::bitset<1> DF105; //!< GLONASS Almanac Health Availability Indicator - int set_DF105(unsigned int glonass_gnav_alm_health_ind); + int32_t set_DF105(uint32_t glonass_gnav_alm_health_ind); std::bitset<2> DF106; //!< GLONASS P1 Word - int set_DF106(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF106(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<12> DF107; //!< GLONASS Epoch (tk) - int set_DF107(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF107(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<1> DF108; //!< GLONASS MSB of Bn Word - int set_DF108(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF108(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<1> DF109; //!< GLONASS P2 Word - int set_DF109(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF109(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<7> DF110; //!< GLONASS Ephmeris Epoch (tb) - int set_DF110(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF110(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<24> DF111; //!< GLONASS Xn first derivative - int set_DF111(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF111(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<27> DF112; //!< GLONASS Xn - int set_DF112(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF112(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<5> DF113; //!< GLONASS Xn second derivative - int set_DF113(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF113(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<24> DF114; //!< GLONASS Yn first derivative - int set_DF114(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF114(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<27> DF115; //!< GLONASS Yn - int set_DF115(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF115(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<5> DF116; //!< GLONASS Yn second derivative - int set_DF116(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF116(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<24> DF117; //!< GLONASS Zn first derivative - int set_DF117(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF117(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<27> DF118; //!< GLONASS Zn - int set_DF118(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF118(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<5> DF119; //!< GLONASS Zn second derivative - int set_DF119(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF119(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<1> DF120; //!< GLONASS P3 - int set_DF120(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF120(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<11> DF121; //!< GLONASS GAMMA_N - int set_DF121(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF121(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<2> DF122; //!< GLONASS P - int set_DF122(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF122(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<1> DF123; //!< GLONASS ln (third string) - int set_DF123(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF123(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<22> DF124; //!< GLONASS TAU_N - int set_DF124(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF124(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<5> DF125; //!< GLONASS DELTA_TAU_N - int set_DF125(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF125(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<5> DF126; //!< GLONASS Eccentricity - int set_DF126(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF126(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<1> DF127; //!< GLONASS P4 - int set_DF127(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF127(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<4> DF128; //!< GLONASS F_T - int set_DF128(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF128(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<11> DF129; //!< GLONASS N_T - int set_DF129(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF129(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<2> DF130; //!< GLONASS M - int set_DF130(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF130(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<1> DF131; //!< GLONASS Availability of additional data - int set_DF131(unsigned int fifth_str_additional_data_ind); + int32_t set_DF131(uint32_t fifth_str_additional_data_ind); std::bitset<11> DF132; //!< GLONASS N_A - int set_DF132(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model); + int32_t set_DF132(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model); std::bitset<32> DF133; //!< GLONASS TAU_C - int set_DF133(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model); + int32_t set_DF133(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model); std::bitset<5> DF134; //!< GLONASS N_4 - int set_DF134(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model); + int32_t set_DF134(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model); std::bitset<22> DF135; //!< GLONASS TAU_GPS - int set_DF135(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model); + int32_t set_DF135(const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model); std::bitset<1> DF136; //!< GLONASS L_N (FIFTH STRING) - int set_DF136(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); + int32_t set_DF136(const Glonass_Gnav_Ephemeris& glonass_gnav_eph); std::bitset<1> DF137; - int set_DF137(const Gps_Ephemeris& gps_eph); + int32_t set_DF137(const Gps_Ephemeris& gps_eph); std::bitset<1> DF141; - int set_DF141(const Gps_Ephemeris& gps_eph); + int32_t set_DF141(const Gps_Ephemeris& gps_eph); std::bitset<1> DF142; - int set_DF142(const Gps_Ephemeris& gps_eph); + int32_t set_DF142(const Gps_Ephemeris& gps_eph); std::bitset<30> DF248; - int set_DF248(double obs_time); + int32_t set_DF248(double obs_time); // Contents of Galileo F/NAV Satellite Ephemeris Data, Message Type 1045 std::bitset<6> DF252; - int set_DF252(const Galileo_Ephemeris& gal_eph); + int32_t set_DF252(const Galileo_Ephemeris& gal_eph); std::bitset<12> DF289; - int set_DF289(const Galileo_Ephemeris& gal_eph); + int32_t set_DF289(const Galileo_Ephemeris& gal_eph); std::bitset<10> DF290; - int set_DF290(const Galileo_Ephemeris& gal_eph); + int32_t set_DF290(const Galileo_Ephemeris& gal_eph); std::bitset<8> DF291; - int set_DF291(const Galileo_Ephemeris& gal_eph); + int32_t set_DF291(const Galileo_Ephemeris& gal_eph); std::bitset<14> DF292; - int set_DF292(const Galileo_Ephemeris& gal_eph); + int32_t set_DF292(const Galileo_Ephemeris& gal_eph); std::bitset<14> DF293; - int set_DF293(const Galileo_Ephemeris& gal_eph); + int32_t set_DF293(const Galileo_Ephemeris& gal_eph); std::bitset<6> DF294; - int set_DF294(const Galileo_Ephemeris& gal_eph); + int32_t set_DF294(const Galileo_Ephemeris& gal_eph); std::bitset<21> DF295; - int set_DF295(const Galileo_Ephemeris& gal_eph); + int32_t set_DF295(const Galileo_Ephemeris& gal_eph); std::bitset<31> DF296; - int set_DF296(const Galileo_Ephemeris& gal_eph); + int32_t set_DF296(const Galileo_Ephemeris& gal_eph); std::bitset<16> DF297; - int set_DF297(const Galileo_Ephemeris& gal_eph); + int32_t set_DF297(const Galileo_Ephemeris& gal_eph); std::bitset<16> DF298; - int set_DF298(const Galileo_Ephemeris& gal_eph); + int32_t set_DF298(const Galileo_Ephemeris& gal_eph); std::bitset<32> DF299; - int set_DF299(const Galileo_Ephemeris& gal_eph); + int32_t set_DF299(const Galileo_Ephemeris& gal_eph); std::bitset<16> DF300; - int set_DF300(const Galileo_Ephemeris& gal_eph); + int32_t set_DF300(const Galileo_Ephemeris& gal_eph); std::bitset<32> DF301; - int set_DF301(const Galileo_Ephemeris& gal_eph); + int32_t set_DF301(const Galileo_Ephemeris& gal_eph); std::bitset<16> DF302; - int set_DF302(const Galileo_Ephemeris& gal_eph); + int32_t set_DF302(const Galileo_Ephemeris& gal_eph); std::bitset<32> DF303; - int set_DF303(const Galileo_Ephemeris& gal_eph); + int32_t set_DF303(const Galileo_Ephemeris& gal_eph); std::bitset<14> DF304; - int set_DF304(const Galileo_Ephemeris& gal_eph); + int32_t set_DF304(const Galileo_Ephemeris& gal_eph); std::bitset<16> DF305; - int set_DF305(const Galileo_Ephemeris& gal_eph); + int32_t set_DF305(const Galileo_Ephemeris& gal_eph); std::bitset<32> DF306; - int set_DF306(const Galileo_Ephemeris& gal_eph); + int32_t set_DF306(const Galileo_Ephemeris& gal_eph); std::bitset<16> DF307; - int set_DF307(const Galileo_Ephemeris& gal_eph); + int32_t set_DF307(const Galileo_Ephemeris& gal_eph); std::bitset<32> DF308; - int set_DF308(const Galileo_Ephemeris& gal_eph); + int32_t set_DF308(const Galileo_Ephemeris& gal_eph); std::bitset<16> DF309; - int set_DF309(const Galileo_Ephemeris& gal_eph); + int32_t set_DF309(const Galileo_Ephemeris& gal_eph); std::bitset<32> DF310; - int set_DF310(const Galileo_Ephemeris& gal_eph); + int32_t set_DF310(const Galileo_Ephemeris& gal_eph); std::bitset<24> DF311; - int set_DF311(const Galileo_Ephemeris& gal_eph); + int32_t set_DF311(const Galileo_Ephemeris& gal_eph); std::bitset<10> DF312; - int set_DF312(const Galileo_Ephemeris& gal_eph); + int32_t set_DF312(const Galileo_Ephemeris& gal_eph); std::bitset<10> DF313; - int set_DF313(const Galileo_Ephemeris& gal_eph); + int32_t set_DF313(const Galileo_Ephemeris& gal_eph); std::bitset<2> DF314; - int set_DF314(const Galileo_Ephemeris& gal_eph); + int32_t set_DF314(const Galileo_Ephemeris& gal_eph); std::bitset<1> DF315; - int set_DF315(const Galileo_Ephemeris& gal_eph); + int32_t set_DF315(const Galileo_Ephemeris& gal_eph); std::bitset<2> DF364; // Content of message header for MSM1, MSM2, MSM3, MSM4, MSM5, MSM6 and MSM7 std::bitset<1> DF393; - int set_DF393(bool more_messages); //1 indicates that more MSMs follow for given physical time and reference station ID + int32_t set_DF393(bool more_messages); //1 indicates that more MSMs follow for given physical time and reference station ID std::bitset<64> DF394; - int set_DF394(const std::map& observables); + int32_t set_DF394(const std::map& observables); std::bitset<32> DF395; - int set_DF395(const std::map& observables); + int32_t set_DF395(const std::map& observables); - std::string set_DF396(const std::map& observables); + std::string set_DF396(const std::map& observables); std::bitset<8> DF397; - int set_DF397(const Gnss_Synchro& gnss_synchro); + int32_t set_DF397(const Gnss_Synchro& gnss_synchro); std::bitset<10> DF398; - int set_DF398(const Gnss_Synchro& gnss_synchro); + int32_t set_DF398(const Gnss_Synchro& gnss_synchro); std::bitset<14> DF399; - int set_DF399(const Gnss_Synchro& gnss_synchro); + int32_t set_DF399(const Gnss_Synchro& gnss_synchro); std::bitset<15> DF400; - int set_DF400(const Gnss_Synchro& gnss_synchro); + int32_t set_DF400(const Gnss_Synchro& gnss_synchro); std::bitset<22> DF401; - int set_DF401(const Gnss_Synchro& gnss_synchro); + int32_t set_DF401(const Gnss_Synchro& gnss_synchro); std::bitset<4> DF402; - int set_DF402(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const Gnss_Synchro& gnss_synchro); + int32_t set_DF402(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const Gnss_Synchro& gnss_synchro); std::bitset<6> DF403; - int set_DF403(const Gnss_Synchro& gnss_synchro); + int32_t set_DF403(const Gnss_Synchro& gnss_synchro); std::bitset<15> DF404; - int set_DF404(const Gnss_Synchro& gnss_synchro); + int32_t set_DF404(const Gnss_Synchro& gnss_synchro); std::bitset<20> DF405; - int set_DF405(const Gnss_Synchro& gnss_synchro); + int32_t set_DF405(const Gnss_Synchro& gnss_synchro); std::bitset<24> DF406; - int set_DF406(const Gnss_Synchro& gnss_synchro); + int32_t set_DF406(const Gnss_Synchro& gnss_synchro); std::bitset<10> DF407; - int set_DF407(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const Gnss_Synchro& gnss_synchro); + int32_t set_DF407(const Gps_Ephemeris& ephNAV, const Gps_CNAV_Ephemeris& ephCNAV, const Galileo_Ephemeris& ephFNAV, const Glonass_Gnav_Ephemeris& ephGNAV, double obs_time, const Gnss_Synchro& gnss_synchro); std::bitset<10> DF408; - int set_DF408(const Gnss_Synchro& gnss_synchro); + int32_t set_DF408(const Gnss_Synchro& gnss_synchro); std::bitset<3> DF409; - int set_DF409(unsigned int iods); + int32_t set_DF409(uint32_t iods); std::bitset<2> DF411; - int set_DF411(unsigned int clock_steering_indicator); + int32_t set_DF411(uint32_t clock_steering_indicator); std::bitset<2> DF412; - int set_DF412(unsigned int external_clock_indicator); + int32_t set_DF412(uint32_t external_clock_indicator); std::bitset<1> DF417; - int set_DF417(bool using_divergence_free_smoothing); + int32_t set_DF417(bool using_divergence_free_smoothing); std::bitset<3> DF418; - int set_DF418(int carrier_smoothing_interval_s); + int32_t set_DF418(int32_t carrier_smoothing_interval_s); std::bitset<1> DF420; - int set_DF420(const Gnss_Synchro& gnss_synchro); + int32_t set_DF420(const Gnss_Synchro& gnss_synchro); }; #endif diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt index 7b41ccfbd..85b250e91 100644 --- a/src/main/CMakeLists.txt +++ b/src/main/CMakeLists.txt @@ -23,91 +23,97 @@ if(ENABLE_GPERFTOOLS) if(GPERFTOOLS_FOUND) set(GNSS_SDR_OPTIONAL_LIBS "${GNSS_SDR_OPTIONAL_LIBS};${GPERFTOOLS_PROFILER};${GPERFTOOLS_TCMALLOC}") set(GNSS_SDR_OPTIONAL_HEADERS "${GNSS_SDR_OPTIONAL_HEADERS};${GPERFTOOLS_INCLUDE_DIR}") - endif(GPERFTOOLS_FOUND) -endif(ENABLE_GPERFTOOLS) + endif() +endif() if(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd) set(GNSS_SDR_OPTIONAL_LIBS ${GNSS_SDR_OPTIONAL_LIBS} ${UHD_LIBRARIES} ${GNURADIO_UHD_LIBRARIES}) set(GNSS_SDR_OPTIONAL_HEADERS ${GNSS_SDR_OPTIONAL_HEADERS} ${UHD_INCLUDE_DIRS}) -endif(ENABLE_UHD AND GNURADIO_UHD_LIBRARIES_gnuradio-uhd) +endif() if(OPENSSL_FOUND) - add_definitions( -DUSE_OPENSSL_FALLBACK=1 ) -endif(OPENSSL_FOUND) + add_definitions(-DUSE_OPENSSL_FALLBACK=1) +endif() if(ENABLE_CUDA) add_definitions(-DCUDA_GPU_ACCEL=1) set(GNSS_SDR_OPTIONAL_LIBS ${GNSS_SDR_OPTIONAL_LIBS} ${CUDA_LIBRARIES}) set(GNSS_SDR_OPTIONAL_HEADERS ${GNSS_SDR_OPTIONAL_HEADERS} ${CUDA_INCLUDE_DIRS}) -endif(ENABLE_CUDA) +endif() if(ORC_FOUND) set(GNSS_SDR_OPTIONAL_LIBS ${GNSS_SDR_OPTIONAL_LIBS} ${ORC_LIBRARIES}) set(GNSS_SDR_OPTIONAL_HEADERS ${GNSS_SDR_OPTIONAL_HEADERS} ${ORC_INCLUDE_DIRS}) -endif(ORC_FOUND) +endif() include_directories( - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/core/libs - ${CMAKE_SOURCE_DIR}/src/core/libs/supl - ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp - ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${ARMADILLO_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${GNSS_SDR_OPTIONAL_HEADERS} - ${VOLK_GNSSSDR_INCLUDE_DIRS} - ${OPT_GNSSSDR_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/core/monitor + ${CMAKE_SOURCE_DIR}/src/core/libs + ${CMAKE_SOURCE_DIR}/src/core/libs/supl + ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp + ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${ARMADILLO_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${PUGIXML_INCLUDE_DIR} + ${GNSS_SDR_OPTIONAL_HEADERS} + ${VOLK_GNSSSDR_INCLUDE_DIRS} + ${OPT_GNSSSDR_INCLUDE_DIRS} ) -add_definitions( -DGNSS_SDR_VERSION="${VERSION}" ) +add_definitions(-DGNSS_SDR_VERSION="${VERSION}") if(OS_IS_MACOSX) - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(MAC_LIBRARIES "-framework Accelerate -lc++") - endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") -endif(OS_IS_MACOSX) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(MAC_LIBRARIES "-framework Accelerate -lc++") + endif() +endif() add_executable(gnss-sdr ${CMAKE_CURRENT_SOURCE_DIR}/main.cc) -add_custom_command(TARGET gnss-sdr POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ - ${CMAKE_SOURCE_DIR}/install/$ ) +add_custom_command(TARGET gnss-sdr + POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ + ${CMAKE_SOURCE_DIR}/install/$ +) -target_link_libraries(gnss-sdr ${MAC_LIBRARIES} - ${Boost_LIBRARIES} - ${GNURADIO_RUNTIME_LIBRARIES} - ${GNURADIO_BLOCKS_LIBRARIES} - ${GNURADIO_FFT_LIBRARIES} - ${GNURADIO_FILTER_LIBRARIES} - ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${ARMADILLO_LIBRARIES} - ${VOLK_GNSSSDR_LIBRARIES} - ${GNSS_SDR_OPTIONAL_LIBS} - gnss_sp_libs - gnss_sdr_flags - gnss_rx ) +target_link_libraries(gnss-sdr + ${MAC_LIBRARIES} + ${THREAD_LIBRARIES} + ${Boost_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${GNURADIO_FFT_LIBRARIES} + ${GNURADIO_FILTER_LIBRARIES} + ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${ARMADILLO_LIBRARIES} + ${VOLK_GNSSSDR_LIBRARIES} + ${GNSS_SDR_OPTIONAL_LIBS} + gnss_sp_libs + gnss_sdr_flags + gnss_rx +) install(TARGETS gnss-sdr - RUNTIME DESTINATION bin - COMPONENT "gnss-sdr" ) + RUNTIME DESTINATION bin + COMPONENT "gnss-sdr") install(DIRECTORY ${CMAKE_SOURCE_DIR}/conf DESTINATION share/gnss-sdr - FILES_MATCHING PATTERN "*.conf" ) + FILES_MATCHING PATTERN "*.conf") install(FILES ${CMAKE_SOURCE_DIR}/conf/gnss-sdr.conf DESTINATION share/gnss-sdr/conf - RENAME default.conf) + RENAME default.conf) -if(NOT VOLK_GNSSSDR_FOUND) +if(NOT VOLKGNSSSDR_FOUND) install(PROGRAMS ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/build/apps/volk_gnsssdr_profile DESTINATION bin COMPONENT "volk_gnsssdr") install(PROGRAMS ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/build/apps/volk_gnsssdr-config-info DESTINATION bin COMPONENT "volk_gnsssdr") -endif(NOT VOLK_GNSSSDR_FOUND) +endif() find_program(GZIP gzip @@ -120,22 +126,21 @@ find_program(GZIP if(NOT GZIP_NOTFOUND) execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/docs/manpage/gnss-sdr-manpage - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/gnss-sdr.1.gz") + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/gnss-sdr.1.gz") install(FILES ${CMAKE_BINARY_DIR}/gnss-sdr.1.gz DESTINATION share/man/man1) execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/docs/changelog - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/changelog.gz") + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/changelog.gz") install(FILES ${CMAKE_BINARY_DIR}/changelog.gz DESTINATION share/doc/gnss-sdr) - if(NOT VOLK_GNSSSDR_FOUND) - execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/volk_gnsssdr_profile.1.gz") - execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr-config-info-manpage - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/volk_gnsssdr-config-info.1.gz") - - install(FILES ${CMAKE_BINARY_DIR}/volk_gnsssdr_profile.1.gz DESTINATION share/man/man1) - install(FILES ${CMAKE_BINARY_DIR}/volk_gnsssdr-config-info.1.gz DESTINATION share/man/man1) - endif(NOT VOLK_GNSSSDR_FOUND) -endif(NOT GZIP_NOTFOUND) + if(NOT VOLKGNSSSDR_FOUND) + execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/volk_gnsssdr_profile.1.gz") + execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr-config-info-manpage + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/volk_gnsssdr-config-info.1.gz") + install(FILES ${CMAKE_BINARY_DIR}/volk_gnsssdr_profile.1.gz DESTINATION share/man/man1) + install(FILES ${CMAKE_BINARY_DIR}/volk_gnsssdr-config-info.1.gz DESTINATION share/man/man1) + endif() +endif() diff --git a/src/main/main.cc b/src/main/main.cc index ef12d5410..b7e06ea78 100644 --- a/src/main/main.cc +++ b/src/main/main.cc @@ -135,9 +135,10 @@ int main(int argc, char** argv) std::chrono::time_point start, end; start = std::chrono::system_clock::now(); + int return_code; try { - control_thread->run(); + return_code = control_thread->run(); } catch (const boost::exception& e) { @@ -189,5 +190,5 @@ int main(int argc, char** argv) google::ShutDownCommandLineFlags(); std::cout << "GNSS-SDR program ended." << std::endl; - return 0; + return return_code; } diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 54b3ac685..de39387b7 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -18,97 +18,100 @@ add_subdirectory(unit-tests/signal-processing-blocks/libs) +add_subdirectory(system-tests/libs) ################################################################################ # Google Test - https://github.com/google/googletest ################################################################################ if(EXISTS $ENV{GTEST_DIR}) - set(GTEST_DIR_LOCAL $ENV{GTEST_DIR}) -endif(EXISTS $ENV{GTEST_DIR}) + set(GTEST_DIR_LOCAL $ENV{GTEST_DIR}) +endif() if(GTEST_DIR) set(GTEST_DIR_LOCAL ${GTEST_DIR}) -endif(GTEST_DIR) +endif() if(NOT GTEST_DIR_LOCAL) set(GTEST_DIR_LOCAL false) else() set(GTEST_DIR_LOCAL true) -endif(NOT GTEST_DIR_LOCAL) +endif() if(GTEST_INCLUDE_DIRS) set(GTEST_DIR_LOCAL true) -endif(GTEST_INCLUDE_DIRS) +endif() set(GTEST_COMPILER -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}) set(TOOLCHAIN_ARG "") if(EXISTS $ENV{OECORE_TARGET_SYSROOT}) set(GTEST_COMPILER "") set(TOOLCHAIN_ARG "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/Toolchains/oe-sdk_cross.cmake") -endif(EXISTS $ENV{OECORE_TARGET_SYSROOT}) +endif() if(NOT ${GTEST_DIR_LOCAL}) - # if GTEST_DIR is not defined, we download and build it - if(CMAKE_VERSION VERSION_LESS 3.2) + # if GTEST_DIR is not defined, we download and build it + if(CMAKE_VERSION VERSION_LESS 3.2) ExternalProject_Add( - gtest-${GNSSSDR_GTEST_LOCAL_VERSION} - GIT_REPOSITORY https://github.com/google/googletest - GIT_TAG release-${GNSSSDR_GTEST_LOCAL_VERSION} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gtest/gtest-${GNSSSDR_GTEST_LOCAL_VERSION} - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gtest-${GNSSSDR_GTEST_LOCAL_VERSION} - CMAKE_ARGS ${GTEST_COMPILER} -DBUILD_GTEST=ON -DBUILD_GMOCK=OFF ${TOOLCHAIN_ARG} - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND "" + gtest-${GNSSSDR_GTEST_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/google/googletest + GIT_TAG release-${GNSSSDR_GTEST_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gtest/gtest-${GNSSSDR_GTEST_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gtest-${GNSSSDR_GTEST_LOCAL_VERSION} + CMAKE_ARGS ${GTEST_COMPILER} -DINSTALL_GTEST=OFF -DBUILD_GMOCK=OFF ${TOOLCHAIN_ARG} + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" ) - else(CMAKE_VERSION VERSION_LESS 3.2) + else() ExternalProject_Add( - gtest-${GNSSSDR_GTEST_LOCAL_VERSION} - GIT_REPOSITORY https://github.com/google/googletest - GIT_TAG release-${GNSSSDR_GTEST_LOCAL_VERSION} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gtest/gtest-${GNSSSDR_GTEST_LOCAL_VERSION} - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gtest-${GNSSSDR_GTEST_LOCAL_VERSION} - CMAKE_ARGS ${GTEST_COMPILER} -DBUILD_GTEST=ON -DBUILD_GMOCK=OFF ${TOOLCHAIN_ARG} - UPDATE_COMMAND "" - PATCH_COMMAND "" - BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/../../gtest-${GNSSSDR_GTEST_LOCAL_VERSION}/googletest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} - ${CMAKE_CURRENT_BINARY_DIR}/../../gtest-${GNSSSDR_GTEST_LOCAL_VERSION}/googletest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX} - INSTALL_COMMAND "" + gtest-${GNSSSDR_GTEST_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/google/googletest + GIT_TAG release-${GNSSSDR_GTEST_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gtest/gtest-${GNSSSDR_GTEST_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gtest-${GNSSSDR_GTEST_LOCAL_VERSION} + CMAKE_ARGS ${GTEST_COMPILER} -DINSTALL_GTEST=OFF -DBUILD_GMOCK=OFF ${TOOLCHAIN_ARG} + UPDATE_COMMAND "" + PATCH_COMMAND "" + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/../../gtest-${GNSSSDR_GTEST_LOCAL_VERSION}/googletest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} + ${CMAKE_CURRENT_BINARY_DIR}/../../gtest-${GNSSSDR_GTEST_LOCAL_VERSION}/googletest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX} + INSTALL_COMMAND "" ) - endif(CMAKE_VERSION VERSION_LESS 3.2) + endif() - # Set up variables - # Set recently downloaded and build Googletest root folder - set(GTEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gtest/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}/googletest") - # Source code - ExternalProject_Get_Property(gtest-${GNSSSDR_GTEST_LOCAL_VERSION} source_dir) - set(GTEST_INCLUDE_DIR ${source_dir}/googletest/include) - set(GTEST_INCLUDE_DIRECTORIES ${GTEST_DIR}/include ${GTEST_DIR} ${GTEST_DIR}/src) - # Library - ExternalProject_Get_Property(gtest-${GNSSSDR_GTEST_LOCAL_VERSION} binary_dir) - if(OS_IS_MACOSX) - if(CMAKE_GENERATOR STREQUAL Xcode) - set(binary_dir "${binary_dir}/Debug") - endif(CMAKE_GENERATOR STREQUAL Xcode) - endif(OS_IS_MACOSX) - set(GTEST_LIBRARY_PATH "${binary_dir}/googletest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest${CMAKE_STATIC_LIBRARY_SUFFIX};${binary_dir}/googletest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(GTEST_LIBRARY gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) - set(GTEST_LIBRARIES - ${binary_dir}/googletest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} - ${binary_dir}/googletest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX} - ) - set(GTEST_LIB_DIR "${CMAKE_CURRENT_BINARY_DIR}/../../gtest-${GNSSSDR_GTEST_LOCAL_VERSION}/googletest") -else(NOT ${GTEST_DIR_LOCAL}) - if(GTEST_INCLUDE_DIRS) - set(GTEST_INCLUDE_DIRECTORIES ${GTEST_INCLUDE_DIRS} ${LIBGTEST_DEV_DIR}) - add_library(gtest ${LIBGTEST_DEV_DIR}/src/gtest-all.cc ${LIBGTEST_DEV_DIR}/src/gtest_main.cc) - set(GTEST_LIBRARIES gtest) - else(GTEST_INCLUDE_DIRS) - # If the variable GTEST_DIR is defined, we use the existing Googletest - set(GTEST_DIR $ENV{GTEST_DIR}) - set(GTEST_INCLUDE_DIRECTORIES ${GTEST_DIR}/include ${GTEST_DIR} ${GTEST_DIR}/src) - add_library(gtest ${GTEST_DIR}/src/gtest-all.cc ${GTEST_DIR}/src/gtest_main.cc) - set(GTEST_LIBRARIES gtest) - endif(GTEST_INCLUDE_DIRS) -endif(NOT ${GTEST_DIR_LOCAL}) + # Set up variables + # Set recently downloaded and build Googletest root folder + set(GTEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gtest/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}/googletest") + # Source code + ExternalProject_Get_Property(gtest-${GNSSSDR_GTEST_LOCAL_VERSION} source_dir) + set(GTEST_INCLUDE_DIR ${source_dir}/googletest/include) + set(GTEST_INCLUDE_DIRECTORIES ${GTEST_DIR}/include ${GTEST_DIR} ${GTEST_DIR}/src) + # Library + ExternalProject_Get_Property(gtest-${GNSSSDR_GTEST_LOCAL_VERSION} binary_dir) + if(OS_IS_MACOSX) + if(CMAKE_GENERATOR STREQUAL Xcode) + set(FINAL_D "d") + set(ADD_DEBUG "Debug/") + endif() + endif() + set(GTEST_LIBRARY_PATH "${binary_dir}/googletest/${ADD_DEBUG}${CMAKE_FIND_LIBRARY_PREFIXES}gtest${FINAL_D}${CMAKE_STATIC_LIBRARY_SUFFIX};${binary_dir}/googletest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest_main${FINAL_D}${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GTEST_LIBRARY gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) + set(GTEST_LIBRARIES + ${binary_dir}/googletest/${ADD_DEBUG}${CMAKE_FIND_LIBRARY_PREFIXES}gtest${FINAL_D}${CMAKE_STATIC_LIBRARY_SUFFIX} + ${binary_dir}/googletest/${ADD_DEBUG}${CMAKE_FIND_LIBRARY_PREFIXES}gtest_main${FINAL_D}${CMAKE_STATIC_LIBRARY_SUFFIX} + ${THREAD_LIBRARIES}) + set(GTEST_LIB_DIR "${CMAKE_CURRENT_BINARY_DIR}/../../gtest-${GNSSSDR_GTEST_LOCAL_VERSION}/googletest") +else() + if(GTEST_INCLUDE_DIRS) + set(GTEST_INCLUDE_DIRECTORIES ${GTEST_INCLUDE_DIRS} ${LIBGTEST_DEV_DIR}) + add_library(gtest ${LIBGTEST_DEV_DIR}/src/gtest-all.cc ${LIBGTEST_DEV_DIR}/src/gtest_main.cc) + set(GTEST_LIBRARIES gtest) + else() + # If the variable GTEST_DIR is defined, we use the existing Googletest + set(GTEST_DIR $ENV{GTEST_DIR}) + set(GTEST_INCLUDE_DIRECTORIES ${GTEST_DIR}/include ${GTEST_DIR} ${GTEST_DIR}/src) + add_library(gtest ${GTEST_DIR}/src/gtest-all.cc ${GTEST_DIR}/src/gtest_main.cc) + set(GTEST_LIBRARIES gtest) + endif() + target_link_libraries(gtest ${THREAD_LIBRARIES}) +endif() @@ -121,230 +124,246 @@ set(GNSS_SDR_TEST_OPTIONAL_HEADERS "") if(ENABLE_CUDA) set(GNSS_SDR_TEST_OPTIONAL_HEADERS ${GNSS_SDR_TEST_OPTIONAL_HEADERS} ${CUDA_INCLUDE_DIRS}) set(GNSS_SDR_TEST_OPTIONAL_LIBS ${GNSS_SDR_TEST_OPTIONAL_LIBS} ${CUDA_LIBRARIES}) -endif(ENABLE_CUDA) +endif() if(ENABLE_GPERFTOOLS) if(GPERFTOOLS_FOUND) set(GNSS_SDR_TEST_OPTIONAL_LIBS "${GNSS_SDR_TEST_OPTIONAL_LIBS};${GPERFTOOLS_LIBRARIES}") set(GNSS_SDR_TEST_OPTIONAL_HEADERS "${GNSS_SDR_TEST_OPTIONAL_HEADERS};${GPERFTOOLS_INCLUDE_DIR}") - endif(GPERFTOOLS_FOUND) -endif(ENABLE_GPERFTOOLS) + endif() +endif() if(Boost_VERSION LESS 105000) - add_definitions(-DOLD_BOOST=1) -endif(Boost_VERSION LESS 105000) + add_definitions(-DOLD_BOOST=1) +endif() + +if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.13.4") + add_definitions(-DGR_GREATER_38=1) +endif() + +if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.15") + add_definitions(-DGR_GREATER_38=1) +endif() if(OPENSSL_FOUND) - add_definitions( -DUSE_OPENSSL_FALLBACK=1 ) -endif(OPENSSL_FOUND) + add_definitions(-DUSE_OPENSSL_FALLBACK=1) +endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if(OS_IS_MACOSX) - set(CLANG_FLAGS "-stdlib=libc++ -lc++") - endif(OS_IS_MACOSX) -endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CLANG_FLAGS "-stdlib=libc++ -lc++") + endif() +endif() if(OPENCL_FOUND) add_definitions(-DOPENCL_BLOCKS_TEST=1) -endif(OPENCL_FOUND) +endif() if(ENABLE_CUDA) add_definitions(-DCUDA_BLOCKS_TEST=1) -endif(ENABLE_CUDA) +endif() if(ENABLE_FPGA) add_definitions(-DFPGA_BLOCKS_TEST=1) -endif(ENABLE_FPGA) +endif() find_package(Gnuplot) if(GNUPLOT_FOUND) add_definitions(-DGNUPLOT_EXECUTABLE="${GNUPLOT_EXECUTABLE}") -endif(GNUPLOT_FOUND) +endif() -if(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.15" ) - add_definitions( -DGR_GREATER_38=1 ) -endif(${PC_GNURADIO_RUNTIME_VERSION} VERSION_GREATER "3.7.15" ) +if(ENABLE_UNIT_TESTING_MINIMAL) + add_definitions(-DUNIT_TESTING_MINIMAL=1) +endif() ################################################################################ # Optional generator ################################################################################ +option(ENABLE_GNSS_SIM_INSTALL "Enable the installation of gnss_sim on the fly" ON) if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) - if(ENABLE_FPGA) + if(ENABLE_FPGA) set(CROSS_INSTALL_DIR "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}") if(EXISTS $ENV{OECORE_TARGET_SYSROOT}) set(CROSS_INSTALL_DIR "${CROSS_INSTALL_DIR} -DBOOST_ROOT=$ENV{OECORE_TARGET_SYSROOT}/usr") - endif(EXISTS $ENV{OECORE_TARGET_SYSROOT}) - else(ENABLE_FPGA) + endif() + else() set(CROSS_INSTALL_DIR "") - endif(ENABLE_FPGA) - ExternalProject_Add( - gnss-sim - GIT_REPOSITORY https://bitbucket.org/jarribas/gnss-simulator - GIT_TAG ${GNSSSDR_GNSS_SIM_LOCAL_VERSION} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gnss-sim - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim - CMAKE_ARGS ${GTEST_COMPILER} ${TOOLCHAIN_ARG} ${CROSS_INSTALL_DIR} - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND "" - ) - if(ENABLE_INSTALL_TESTS) - install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim/gnss_sim DESTINATION bin) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n DESTINATION share/gnss-sim) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/circle.csv DESTINATION share/gnss-sim) - set(SW_GENERATOR_BIN ${CMAKE_INSTALL_PREFIX}/bin/gnss_sim) + endif() + find_package(GNSSSIMULATOR QUIET) + if(GNSSSIMULATOR_FOUND OR NOT ENABLE_GNSS_SIM_INSTALL) add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}") add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_INSTALL_PREFIX}/share/gnss-sim/brdc3540.14n") add_definitions(-DDEFAULT_POSITION_FILE="${CMAKE_INSTALL_PREFIX}/share/gnss-sim/circle.csv") - else(ENABLE_INSTALL_TESTS) - set(SW_GENERATOR_BIN ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim/gnss_sim) - add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}") - add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n") - add_definitions(-DDEFAULT_POSITION_FILE="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/circle.csv") - endif(ENABLE_INSTALL_TESTS) + else() + ExternalProject_Add( + gnss-sim + GIT_REPOSITORY https://bitbucket.org/jarribas/gnss-simulator + GIT_TAG ${GNSSSDR_GNSS_SIM_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gnss-sim + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim + CMAKE_ARGS ${GTEST_COMPILER} ${TOOLCHAIN_ARG} ${CROSS_INSTALL_DIR} + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + if(ENABLE_INSTALL_TESTS) + install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim/gnss_sim DESTINATION bin) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n DESTINATION share/gnss-sim) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/circle.csv DESTINATION share/gnss-sim) + set(SW_GENERATOR_BIN ${CMAKE_INSTALL_PREFIX}/bin/gnss_sim) + add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}") + add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_INSTALL_PREFIX}/share/gnss-sim/brdc3540.14n") + add_definitions(-DDEFAULT_POSITION_FILE="${CMAKE_INSTALL_PREFIX}/share/gnss-sim/circle.csv") + else() + set(SW_GENERATOR_BIN ${CMAKE_CURRENT_BINARY_DIR}/../../gnss-sim/gnss_sim) + add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}") + add_definitions(-DDEFAULT_RINEX_NAV="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/brdc3540.14n") + add_definitions(-DDEFAULT_POSITION_FILE="${CMAKE_CURRENT_BINARY_DIR}/../../../thirdparty/gnss-sim/circle.csv") + endif() + endif() - ################################################################################ - # Local installation of GPSTk http://www.gpstk.org/ - ################################################################################ - find_package(GPSTK) - if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) + ################################################################################ + # Local installation of GPSTk http://www.gpstk.org/ + ################################################################################ + find_package(GPSTK) + if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) message(STATUS "GPSTk v${GNSSSDR_GPSTK_LOCAL_VERSION} will be automatically downloaded and built when doing 'make'.") - if(NOT ENABLE_FPGA) - if(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add( - gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} - GIT_REPOSITORY https://github.com/SGL-UT/GPSTk - GIT_TAG v${GNSSSDR_GPSTK_LOCAL_VERSION} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} - CMAKE_ARGS ${GTEST_COMPILER} ${TOOLCHAIN_ARG} -DCMAKE_INSTALL_PREFIX=${CMAKE_SOURCE_DIR}/thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install -DBUILD_EXT=OFF -DBUILD_PYTHON=OFF - UPDATE_COMMAND "" - PATCH_COMMAND "" - ) - else(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add( - gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} - GIT_REPOSITORY https://github.com/SGL-UT/GPSTk - GIT_TAG v${GNSSSDR_GPSTK_LOCAL_VERSION} - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} - CMAKE_ARGS ${GTEST_COMPILER} ${TOOLCHAIN_ARG} -DCMAKE_INSTALL_PREFIX=${CMAKE_SOURCE_DIR}/thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install -DBUILD_EXT=OFF -DBUILD_PYTHON=OFF - BUILD_BYPRODUCTS ${CMAKE_SOURCE_DIR}/thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_SHARED_LIBRARY_SUFFIX} - UPDATE_COMMAND "" - PATCH_COMMAND "" - ) - endif(CMAKE_VERSION VERSION_LESS 3.2) - - set(GPSTK_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/include CACHE PATH "Local GPSTK headers") - add_library(gpstk UNKNOWN IMPORTED) - set_property(TARGET gpstk PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_SHARED_LIBRARY_SUFFIX}) - add_dependencies(gpstk gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}) - set(GPSTK_BINDIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/bin/ ) - add_definitions(-DGPSTK_BINDIR="${GPSTK_BINDIR}") - set(gpstk_libs gpstk) - set(OWN_GPSTK True) - else(NOT ENABLE_FPGA) - message(STATUS "GPSTk has not been found, try to install it on target.") - message(STATUS "Some extra tests requiring GPSTk will not be built.") - endif(NOT ENABLE_FPGA) - else(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) - set(gpstk_libs ${GPSTK_LIBRARIES}) - set(GPSTK_INCLUDE_DIRS ${GPSTK_INCLUDE_DIR}) - set(GPSTK_BINDIR ${GPSTK_LIBRARY}/../bin/ ) - add_definitions(-DGPSTK_BINDIR="${GPSTK_BINDIR}") - endif(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) -endif(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) + if("${TOOLCHAIN_ARG}" STREQUAL "") + set(TOOLCHAIN_ARG "-DCMAKE_CXX_FLAGS=\"-Wno-deprecated\"") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated") + endif() + include(GNUInstallDirs) + string(REGEX REPLACE /[^/]*$ "" LIBDIR ${CMAKE_INSTALL_LIBDIR}) + if(CMAKE_VERSION VERSION_LESS 3.2) + ExternalProject_Add( + gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/SGL-UT/GPSTk + GIT_TAG v${GNSSSDR_GPSTK_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} + CMAKE_ARGS ${GTEST_COMPILER} ${TOOLCHAIN_ARG} -DCMAKE_INSTALL_PREFIX=${CMAKE_SOURCE_DIR}/thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install -DBUILD_EXT=OFF -DBUILD_PYTHON=OFF + UPDATE_COMMAND "" + PATCH_COMMAND "" + ) + else() + ExternalProject_Add( + gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/SGL-UT/GPSTk + GIT_TAG v${GNSSSDR_GPSTK_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION} + CMAKE_ARGS ${GTEST_COMPILER} ${TOOLCHAIN_ARG} -DCMAKE_INSTALL_PREFIX=${CMAKE_SOURCE_DIR}/thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install -DBUILD_EXT=OFF -DBUILD_PYTHON=OFF + BUILD_BYPRODUCTS ${CMAKE_SOURCE_DIR}/thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/${LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_SHARED_LIBRARY_SUFFIX} + UPDATE_COMMAND "" + PATCH_COMMAND "" + ) + endif() + set(GPSTK_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/include CACHE PATH "Local GPSTK headers") + set(GPSTK_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/${LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(GPSTK_BINDIR ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/bin/) + add_definitions(-DGPSTK_BINDIR="${GPSTK_BINDIR}") + set(OWN_GPSTK True) + else() + set(GPSTK_INCLUDE_DIRS ${GPSTK_INCLUDE_DIR}) + set(GPSTK_BINDIR ${GPSTK_LIBRARY}/../bin/) + add_definitions(-DGPSTK_BINDIR="${GPSTK_BINDIR}") + endif() +endif() if(ENABLE_UNIT_TESTING_EXTRA) - add_definitions(-DEXTRA_TESTS) - if(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/gps_l2c_m_prn7_5msps.dat) + set(GNSS_SDR_TEST_OPTIONAL_LIBS ${GNSS_SDR_TEST_OPTIONAL_LIBS} ${GPSTK_LIBRARY}) + set(GNSS_SDR_TEST_OPTIONAL_HEADERS ${GNSS_SDR_TEST_OPTIONAL_HEADERS} ${GPSTK_INCLUDE_DIRS} ${GPSTK_INCLUDE_DIRS}/gpstk) +endif() + +if(ENABLE_UNIT_TESTING_EXTRA) + add_definitions(-DEXTRA_TESTS) + if(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/gps_l2c_m_prn7_5msps.dat) message(STATUS "Downloading some data files for testing...") file(DOWNLOAD https://sourceforge.net/projects/gnss-sdr/files/data/gps_l2c_m_prn7_5msps.dat ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/gps_l2c_m_prn7_5msps.dat - SHOW_PROGRESS - EXPECTED_HASH MD5=a6fcbefe155137945d3c33c5ef7bd0f9 ) - endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/gps_l2c_m_prn7_5msps.dat) - if(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat) + SHOW_PROGRESS + EXPECTED_HASH MD5=a6fcbefe155137945d3c33c5ef7bd0f9) + endif() + if(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat) message(STATUS "Downloading some data files for testing...") file(DOWNLOAD https://sourceforge.net/projects/gnss-sdr/files/data/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat - SHOW_PROGRESS - EXPECTED_HASH MD5=ffb72fc63c116be58d5e5ccb1daaed3a ) - endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat) - # if(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/NT1065_GLONASS_L2_20160831_fs6625e6_if0e3_4ms.bin) - # message(STATUS "Downloading some data files for testing...") - # file(DOWNLOAD https://sourceforge.net/projects/gnss-sdr/files/data/NT1065_GLONASS_L2_20160831_fs6625e6_if0e3_4ms.bin ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/NT1065_GLONASS_L2_20160831_fs6625e6_if0e3_4ms.bin - # SHOW_PROGRESS - # EXPECTED_HASH MD5=d7055fc1dc931872b547a148af50a09b ) - # endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples/NT1065_GLONASS_L2_20160831_fs6625e6_if0e3_4ms.bin) - if(ENABLE_INSTALL_TESTS) + SHOW_PROGRESS + EXPECTED_HASH MD5=ffb72fc63c116be58d5e5ccb1daaed3a) + endif() + if(ENABLE_INSTALL_TESTS) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/gps_l2c_m_prn7_5msps.dat DESTINATION share/gnss-sdr/signal_samples) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat DESTINATION share/gnss-sdr/signal_samples) - # install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/signal_samples/NT1065_GLONASS_L2_20160831_fs6625e6_if0e3_4ms.bin DESTINATION share/gnss-sdr/signal_samples) - endif(ENABLE_INSTALL_TESTS) -endif(ENABLE_UNIT_TESTING_EXTRA) + endif() +endif() if(ENABLE_INSTALL_TESTS) - install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat DESTINATION share/gnss-sdr/signal_samples) - install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat DESTINATION share/gnss-sdr/signal_samples) - install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat DESTINATION share/gnss-sdr/signal_samples) - install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin DESTINATION share/gnss-sdr/signal_samples) - add_definitions(-DTEST_PATH="${CMAKE_INSTALL_PREFIX}/share/gnss-sdr/") -else(ENABLE_INSTALL_TESTS) - file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) - file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) - file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) - file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) - add_definitions(-DTEST_PATH="${CMAKE_SOURCE_DIR}/thirdparty/") -endif(ENABLE_INSTALL_TESTS) + install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat DESTINATION share/gnss-sdr/signal_samples) + install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat DESTINATION share/gnss-sdr/signal_samples) + install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat DESTINATION share/gnss-sdr/signal_samples) + install(FILES ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin DESTINATION share/gnss-sdr/signal_samples) + install(FILES ${CMAKE_SOURCE_DIR}/src/tests/data/rtklib_test/obs_test1.xml DESTINATION share/gnss-sdr/data/rtklib_test) + install(FILES ${CMAKE_SOURCE_DIR}/src/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml DESTINATION share/gnss-sdr/data/rtklib_test) + add_definitions(-DTEST_PATH="${CMAKE_INSTALL_PREFIX}/share/gnss-sdr/") +else() + file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) + file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) + file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) + file(COPY ${CMAKE_SOURCE_DIR}/src/tests/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/signal_samples) + file(COPY ${CMAKE_SOURCE_DIR}/src/tests/data/rtklib_test/obs_test1.xml DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/data/rtklib_test) + file(COPY ${CMAKE_SOURCE_DIR}/src/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml DESTINATION ${CMAKE_SOURCE_DIR}/thirdparty/data/rtklib_test) + add_definitions(-DTEST_PATH="${CMAKE_SOURCE_DIR}/thirdparty/") +endif() set(LIST_INCLUDE_DIRS - ${GTEST_INCLUDE_DIRECTORIES} - ${CMAKE_SOURCE_DIR}/src/core/system_parameters - ${CMAKE_SOURCE_DIR}/src/core/interfaces - ${CMAKE_SOURCE_DIR}/src/core/receiver - ${CMAKE_SOURCE_DIR}/src/core/libs - ${CMAKE_SOURCE_DIR}/src/core/libs/supl - ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp - ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl - ${CMAKE_SOURCE_DIR}/src/core/monitor - ${CMAKE_SOURCE_DIR}/src/algorithms/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib - ${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/resampler/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/resampler/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/channel/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/channel/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/observables/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/observables/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/signal_generator/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/signal_generator/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/input_filter/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/input_filter/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs - ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/adapters - ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks - ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs - ${CMAKE_SOURCE_DIR}/src/tests/unit-tests/signal-processing-blocks/libs - ${CMAKE_SOURCE_DIR}/src/tests/common-files - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${GNURADIO_RUNTIME_INCLUDE_DIRS} - ${ARMADILLO_INCLUDE_DIRS} - ${VOLK_INCLUDE_DIRS} - ${VOLK_GNSSSDR_INCLUDE_DIRS} - ${MATIO_INCLUDE_DIRS} - ${GNSS_SDR_TEST_OPTIONAL_HEADERS} + ${GTEST_INCLUDE_DIRECTORIES} + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${CMAKE_SOURCE_DIR}/src/core/interfaces + ${CMAKE_SOURCE_DIR}/src/core/receiver + ${CMAKE_SOURCE_DIR}/src/core/libs + ${CMAKE_SOURCE_DIR}/src/core/libs/supl + ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp + ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl + ${CMAKE_SOURCE_DIR}/src/core/monitor + ${CMAKE_SOURCE_DIR}/src/algorithms/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/libs/rtklib + ${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/data_type_adapter/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/resampler/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/resampler/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/channel/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/channel/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/tracking/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/telemetry_decoder/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/observables/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/observables/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/signal_source/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/signal_generator/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/signal_generator/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/input_filter/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/input_filter/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs + ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/adapters + ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks + ${CMAKE_SOURCE_DIR}/src/algorithms/PVT/libs + ${CMAKE_SOURCE_DIR}/src/tests/unit-tests/signal-processing-blocks/libs + ${CMAKE_SOURCE_DIR}/src/tests/system-tests/libs + ${CMAKE_SOURCE_DIR}/src/tests/common-files + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${ARMADILLO_INCLUDE_DIRS} + ${VOLK_INCLUDE_DIRS} + ${VOLK_GNSSSDR_INCLUDE_DIRS} + ${MATIO_INCLUDE_DIRS} + ${PUGIXML_INCLUDE_DIR} + ${GNSS_SDR_TEST_OPTIONAL_HEADERS} ) include_directories(${LIST_INCLUDE_DIRS}) @@ -374,50 +393,53 @@ if(ENABLE_UNIT_TESTING) signal_generator_adapters pvt_gr_blocks signal_processing_testing_lib + system_testing_lib ${VOLK_GNSSSDR_LIBRARIES} ${MATIO_LIBRARIES} ${GNSS_SDR_TEST_OPTIONAL_LIBS} ) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(run_tests gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) - endif(NOT ${GTEST_DIR_LOCAL}) + endif() if(ENABLE_INSTALL_TESTS) if(EXISTS ${CMAKE_SOURCE_DIR}/install/run_tests) file(REMOVE ${CMAKE_SOURCE_DIR}/install/run_tests) - endif(EXISTS ${CMAKE_SOURCE_DIR}/install/run_tests) + endif() install(TARGETS run_tests RUNTIME DESTINATION bin COMPONENT "run_tests") - else(ENABLE_INSTALL_TESTS) + else() add_custom_command(TARGET run_tests POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ - ${CMAKE_SOURCE_DIR}/install/$) - endif(ENABLE_INSTALL_TESTS) -endif(ENABLE_UNIT_TESTING) + COMMAND ${CMAKE_COMMAND} -E copy $ + ${CMAKE_SOURCE_DIR}/install/$) + endif() +endif() if(ENABLE_FPGA) add_executable(gps_l1_ca_dll_pll_tracking_test_fpga - ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc ) + ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc + ) target_link_libraries(gps_l1_ca_dll_pll_tracking_test_fpga - ${Boost_LIBRARIES} - ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${GTEST_LIBRARIES} - ${GNURADIO_RUNTIME_LIBRARIES} - ${GNURADIO_BLOCKS_LIBRARIES} - ${ARMADILLO_LIBRARIES} - ${VOLK_LIBRARIES} - ${MATIO_LIBRARIES} - channel_fsm - gnss_sp_libs - gnss_rx - gnss_system_parameters - signal_processing_testing_lib - ) + ${Boost_LIBRARIES} + ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GTEST_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${ARMADILLO_LIBRARIES} + ${VOLK_LIBRARIES} + ${MATIO_LIBRARIES} + channel_fsm + gnss_sp_libs + gnss_rx + gnss_system_parameters + signal_processing_testing_lib + ) install(TARGETS gps_l1_ca_dll_pll_tracking_test_fpga - RUNTIME DESTINATION bin - COMPONENT "fpga-test" ) -endif(ENABLE_FPGA) + RUNTIME DESTINATION bin + COMPONENT "fpga-test" + ) +endif() @@ -431,29 +453,29 @@ function(add_system_test executable) # Ensure that executable is rebuilt if it was previously built and then removed if(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/${executable}) execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${SYSTEM_TEST_SOURCES}) - endif(NOT EXISTS ${CMAKE_SOURCE_DIR}/install/${executable}) + endif() add_executable(${executable} ${SYSTEM_TEST_SOURCES}) if(NOT ${GTEST_DIR_LOCAL}) - add_dependencies(${executable} gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ) - else(NOT ${GTEST_DIR_LOCAL}) + add_dependencies(${executable} gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) + else() add_dependencies(${executable} gtest) - endif(NOT ${GTEST_DIR_LOCAL}) + endif() include_directories(${OPT_INCLUDES_}) - target_link_libraries(${executable} ${OPT_LIBS_} ) + target_link_libraries(${executable} ${OPT_LIBS_}) if(ENABLE_INSTALL_TESTS) if(EXISTS ${CMAKE_SOURCE_DIR}/install/${executable}) file(REMOVE ${CMAKE_SOURCE_DIR}/install/${executable}) - endif(EXISTS ${CMAKE_SOURCE_DIR}/install/${executable}) + endif() install(TARGETS ${executable} RUNTIME DESTINATION bin COMPONENT "${executable}_test") - else(ENABLE_INSTALL_TESTS) + else() add_custom_command(TARGET ${executable} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ - ${CMAKE_SOURCE_DIR}/install/$ ) - endif(ENABLE_INSTALL_TESTS) -endfunction(add_system_test) + COMMAND ${CMAKE_COMMAND} -E copy $ + ${CMAKE_SOURCE_DIR}/install/$) + endif() +endfunction() if(ENABLE_SYSTEM_TESTING) @@ -461,66 +483,46 @@ if(ENABLE_SYSTEM_TESTING) if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(HOST_SYSTEM "GNU/Linux ${LINUX_DISTRIBUTION} ${LINUX_VER} ${ARCH_}") string(REPLACE "\n" "" HOST_SYSTEM "${HOST_SYSTEM}") - endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + string(REPLACE "\"" "" HOST_SYSTEM "${HOST_SYSTEM}") + endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(HOST_SYSTEM "MacOS") - endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + endif() add_definitions(-DHOST_SYSTEM="${HOST_SYSTEM}") #### TTFF - set(OPT_LIBS_ ${Boost_LIBRARIES} ${GFlags_LIBS} ${GLOG_LIBRARIES} + set(OPT_LIBS_ ${Boost_LIBRARIES} ${THREAD_LIBRARIES} ${GFlags_LIBS} ${GLOG_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES} ${GTEST_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES} ${GNURADIO_FILTER_LIBRARIES} ${GNURADIO_ANALOG_LIBRARIES} gnss_sp_libs - gnss_rx gnss_system_parameters ) + gnss_rx gnss_system_parameters) add_system_test(ttff) if(ENABLE_SYSTEM_TESTING_EXTRA) #### POSITION_TEST - set(OPT_LIBS_ ${Boost_LIBRARIES} ${GFlags_LIBS} ${GLOG_LIBRARIES} + set(OPT_LIBS_ ${Boost_LIBRARIES} ${THREAD_LIBRARIES} ${GFlags_LIBS} ${GLOG_LIBRARIES} ${GTEST_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES} ${GNURADIO_FILTER_LIBRARIES} ${GNURADIO_ANALOG_LIBRARIES} ${VOLK_GNSSSDR_LIBRARIES} - gnss_sp_libs gnss_rx gnss_system_parameters ) - + gnss_sp_libs gnss_rx gnss_system_parameters + system_testing_lib) add_system_test(position_test) - - if(GPSTK_FOUND OR OWN_GPSTK) - ## OBS_SYSTEM_TEST and OBS_GPS_L1_SYSTEM_TEST - set(OPT_LIBS_ ${GFlags_LIBS} ${GLOG_LIBRARIES} ${GTEST_LIBRARIES} - gnss_sp_libs gnss_rx ${gpstk_libs} ) - set(OPT_INCLUDES_ ${GPSTK_INCLUDE_DIRS} ${GPSTK_INCLUDE_DIRS}/gpstk) - add_system_test(obs_gps_l1_system_test) - add_system_test(obs_system_test) - endif(GPSTK_FOUND OR OWN_GPSTK) - else(ENABLE_SYSTEM_TESTING_EXTRA) + else() # Avoid working with old executables if they were switched ON and then OFF if(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) - file(REMOVE ${CMAKE_SOURCE_DIR}/install/position_test) - endif(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) - if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) - file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) - endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) - if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) - file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_system_test) - endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) - endif(ENABLE_SYSTEM_TESTING_EXTRA) -else(ENABLE_SYSTEM_TESTING) + file(REMOVE ${CMAKE_SOURCE_DIR}/install/position_test) + endif() + endif() +else() # Avoid working with old executables if they were switched ON and then OFF if(EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) - file(REMOVE ${CMAKE_SOURCE_DIR}/install/ttff) - endif(EXISTS ${CMAKE_SOURCE_DIR}/install/ttff) + file(REMOVE ${CMAKE_SOURCE_DIR}/install/ttff) + endif() if(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) file(REMOVE ${CMAKE_SOURCE_DIR}/install/position_test) - endif(EXISTS ${CMAKE_SOURCE_DIR}/install/position_test) - if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) - file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) - endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_gps_l1_system_test) - if(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) - file(REMOVE ${CMAKE_SOURCE_DIR}/install/obs_system_test) - endif(EXISTS ${CMAKE_SOURCE_DIR}/install/obs_system_test) -endif(ENABLE_SYSTEM_TESTING) + endif() +endif() ######################################################### @@ -530,185 +532,203 @@ set(CMAKE_CTEST_COMMAND ctest -V) add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) add_executable(flowgraph_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_flowgraph_test.cc ) + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_flowgraph_test.cc) target_link_libraries(flowgraph_test ${Boost_LIBRARIES} - ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${GNURADIO_RUNTIME_LIBRARIES} - ${GTEST_LIBRARIES} - gnss_sp_libs - gnss_rx - gnss_system_parameters - ${VOLK_GNSSSDR_LIBRARIES} ) + ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} + ${GTEST_LIBRARIES} + gnss_sp_libs + gnss_rx + gnss_system_parameters + ${VOLK_GNSSSDR_LIBRARIES} +) + add_test(flowgraph_test flowgraph_test) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(flowgraph_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) -else(NOT ${GTEST_DIR_LOCAL}) +else() add_dependencies(flowgraph_test gtest) -endif(NOT ${GTEST_DIR_LOCAL}) +endif() set_property(TEST flowgraph_test PROPERTY TIMEOUT 30) ######################################################### add_executable(gnss_block_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/sources/file_signal_source_test.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/adapter_test.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_block_factory_test.cc ) + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/sources/file_signal_source_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/adapter/adapter_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/gnss_block_factory_test.cc +) target_link_libraries(gnss_block_test ${Boost_LIBRARIES} - ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${GTEST_LIBRARIES} - ${GNURADIO_RUNTIME_LIBRARIES} - ${GNURADIO_BLOCKS_LIBRARIES} - ${GNURADIO_FILTER_LIBRARIES} - ${GNURADIO_ANALOG_LIBRARIES} - gnss_sp_libs - gnss_rx - gnss_system_parameters - ${VOLK_GNSSSDR_LIBRARIES} ) + ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GTEST_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${GNURADIO_FILTER_LIBRARIES} + ${GNURADIO_ANALOG_LIBRARIES} + gnss_sp_libs + gnss_rx + gnss_system_parameters + ${VOLK_GNSSSDR_LIBRARIES} +) add_test(gnss_block_test gnss_block_test) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(gnss_block_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) -else(NOT ${GTEST_DIR_LOCAL}) +else() add_dependencies(gnss_block_test gtest) -endif(NOT ${GTEST_DIR_LOCAL}) +endif() +set_property(TEST gnss_block_test PROPERTY TIMEOUT 60) ######################################################### add_executable(gnuradio_block_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc ) + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc +) target_link_libraries(gnuradio_block_test ${Boost_LIBRARIES} - ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${GTEST_LIBRARIES} - ${GNURADIO_RUNTIME_LIBRARIES} - ${GNURADIO_BLOCKS_LIBRARIES} - ${GNURADIO_FILTER_LIBRARIES} - ${GNURADIO_ANALOG_LIBRARIES} - gnss_sp_libs - gnss_rx - gnss_system_parameters - ${VOLK_GNSSSDR_LIBRARIES} ) + ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GTEST_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${GNURADIO_FILTER_LIBRARIES} + ${GNURADIO_ANALOG_LIBRARIES} + gnss_sp_libs + gnss_rx + gnss_system_parameters + ${VOLK_GNSSSDR_LIBRARIES} +) add_test(gnuradio_block_test gnuradio_block_test) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(gnuradio_block_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) -else(NOT ${GTEST_DIR_LOCAL}) +else() add_dependencies(gnuradio_block_test gtest) -endif(NOT ${GTEST_DIR_LOCAL}) +endif() +set_property(TEST gnuradio_block_test PROPERTY TIMEOUT 30) ######################################################### add_executable(matio_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/arithmetic/matio_test.cc ) - + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/arithmetic/matio_test.cc +) target_link_libraries(matio_test ${Boost_LIBRARIES} - ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${GTEST_LIBRARIES} - ${MATIO_LIBRARIES} - gnss_system_parameters ) + ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GTEST_LIBRARIES} + ${MATIO_LIBRARIES} + gnss_system_parameters +) add_test(matio_test matio_test) if(NOT ${GTEST_DIR_LOCAL}) if(MATIO_FOUND) add_dependencies(matio_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) - else(MATIO_FOUND) + else() add_dependencies(matio_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION} matio-${GNSSSDR_MATIO_LOCAL_VERSION}) - endif(MATIO_FOUND) -else(NOT ${GTEST_DIR_LOCAL}) - if(MATIO_FOUND) + endif() +else() + if(MATIO_FOUND) add_dependencies(matio_test gtest) - else(MATIO_FOUND) + else() add_dependencies(matio_test gtest matio-${GNSSSDR_MATIO_LOCAL_VERSION}) - endif(MATIO_FOUND) -endif(NOT ${GTEST_DIR_LOCAL}) + endif() +endif() +set_property(TEST matio_test PROPERTY TIMEOUT 30) ######################################################### add_executable(acq_test - ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc ) + ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc) target_link_libraries(acq_test ${Boost_LIBRARIES} - ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${GTEST_LIBRARIES} - ${GNURADIO_RUNTIME_LIBRARIES} - ${GNURADIO_BLOCKS_LIBRARIES} - ${GNURADIO_FILTER_LIBRARIES} - ${GNURADIO_ANALOG_LIBRARIES} - gnss_sp_libs - gnss_rx - gnss_system_parameters - signal_generator_blocks - signal_processing_testing_lib - ${VOLK_GNSSSDR_LIBRARIES} ) + ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GTEST_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${GNURADIO_FILTER_LIBRARIES} + ${GNURADIO_ANALOG_LIBRARIES} + gnss_sp_libs + gnss_rx + gnss_system_parameters + signal_generator_blocks + signal_processing_testing_lib + ${VOLK_GNSSSDR_LIBRARIES}) add_test(acq_test acq_test) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(acq_test acq_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) -else(NOT ${GTEST_DIR_LOCAL}) +else() add_dependencies(acq_test acq_test gtest) -endif(NOT ${GTEST_DIR_LOCAL}) +endif() +set_property(TEST acq_test PROPERTY TIMEOUT 30) ######################################################### add_executable(trk_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc ) + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/tracking/bayesian_estimation_test.cc +) target_link_libraries(trk_test ${Boost_LIBRARIES} - ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${GTEST_LIBRARIES} - ${GNURADIO_RUNTIME_LIBRARIES} - ${GNURADIO_BLOCKS_LIBRARIES} - ${GNURADIO_FILTER_LIBRARIES} - ${GNURADIO_ANALOG_LIBRARIES} - gnss_sp_libs - gnss_rx - gnss_system_parameters - signal_generator_blocks - ${VOLK_GNSSSDR_LIBRARIES} ) + ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GTEST_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${GNURADIO_FILTER_LIBRARIES} + ${GNURADIO_ANALOG_LIBRARIES} + gnss_sp_libs + gnss_rx + gnss_system_parameters + signal_generator_blocks + ${VOLK_GNSSSDR_LIBRARIES} +) add_test(trk_test trk_test) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(trk_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) -else(NOT ${GTEST_DIR_LOCAL}) +else() add_dependencies(trk_test gtest) -endif(NOT ${GTEST_DIR_LOCAL}) +endif() +set_property(TEST trk_test PROPERTY TIMEOUT 30) + ######################################################### if(NOT ENABLE_PACKAGING) add_executable(control_thread_test ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/control_message_factory_test.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/control_thread_test.cc ) + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/control_message_factory_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/control-plane/control_thread_test.cc + ) target_link_libraries(control_thread_test ${Boost_LIBRARIES} - ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${GTEST_LIBRARIES} - gnss_rx ) + ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${GTEST_LIBRARIES} + gnss_rx + ) add_test(control_thread_test control_thread_test) if(NOT ${GTEST_DIR_LOCAL}) add_dependencies(control_thread_test gtest-${GNSSSDR_GTEST_LOCAL_VERSION}) - else(NOT ${GTEST_DIR_LOCAL}) + else() add_dependencies(control_thread_test gtest) - endif(NOT ${GTEST_DIR_LOCAL}) + endif() set_property(TEST control_thread_test PROPERTY TIMEOUT 30) -endif(NOT ENABLE_PACKAGING) +endif() ######################################################### if(ENABLE_PACKAGING) add_dependencies(check flowgraph_test gnss_block_test - gnuradio_block_test acq_test trk_test matio_test) -else(ENABLE_PACKAGING) + gnuradio_block_test acq_test trk_test matio_test) +else() add_dependencies(check control_thread_test flowgraph_test gnss_block_test - gnuradio_block_test acq_test trk_test matio_test) -endif(ENABLE_PACKAGING) + gnuradio_block_test acq_test trk_test matio_test) +endif() diff --git a/src/tests/common-files/observable_tests_flags.h b/src/tests/common-files/observable_tests_flags.h new file mode 100644 index 000000000..37d2bab99 --- /dev/null +++ b/src/tests/common-files/observable_tests_flags.h @@ -0,0 +1,42 @@ +/*! + * \file tracking_tests_flags.h + * \brief Helper file for unit testing + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_OBSERVABLE_TESTS_FLAGS_H_ +#define GNSS_SDR_OBSERVABLE_TESTS_FLAGS_H_ + +#include +#include + +DEFINE_double(skip_obs_transitory_s, 30.0, "Skip the initial observable outputs to avoid transitory results [s]"); +DEFINE_bool(compute_single_diffs, false, "Compute also the single difference errors for Accumulated Carrier Phase and Carrier Doppler (requires LO synchronization between receivers)"); +DEFINE_bool(compare_with_5X, false, "Compare the E5a Doppler and Carrier Phases with the E5 full bw in RINEX (expect discrepancy due to the center frequencies differences"); +DEFINE_bool(duplicated_satellites_test, false, "Enable special observable test mode where the scenario contains duplicated satellite orbits"); +DEFINE_string(duplicated_satellites_prns, "1,2,3,4", "List of duplicated satellites PRN pairs (i.e. 1,2,3,4 indicates that the PRNs 1,2 share the same orbit. The same applies for PRNs 3,4)"); +#endif diff --git a/src/tests/common-files/signal_generator_flags.h b/src/tests/common-files/signal_generator_flags.h index e65e98846..b5e737adc 100644 --- a/src/tests/common-files/signal_generator_flags.h +++ b/src/tests/common-files/signal_generator_flags.h @@ -38,13 +38,14 @@ DEFINE_bool(disable_generator, false, "Disable the signal generator (a external DEFINE_string(generator_binary, std::string(SW_GENERATOR_BIN), "Path of software-defined signal generator binary"); DEFINE_string(rinex_nav_file, std::string(DEFAULT_RINEX_NAV), "Input RINEX navigation file"); DEFINE_int32(duration, 100, "Duration of the experiment [in seconds, max = 300]"); -DEFINE_string(static_position, "30.286502,120.032669,100", "Static receiver position [log,lat,height]"); +DEFINE_string(static_position, "30.286502,120.032669,100", "Static receiver position [latitude,longitude,height]"); DEFINE_string(dynamic_position, "", "Observer positions file, in .csv or .nmea format"); DEFINE_string(filename_rinex_obs, "sim.16o", "Filename of output RINEX navigation file"); DEFINE_string(filename_raw_data, "signal_out.bin", "Filename of output raw data file"); DEFINE_int32(fs_gen_sps, 2600000, "Sampling frequency [sps]"); DEFINE_int32(test_satellite_PRN, 1, "PRN of the satellite under test (must be visible during the observation time)"); DEFINE_int32(test_satellite_PRN2, 2, "PRN of the satellite under test (must be visible during the observation time)"); +DEFINE_string(test_satellite_PRN_list, "1,2,3,6,9,10,12,17,20,23,28", "List of PRN of the satellites under test (must be visible during the observation time)"); DEFINE_double(CN0_dBHz, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 [dB-Hz]"); #endif diff --git a/src/tests/common-files/tracking_tests_flags.h b/src/tests/common-files/tracking_tests_flags.h index dc54da91e..2ff85dabf 100644 --- a/src/tests/common-files/tracking_tests_flags.h +++ b/src/tests/common-files/tracking_tests_flags.h @@ -34,20 +34,26 @@ #include #include + +DEFINE_string(trk_test_implementation, std::string("GPS_L1_CA_DLL_PLL_Tracking"), "Tracking block implementation under test, defaults to GPS_L1_CA_DLL_PLL_Tracking"); // Input signal configuration DEFINE_bool(enable_external_signal_file, false, "Use an external signal file capture instead of the software-defined signal generator"); -DEFINE_int32(external_signal_acquisition_threshold, 2.0, "Threshold for satellite acquisition when external file is used"); +DEFINE_double(external_signal_acquisition_threshold, 2.5, "Threshold for satellite acquisition when external file is used"); +DEFINE_int32(external_signal_acquisition_dwells, 5, "Maximum dwells count for satellite acquisition when external file is used"); +DEFINE_double(external_signal_acquisition_doppler_max_hz, 5000.0, "Doppler max for satellite acquisition when external file is used"); +DEFINE_double(external_signal_acquisition_doppler_step_hz, 125.0, "Doppler step for satellite acquisition when external file is used"); + DEFINE_string(signal_file, std::string("signal_out.bin"), "Path of the external signal capture file"); DEFINE_double(CN0_dBHz_start, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]"); DEFINE_double(CN0_dBHz_stop, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]"); DEFINE_double(CN0_dB_step, 3.0, "Noise generator CN0 sweep step value [dB]"); -DEFINE_double(PLL_bw_hz_start, 40.0, "PLL Wide configuration start sweep value [Hz]"); -DEFINE_double(PLL_bw_hz_stop, 40.0, "PLL Wide configuration stop sweep value [Hz]"); +DEFINE_double(PLL_bw_hz_start, 20.0, "PLL Wide configuration start sweep value [Hz]"); +DEFINE_double(PLL_bw_hz_stop, 20.0, "PLL Wide configuration stop sweep value [Hz]"); DEFINE_double(PLL_bw_hz_step, 5.0, "PLL Wide configuration sweep step value [Hz]"); -DEFINE_double(DLL_bw_hz_start, 1.5, "DLL Wide configuration start sweep value [Hz]"); -DEFINE_double(DLL_bw_hz_stop, 1.5, "DLL Wide configuration stop sweep value [Hz]"); +DEFINE_double(DLL_bw_hz_start, 1.0, "DLL Wide configuration start sweep value [Hz]"); +DEFINE_double(DLL_bw_hz_stop, 1.0, "DLL Wide configuration stop sweep value [Hz]"); DEFINE_double(DLL_bw_hz_step, 0.25, "DLL Wide configuration sweep step value [Hz]"); DEFINE_double(PLL_narrow_bw_hz, 5.0, "PLL Narrow configuration value [Hz]"); @@ -61,13 +67,21 @@ DEFINE_double(acq_Delay_error_chips_start, 2.0, "Acquisition Code Delay error st DEFINE_double(acq_Delay_error_chips_stop, -2.0, "Acquisition Code Delay error stop sweep value [Chips]"); DEFINE_double(acq_Delay_error_chips_step, -0.1, "Acquisition Code Delay error sweep step value [Chips]"); +DEFINE_double(acq_to_trk_delay_s, 0.0, "Acquisition to Tracking delay value [s]"); + + +DEFINE_int64(skip_samples, 0, "Skip an initial transitory in the processed signal file capture [samples]"); DEFINE_int32(plot_detail_level, 0, "Specify the desired plot detail (0,1,2): 0 - Minimum plots (default) 2 - Plot all tracking parameters"); +DEFINE_double(skip_trk_transitory_s, 1.0, "Skip the initial tracking output signal to avoid transitory results [s]"); + //Emulated acquisition configuration //Tracking configuration DEFINE_int32(extend_correlation_symbols, 1, "Set the tracking coherent correlation to N symbols (up to 20 for GPS L1 C/A)"); +DEFINE_int32(smoother_length, 10, "Set the moving average size for the carrier phase and code phase in case of high dynamics"); +DEFINE_bool(high_dyn, false, "Activates the code resampler and NCO generator for high dynamics"); //Test output configuration DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); diff --git a/src/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml b/src/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml new file mode 100644 index 000000000..4dcc2564d --- /dev/null +++ b/src/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml @@ -0,0 +1,481 @@ + + + + + 11 + 0 + + 1 + + 1 + 5.18448000000000000e+05 + 9.20000000000000000e+01 + 9.20000000000000000e+01 + 1.83125000000000000e+01 + 4.86413118201646669e-09 + 2.06468198930943725e+00 + 9.42498445510864258e-07 + 3.73082922305911736e-03 + 5.76488673686981201e-06 + 5.15366174697875977e+03 + 5.18400000000000000e+05 + 5.18400000000000000e+05 + -5.40167093276977539e-08 + 9.52167247599200905e-01 + 1.86264514923095703e-08 + 9.61377026423456127e-01 + 2.66968750000000000e+02 + 4.44935333708291858e-01 + -8.14641075927847669e-09 + 4.15017287135849497e-10 + 0 + 799 + 0 + 2 + 0 + 5.12227416038513184e-09 + 9.20000000000000000e+01 + 27900 + 0 + 0.00000000000000000e+00 + 0.00000000000000000e+00 + -1.09937973320484161e-05 + 3.41060513164847988e-13 + 0.00000000000000000e+00 + 0 + 0 + 0 + + + + 2 + + 2 + 5.18448000000000000e+05 + 5.50000000000000000e+01 + 5.50000000000000000e+01 + 2.22812500000000000e+01 + 5.12771358985317661e-09 + 2.75926302782053146e+00 + 1.10082328319549561e-06 + 1.40569622162729484e-02 + 6.26407563686370850e-06 + 5.15372654151916504e+03 + 5.18400000000000000e+05 + 5.18400000000000000e+05 + -1.86264514923095703e-08 + 9.18037446344556307e-01 + -2.16066837310791016e-07 + 9.39991586696909520e-01 + 2.45468750000000000e+02 + -2.35598690357981555e+00 + -8.07140763509730069e-09 + 5.25736184736635464e-10 + 0 + 799 + 0 + 2 + 0 + -2.00234353542327881e-08 + 5.50000000000000000e+01 + 27900 + 0 + 0.00000000000000000e+00 + 0.00000000000000000e+00 + 5.36850653588771820e-04 + 2.16004991671070416e-12 + 0.00000000000000000e+00 + 0 + 0 + 0 + + + + 3 + + 3 + 5.18448000000000000e+05 + 7.00000000000000000e+01 + 7.00000000000000000e+01 + -2.04375000000000000e+01 + 4.75769817722603366e-09 + -1.78871492992227910e+00 + -1.30012631416320801e-06 + 9.70319728367030512e-04 + 8.26455652713775635e-06 + 5.15378153991699219e+03 + 5.18400000000000000e+05 + 5.18400000000000000e+05 + 7.82310962677001953e-08 + 1.99297660614955263e+00 + -1.11758708953857422e-08 + 9.59058451948379909e-01 + 2.19593750000000000e+02 + -3.00536842405812843e+00 + -8.02712007605698577e-09 + -5.17164399115929480e-10 + 0 + 799 + 0 + 2 + 0 + 5.12227416038513184e-09 + 7.00000000000000000e+01 + 27900 + 0 + 0.00000000000000000e+00 + 0.00000000000000000e+00 + 8.80691222846508026e-05 + 2.89901436190120811e-11 + 0.00000000000000000e+00 + 0 + 0 + 0 + + + + 6 + + 6 + 5.18448000000000000e+05 + 2.30000000000000000e+01 + 2.30000000000000000e+01 + 1.63750000000000000e+01 + 4.76305554323897445e-09 + -1.28531071631616522e+00 + 9.12696123123168945e-07 + 5.50022465176880251e-04 + 6.24358654022216797e-06 + 5.15365166282653809e+03 + 5.18400000000000000e+05 + 5.18400000000000000e+05 + -1.30385160446166992e-08 + 9.43624288779246867e-01 + -1.86264514923095703e-09 + 9.61292940818096020e-01 + 2.58406250000000000e+02 + 2.29191014519991665e+00 + -8.08069373618639861e-09 + 4.79305679291144535e-10 + 0 + 799 + 0 + 2 + 0 + 4.65661287307739258e-09 + 2.30000000000000000e+01 + 27900 + 0 + 0.00000000000000000e+00 + 0.00000000000000000e+00 + 3.07881273329257965e-05 + 8.18545231595635253e-12 + 0.00000000000000000e+00 + 0 + 0 + 0 + + + + 9 + + 9 + 5.18448000000000000e+05 + 4.70000000000000000e+01 + 4.70000000000000000e+01 + 1.12906250000000000e+02 + 4.37911097897818463e-09 + -2.75253879947800195e+00 + 5.85243105888366699e-06 + 2.16206186451017829e-04 + 1.16303563117980957e-05 + 5.15369471168518066e+03 + 5.18400000000000000e+05 + 5.18400000000000000e+05 + 1.67638063430786133e-08 + 3.03742251571970812e+00 + -1.11758708953857422e-08 + 9.59160503650671514e-01 + 1.56125000000000000e+02 + 2.60662251530764344e+00 + -7.85854162551643464e-09 + -3.46443002170201364e-11 + 0 + 799 + 0 + 2 + 0 + 4.65661287307739258e-10 + 4.70000000000000000e+01 + 27900 + 0 + 0.00000000000000000e+00 + 0.00000000000000000e+00 + -3.18535603582859039e-05 + -9.66338120633736091e-12 + 0.00000000000000000e+00 + 0 + 0 + 0 + + + + 10 + + 10 + 5.18448000000000000e+05 + 5.80000000000000000e+01 + 5.80000000000000000e+01 + -2.72500000000000000e+01 + 5.27093384126580581e-09 + -8.86982818851813737e-01 + -1.17719173431396484e-06 + 1.44534236751496774e-02 + 7.90506601333618164e-06 + 5.15363725471496582e+03 + 5.18400000000000000e+05 + 5.18400000000000000e+05 + 1.45286321640014648e-07 + 2.00408517949479270e+00 + 2.40281224250793457e-07 + 9.41160112993577269e-01 + 2.15406250000000000e+02 + 9.09732121011562200e-01 + -8.42213653007785350e-09 + -5.42879755978047536e-10 + 0 + 799 + 0 + 2 + 0 + -2.79396772384643555e-09 + 5.80000000000000000e+01 + 27900 + 0 + 0.00000000000000000e+00 + 0.00000000000000000e+00 + -1.54968351125717163e-04 + -1.59161572810262401e-12 + 0.00000000000000000e+00 + 0 + 0 + 0 + + + + 12 + + 12 + 5.18448000000000000e+05 + 1.06000000000000000e+02 + 1.06000000000000000e+02 + -1.17468750000000000e+02 + 3.94516433192994276e-09 + 1.11631735294997192e+00 + -6.15417957305908203e-06 + 5.05860964767634782e-03 + 4.52436506748199463e-06 + 5.15376680946350098e+03 + 5.18400000000000000e+05 + 5.18400000000000000e+05 + -5.40167093276977539e-08 + -1.10425023618040785e+00 + 4.09781932830810547e-08 + 9.88803748742243305e-01 + 3.07187500000000000e+02 + 5.00154452274795935e-01 + -7.97176062725659211e-09 + -4.18231706743614228e-10 + 0 + 799 + 0 + 2 + 0 + -1.16415321826934814e-08 + 1.06000000000000000e+02 + 27900 + 0 + 0.00000000000000000e+00 + 0.00000000000000000e+00 + 2.54871323704719543e-04 + 2.72848410531878391e-12 + 0.00000000000000000e+00 + 0 + 0 + 0 + + + + 17 + + 17 + 5.18448000000000000e+05 + 2.60000000000000000e+01 + 2.60000000000000000e+01 + -5.91250000000000000e+01 + 3.88194741297723567e-09 + -1.94252959218893162e+00 + -3.04728746414184570e-06 + 9.88844956737011498e-03 + 1.18296593427658081e-05 + 5.15369299888610840e+03 + 5.18400000000000000e+05 + 5.18400000000000000e+05 + 2.03028321266174316e-07 + -5.68690999805671268e-02 + -7.63684511184692383e-08 + 9.71201777972365177e-01 + 1.56531250000000000e+02 + -2.06928329237789344e+00 + -7.44602444251995675e-09 + 4.40375486263771432e-10 + 0 + 799 + 0 + 2 + 0 + -1.07102096080780029e-08 + 2.60000000000000000e+01 + 27900 + 0 + 0.00000000000000000e+00 + 0.00000000000000000e+00 + -1.44933816045522690e-04 + -2.27373675443232019e-12 + 0.00000000000000000e+00 + 0 + 0 + 0 + + + + 20 + + 20 + 5.18448000000000000e+05 + 1.17000000000000000e+02 + 1.17000000000000000e+02 + -2.58437500000000000e+01 + 5.60380484953655626e-09 + 1.28625710142833249e-01 + -1.52923166751861572e-06 + 5.80669869668781671e-03 + 7.51018524169921875e-06 + 5.15578671264648438e+03 + 5.18400000000000000e+05 + 5.18400000000000000e+05 + -2.23517417907714844e-08 + 1.92543994118208528e+00 + 4.65661287307739258e-08 + 9.26021286652122910e-01 + 2.18031250000000000e+02 + 1.23365536128043107e+00 + -8.54892752571746483e-09 + -5.16450083647537340e-10 + 0 + 799 + 0 + 2 + 0 + -8.38190317153930664e-09 + 1.17000000000000000e+02 + 27900 + 0 + 0.00000000000000000e+00 + 0.00000000000000000e+00 + 2.69209500402212143e-04 + 4.20641299569979229e-12 + 0.00000000000000000e+00 + 0 + 0 + 0 + + + + 23 + + 23 + 5.18448000000000000e+05 + 4.10000000000000000e+01 + 4.10000000000000000e+01 + 1.20250000000000000e+02 + 4.45161399901998963e-09 + 3.04794581942897569e+00 + 6.13741576671600342e-06 + 9.67817602213471954e-03 + 1.14180147647857666e-05 + 5.15370163154602051e+03 + 5.18400000000000000e+05 + 5.18400000000000000e+05 + -6.14672899246215820e-08 + 3.04748172476042711e+00 + -1.04308128356933594e-07 + 9.50229191282804808e-01 + 1.56000000000000000e+02 + -2.71676891930177256e+00 + -7.78032408172749087e-09 + -2.75011455330984601e-11 + 0 + 799 + 0 + 2 + 0 + -1.95577740669250488e-08 + 4.10000000000000000e+01 + 27900 + 0 + 0.00000000000000000e+00 + 0.00000000000000000e+00 + -7.56788067519664764e-05 + -2.72848410531878391e-12 + 0.00000000000000000e+00 + 0 + 0 + 0 + + + + 28 + + 28 + 5.18448000000000000e+05 + 3.30000000000000000e+01 + 3.30000000000000000e+01 + -1.27750000000000000e+02 + 4.04302555109966970e-09 + -1.16607683198628931e+00 + -6.37024641036987305e-06 + 1.97223023278638686e-02 + 5.66989183425903320e-06 + 5.15368548965454102e+03 + 5.18400000000000000e+05 + 5.18400000000000000e+05 + -1.37835741043090820e-07 + -1.08006546321039543e+00 + 4.35858964920043945e-07 + 9.87961552655681530e-01 + 2.84718750000000000e+02 + -1.69047108635756738e+00 + -8.17855495535612472e-09 + -4.44661379074124424e-10 + 0 + 799 + 0 + 2 + 0 + -1.11758708953857422e-08 + 3.30000000000000000e+01 + 27900 + 0 + 0.00000000000000000e+00 + 0.00000000000000000e+00 + 4.06486913561820984e-04 + 2.61479726759716828e-12 + 0.00000000000000000e+00 + 0 + 0 + 0 + + + + diff --git a/src/tests/data/rtklib_test/obs_test1.xml b/src/tests/data/rtklib_test/obs_test1.xml new file mode 100644 index 000000000..8c96fc2ff --- /dev/null +++ b/src/tests/data/rtklib_test/obs_test1.xml @@ -0,0 +1,358 @@ + + + + + 10 + 0 + + 0 + + 71 + + 3 + 49 + 67 + 0 + + 1 + 0 + 2.28200000000000000e+03 + -2.50000000000000000e+03 + 10791 + 0 + 0 + 2600000 + -3.85959140625000000e+04 + -9.03592163085937500e+02 + 5.96898384094238281e+01 + -2.57914688873291016e+03 + 8.35350813421410858e+05 + 3.31084377635761484e-01 + 133923691 + 1 + 1 + 1 + 518451424 + 2.28178186234515086e+07 + 5.18451500000000000e+05 + 1 + 5.18451423887949765e+08 + + + + 1 + + 71 + + 3 + 49 + 67 + 0 + + 3 + 1 + 2.38500000000000000e+03 + -3.00000000000000000e+03 + 68450858 + 0 + 0 + 2600000 + -4.34972734375000000e+04 + 4.21364685058593750e+02 + 5.16798934936523438e+01 + -3.12509065246582031e+03 + 4.93910706686261110e+05 + 7.36033200862493686e-01 + 133923971 + 1 + 1 + 1 + 518451431 + 2.07516033774388395e+07 + 5.18451500000000000e+05 + 1 + 5.18451430780101955e+08 + + + + 2 + + 71 + + 3 + 49 + 67 + 0 + + 28 + 2 + 1.52700000000000000e+03 + -3.00000000000000000e+03 + 1350770 + 0 + 0 + 2600000 + 4.46268046875000000e+04 + -3.98811938476562500e+03 + 5.25376167297363281e+01 + -2.92984253692626953e+03 + 9.35704822809229488e+05 + 9.30327007595224131e-01 + 133923941 + 1 + 1 + 1 + 518451436 + 1.92492043561209217e+07 + 5.18451500000000000e+05 + 1 + 5.18451435791565657e+08 + + + + 4 + + 71 + + 3 + 49 + 67 + 0 + + 23 + 4 + 1.13100000000000000e+03 + 1.00000000000000000e+03 + 994247 + 0 + 0 + 2600000 + 3.98655546875000000e+04 + -8.63781860351562500e+02 + 5.24684982299804688e+01 + 1.09281750951009121e+03 + -3.54128275530727289e+05 + 4.08304036132904002e-01 + 133922883 + 1 + 1 + 1 + 518451429 + 2.12256989876578376e+07 + 5.18451500000000000e+05 + 1 + 5.18451429198689222e+08 + + + + 5 + + 71 + + 3 + 49 + 67 + 0 + + 2 + 5 + 5.38000000000000000e+02 + 1.75000000000000000e+03 + 4917751 + 0 + 0 + 2600000 + -4.72456406250000000e+04 + -2.63723022460937500e+02 + 4.89446220397949219e+01 + 1.83319645690917969e+03 + -5.72184006019302527e+05 + 5.89544135488722532e-01 + 133922337 + 1 + 1 + 1 + 518451430 + 2.08629709015843943e+07 + 5.18451500000000000e+05 + 1 + 5.18451430408619881e+08 + + + + 6 + + 71 + + 3 + 49 + 67 + 0 + + 17 + 6 + 2.21000000000000000e+02 + 2.50000000000000000e+02 + 514377 + 0 + 0 + 2600000 + 4.27717460937500000e+04 + -9.45822082519531250e+02 + 5.38986015319824219e+01 + 2.73018497467041016e+02 + -9.09813659855529113e+04 + 6.57473345280777721e-01 + 133923172 + 1 + 1 + 1 + 518451440 + 1.79613337841309197e+07 + 5.18451500000000000e+05 + 1 + 5.18451440087439477e+08 + + + + 7 + + 71 + + 3 + 49 + 67 + 0 + + 9 + 7 + 1.56900000000000000e+03 + 2.25000000000000000e+03 + 7365787 + 0 + 0 + 2600000 + -3.96159960937500000e+04 + -5.03847460937500000e+03 + 5.33032913208007812e+01 + 2.30021731185913086e+03 + -7.04913853936602012e+05 + 3.21518194999043772e-01 + 133922169 + 1 + 1 + 1 + 518451430 + 2.08435687343175523e+07 + 5.18451500000000000e+05 + 1 + 5.18451430473338544e+08 + + + + 8 + + 71 + + 3 + 49 + 67 + 0 + + 10 + 8 + 2.12600000000000000e+03 + 2.75000000000000000e+03 + 2173576 + 0 + 0 + 2600000 + 4.00322539062500000e+04 + -3.88590087890625000e+02 + 4.85561523437500000e+01 + 2.81225794982910156e+03 + -8.99142229977656389e+05 + 1.02370741655249731e-01 + 133922664 + 1 + 1 + 1 + 518451438 + 1.85022797143675610e+07 + 5.18451500000000000e+05 + 1 + 5.18451438283038080e+08 + + + + 9 + + 71 + + 3 + 49 + 67 + 0 + + 12 + 9 + 2.13000000000000000e+02 + 3.00000000000000000e+03 + 7464974 + 0 + 0 + 2600000 + -4.03654140625000000e+04 + 3.92351245117187500e+03 + 5.17314453125000000e+01 + 3.03019989013671875e+03 + -9.28340507655202877e+05 + 5.73995602361264901e-01 + 133923741 + 1 + 1 + 1 + 518451427 + 2.19242346189941987e+07 + 5.18451500000000000e+05 + 1 + 5.18451426868625164e+08 + + + + 10 + + 71 + + 3 + 49 + 67 + 0 + + 6 + 10 + 4.70000000000000000e+01 + 5.00000000000000000e+02 + 1859813 + 0 + 0 + 2600000 + 3.87814335937500000e+04 + 2.13637329101562500e+03 + 6.00463027954101562e+01 + 5.54514957427978516e+02 + -1.78723083774703584e+05 + 3.47952294631795667e-01 + 133924211 + 1 + 1 + 1 + 518451439 + 1.83808922785463184e+07 + 5.18451500000000000e+05 + 1 + 5.18451438687942982e+08 + + + + diff --git a/src/tests/single_test_main.cc b/src/tests/single_test_main.cc index 5dbfee8f9..d539f2563 100644 --- a/src/tests/single_test_main.cc +++ b/src/tests/single_test_main.cc @@ -29,6 +29,8 @@ * ------------------------------------------------------------------------- */ +#include "agnss_ref_location.h" +#include "agnss_ref_time.h" #include "concurrent_queue.h" #include "concurrent_map.h" #include "gps_navigation_message.h" @@ -36,8 +38,6 @@ #include "gps_cnav_ephemeris.h" #include "gps_cnav_iono.h" #include "gps_acq_assist.h" -#include "gps_ref_location.h" -#include "gps_ref_time.h" #include "galileo_navigation_message.h" #include #include diff --git a/src/tests/system-tests/libs/CMakeLists.txt b/src/tests/system-tests/libs/CMakeLists.txt new file mode 100644 index 000000000..178f83479 --- /dev/null +++ b/src/tests/system-tests/libs/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright (C) 2012-2018 (see AUTHORS file for a list of contributors) +# +# This file is part of GNSS-SDR. +# +# GNSS-SDR is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GNSS-SDR is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNSS-SDR. If not, see . +# + + +set(SYSTEM_TESTING_LIB_SOURCES + spirent_motion_csv_dump_reader.cc + rtklib_solver_dump_reader.cc +) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${Boost_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${MATIO_INCLUDE_DIRS} + ${ARMADILLO_INCLUDE_DIRS} +) + +file(GLOB SYSTEM_TESTING_LIB_HEADERS "*.h") +list(SORT SYSTEM_TESTING_LIB_HEADERS) + +add_library(system_testing_lib + ${SYSTEM_TESTING_LIB_SOURCES} + ${SYSTEM_TESTING_LIB_HEADERS} +) + +source_group(Headers FILES ${SYSTEM_TESTING_LIB_HEADERS}) + +if(NOT MATIO_FOUND) + add_dependencies(system_testing_lib + armadillo-${armadillo_RELEASE} + matio-${GNSSSDR_MATIO_LOCAL_VERSION} + ) +else() + add_dependencies(system_testing_lib armadillo-${armadillo_RELEASE}) +endif() diff --git a/src/tests/system-tests/libs/position_test_flags.h b/src/tests/system-tests/libs/position_test_flags.h new file mode 100644 index 000000000..1ebe296e6 --- /dev/null +++ b/src/tests/system-tests/libs/position_test_flags.h @@ -0,0 +1,50 @@ +/*! + * \file signal_generator_flags.h + * \brief Helper file for unit testing + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_POSITION_TEST_FLAGS_H_ +#define GNSS_SDR_POSITION_TEST_FLAGS_H_ + +#include +#include + +DEFINE_string(config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); +DEFINE_bool(plot_position_test, false, "Plots results of with gnuplot"); +DEFINE_bool(static_scenario, true, "Compute figures of merit for static user position (DRMS, CEP, etc..)"); +DEFINE_bool(use_ref_motion_file, false, "Enable or disable the use of a reference file containing the true receiver position, velocity and acceleration."); +DEFINE_int32(ref_motion_file_type, 1, "Type of reference motion file: 1- Spirent CSV motion file"); +DEFINE_string(ref_motion_filename, std::string("motion.csv"), "Path and filename for the reference motion file"); +DEFINE_string(pvt_solver_dump_filename, std::string("PVT.dat"), "Path and filename for the PVT solver binary dump file"); +DEFINE_double(static_2D_error_m, 2.0, "Static scenario 2D (East, North) positioning error threshold [meters]"); +DEFINE_double(static_3D_error_m, 5.0, "Static scenario 3D (East, North, Up) positioning error threshold [meters]"); +DEFINE_double(accuracy_CEP, 2.0, "Static scenario 2D (East, North) accuracy Circular Error Position (CEP) threshold [meters]"); +DEFINE_double(precision_SEP, 10.0, "Static scenario 3D (East, North, Up) precision Spherical Error Position (SEP) threshold [meters]"); +DEFINE_double(dynamic_3D_position_RMSE, 10.0, "Dynamic scenario 3D (ECEF) accuracy RMSE threshold [meters]"); +DEFINE_double(dynamic_3D_velocity_RMSE, 5.0, "Dynamic scenario 3D (ECEF) velocity accuracy RMSE threshold [meters/second]"); +#endif diff --git a/src/tests/system-tests/libs/rtklib_solver_dump_reader.cc b/src/tests/system-tests/libs/rtklib_solver_dump_reader.cc new file mode 100644 index 000000000..b32f12bc5 --- /dev/null +++ b/src/tests/system-tests/libs/rtklib_solver_dump_reader.cc @@ -0,0 +1,138 @@ +/*! + * \file rtklib_solver_dump_reader.cc + * \brief Helper file for unit testing + * \author Javier Arribas, 2017. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "rtklib_solver_dump_reader.h" +#include + +bool rtklib_solver_dump_reader::read_binary_obs() +{ + try + { + d_dump_file.read(reinterpret_cast(&TOW_at_current_symbol_ms), sizeof(uint32_t)); + d_dump_file.read(reinterpret_cast(&week), sizeof(uint32_t)); + d_dump_file.read(reinterpret_cast(&RX_time), sizeof(double)); + d_dump_file.read(reinterpret_cast(&clk_offset_s), sizeof(double)); + d_dump_file.read(reinterpret_cast(&rr[0]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&rr[1]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&rr[2]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&rr[3]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&rr[4]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&rr[5]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&qr[0]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&qr[1]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&qr[2]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&qr[3]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&qr[4]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&qr[5]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&latitude), sizeof(double)); + d_dump_file.read(reinterpret_cast(&longitude), sizeof(double)); + d_dump_file.read(reinterpret_cast(&height), sizeof(double)); + d_dump_file.read(reinterpret_cast(&ns), sizeof(uint8_t)); + d_dump_file.read(reinterpret_cast(&status), sizeof(uint8_t)); + d_dump_file.read(reinterpret_cast(&type), sizeof(uint8_t)); + d_dump_file.read(reinterpret_cast(&AR_ratio), sizeof(float)); + d_dump_file.read(reinterpret_cast(&AR_thres), sizeof(float)); + d_dump_file.read(reinterpret_cast(&dop[0]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&dop[1]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&dop[2]), sizeof(double)); + d_dump_file.read(reinterpret_cast(&dop[3]), sizeof(double)); + } + catch (const std::ifstream::failure &e) + { + return false; + } + return true; +} + + +bool rtklib_solver_dump_reader::restart() +{ + if (d_dump_file.is_open()) + { + d_dump_file.clear(); + d_dump_file.seekg(0, std::ios::beg); + return true; + } + else + { + return false; + } +} + + +int64_t rtklib_solver_dump_reader::num_epochs() +{ + std::ifstream::pos_type size; + int epoch_size_bytes = 2 * sizeof(uint32_t) + 21 * sizeof(double) + 3 * sizeof(uint8_t) + 2 * sizeof(float); + std::ifstream tmpfile(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); + if (tmpfile.is_open()) + { + size = tmpfile.tellg(); + int64_t nepoch = size / epoch_size_bytes; + return nepoch; + } + else + { + return 0; + } +} + + +bool rtklib_solver_dump_reader::open_obs_file(std::string out_file) +{ + if (d_dump_file.is_open() == false) + { + try + { + d_dump_filename = out_file; + d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + d_dump_file.open(d_dump_filename.c_str(), std::ios::in | std::ios::binary); + return true; + } + catch (const std::ifstream::failure &e) + { + std::cout << "Problem opening rtklib_solver dump Log file: " << d_dump_filename.c_str() << std::endl; + return false; + } + } + else + { + return false; + } +} + + +rtklib_solver_dump_reader::~rtklib_solver_dump_reader() +{ + if (d_dump_file.is_open() == true) + { + d_dump_file.close(); + } +} diff --git a/src/tests/system-tests/libs/rtklib_solver_dump_reader.h b/src/tests/system-tests/libs/rtklib_solver_dump_reader.h new file mode 100644 index 000000000..5006482dd --- /dev/null +++ b/src/tests/system-tests/libs/rtklib_solver_dump_reader.h @@ -0,0 +1,88 @@ +/*! + * \file rtklib_solver_dump_reader.h + * \brief Helper file for unit testing + * \author Javier Arribas, 2017. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_RTKLIB_SOLVER_DUMP_READER_H +#define GNSS_SDR_RTKLIB_SOLVER_DUMP_READER_H + +#include +#include +#include +#include + +class rtklib_solver_dump_reader +{ +public: + ~rtklib_solver_dump_reader(); + bool read_binary_obs(); + bool restart(); + int64_t num_epochs(); + bool open_obs_file(std::string out_file); + + // rtklib_solver dump variables + // TOW + uint32_t TOW_at_current_symbol_ms; + // WEEK + uint32_t week; + // PVT GPS time + double RX_time; + // User clock offset [s] + double clk_offset_s; + // ECEF POS X,Y,X [m] + ECEF VEL X,Y,X [m/s] (6 x double) + double rr[6]; + // position variance/covariance (m^2) {c_xx,c_yy,c_zz,c_xy,c_yz,c_zx} (6 x double) + double qr[6]; + + // GEO user position Latitude [deg] + double latitude; + // GEO user position Longitude [deg] + double longitude; + // GEO user position Height [m] + double height; + + // NUMBER OF VALID SATS + uint8_t ns; + // RTKLIB solution status + uint8_t status; + // RTKLIB solution type (0:xyz-ecef,1:enu-baseline) + uint8_t type; + // AR ratio factor for validation + float AR_ratio; + // AR ratio threshold for validation + float AR_thres; + + // GDOP / PDOP / HDOP / VDOP + double dop[4]; + +private: + std::string d_dump_filename; + std::ifstream d_dump_file; +}; + +#endif //GNSS_SDR_RTKLIB_SOLVER_DUMP_READER_H diff --git a/src/tests/system-tests/libs/spirent_motion_csv_dump_reader.cc b/src/tests/system-tests/libs/spirent_motion_csv_dump_reader.cc new file mode 100644 index 000000000..15cd3335d --- /dev/null +++ b/src/tests/system-tests/libs/spirent_motion_csv_dump_reader.cc @@ -0,0 +1,250 @@ +/*! + * \file spirent_motion_csv_dump_reader.cc + * \brief Helper file for unit testing + * \author Javier Arribas, 2017. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "spirent_motion_csv_dump_reader.h" +#include +#include + + +spirent_motion_csv_dump_reader::spirent_motion_csv_dump_reader() +{ + header_lines = 2; + TOW_ms = 0.0; + Pos_X = 0.0; + Pos_Y = 0.0; + Pos_Z = 0.0; + Vel_X = 0.0; + Vel_Y = 0.0; + Vel_Z = 0.0; + Acc_X = 0.0; + Acc_Y = 0.0; + Acc_Z = 0.0; + Jerk_X = 0.0; + Jerk_Y = 0.0; + Jerk_Z = 0.0; + Lat = 0.0; + Long = 0.0; + Height = 0.0; + Heading = 0.0; + Elevation = 0.0; + Bank = 0.0; + Ang_vel_X = 0.0; + Ang_vel_Y = 0.0; + Ang_vel_Z = 0.0; + Ang_acc_X = 0.0; + Ang_acc_Y = 0.0; + Ang_acc_Z = 0.0; + Ant1_Pos_X = 0.0; + Ant1_Pos_Y = 0.0; + Ant1_Pos_Z = 0.0; + Ant1_Vel_X = 0.0; + Ant1_Vel_Y = 0.0; + Ant1_Vel_Z = 0.0; + Ant1_Acc_X = 0.0; + Ant1_Acc_Y = 0.0; + Ant1_Acc_Z = 0.0; + Ant1_Lat = 0.0; + Ant1_Long = 0.0; + Ant1_Height = 0.0; + Ant1_DOP = 0.0; +} + + +spirent_motion_csv_dump_reader::~spirent_motion_csv_dump_reader() +{ + if (d_dump_file.is_open() == true) + { + d_dump_file.close(); + } +} + + +bool spirent_motion_csv_dump_reader::read_csv_obs() +{ + try + { + std::vector vec; + std::string line; + if (getline(d_dump_file, line)) + { + boost::tokenizer> tk( + line, boost::escaped_list_separator('\\', ',', '\"')); + for (boost::tokenizer>::iterator i( + tk.begin()); + i != tk.end(); ++i) + { + try + { + vec.push_back(std::stod(*i)); + } + catch (const std::exception &ex) + { + vec.push_back(0.0); + } + } + parse_vector(vec); + } + } + catch (const std::ifstream::failure &e) + { + return false; + } + return true; +} + + +bool spirent_motion_csv_dump_reader::parse_vector(std::vector &vec) +{ + try + { + int n = 0; + TOW_ms = vec.at(n++); + Pos_X = vec.at(n++); + Pos_Y = vec.at(n++); + Pos_Z = vec.at(n++); + Vel_X = vec.at(n++); + Vel_Y = vec.at(n++); + Vel_Z = vec.at(n++); + Acc_X = vec.at(n++); + Acc_Y = vec.at(n++); + Acc_Z = vec.at(n++); + Jerk_X = vec.at(n++); + Jerk_Y = vec.at(n++); + Jerk_Z = vec.at(n++); + Lat = vec.at(n++); + Long = vec.at(n++); + Height = vec.at(n++); + Heading = vec.at(n++); + Elevation = vec.at(n++); + Bank = vec.at(n++); + Ang_vel_X = vec.at(n++); + Ang_vel_Y = vec.at(n++); + Ang_vel_Z = vec.at(n++); + Ang_acc_X = vec.at(n++); + Ang_acc_Y = vec.at(n++); + Ang_acc_Z = vec.at(n++); + Ant1_Pos_X = vec.at(n++); + Ant1_Pos_Y = vec.at(n++); + Ant1_Pos_Z = vec.at(n++); + Ant1_Vel_X = vec.at(n++); + Ant1_Vel_Y = vec.at(n++); + Ant1_Vel_Z = vec.at(n++); + Ant1_Acc_X = vec.at(n++); + Ant1_Acc_Y = vec.at(n++); + Ant1_Acc_Z = vec.at(n++); + Ant1_Lat = vec.at(n++); + Ant1_Long = vec.at(n++); + Ant1_Height = vec.at(n++); + Ant1_DOP = vec.at(n++); + return true; + } + catch (const std::exception &ex) + { + return false; + } +} + + +bool spirent_motion_csv_dump_reader::restart() +{ + if (d_dump_file.is_open()) + { + d_dump_file.clear(); + d_dump_file.seekg(0, std::ios::beg); + std::string line; + for (int n = 0; n < header_lines; n++) + { + getline(d_dump_file, line); + } + return true; + } + else + { + return false; + } +} + + +int64_t spirent_motion_csv_dump_reader::num_epochs() +{ + int64_t nepoch = 0LL; + std::string line; + std::ifstream tmpfile(d_dump_filename.c_str()); + if (tmpfile.is_open()) + { + while (std::getline(tmpfile, line)) + { + ++nepoch; + } + return nepoch - header_lines; + } + else + { + return 0; + } +} + + +bool spirent_motion_csv_dump_reader::open_obs_file(std::string out_file) +{ + if (d_dump_file.is_open() == false) + { + try + { + d_dump_filename = out_file; + d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + d_dump_file.open(d_dump_filename.c_str()); + std::string line; + for (int n = 0; n < header_lines; n++) + { + getline(d_dump_file, line); + } + return true; + } + catch (const std::ifstream::failure &e) + { + std::cout << "Problem opening Spirent CSV dump Log file: " << d_dump_filename.c_str() << std::endl; + return false; + } + } + else + { + return false; + } +} + + +void spirent_motion_csv_dump_reader::close_obs_file() +{ + if (d_dump_file.is_open() == false) + { + d_dump_file.close(); + } +} diff --git a/src/tests/system-tests/libs/spirent_motion_csv_dump_reader.h b/src/tests/system-tests/libs/spirent_motion_csv_dump_reader.h new file mode 100644 index 000000000..b08beb6e0 --- /dev/null +++ b/src/tests/system-tests/libs/spirent_motion_csv_dump_reader.h @@ -0,0 +1,97 @@ +/*! + * \file spirent_motion_csv_dump_reader.h + * \brief Helper file for unit testing + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_SPIRENT_MOTION_CSV_DUMP_READER_H +#define GNSS_SDR_SPIRENT_MOTION_CSV_DUMP_READER_H + +#include +#include +#include +#include + +class spirent_motion_csv_dump_reader +{ +public: + spirent_motion_csv_dump_reader(); + ~spirent_motion_csv_dump_reader(); + bool read_csv_obs(); + bool restart(); + int64_t num_epochs(); + bool open_obs_file(std::string out_file); + void close_obs_file(); + + int header_lines; + // dump variables + double TOW_ms; + double Pos_X; + double Pos_Y; + double Pos_Z; + double Vel_X; + double Vel_Y; + double Vel_Z; + double Acc_X; + double Acc_Y; + double Acc_Z; + double Jerk_X; + double Jerk_Y; + double Jerk_Z; + double Lat; + double Long; + double Height; + double Heading; + double Elevation; + double Bank; + double Ang_vel_X; + double Ang_vel_Y; + double Ang_vel_Z; + double Ang_acc_X; + double Ang_acc_Y; + double Ang_acc_Z; + double Ant1_Pos_X; + double Ant1_Pos_Y; + double Ant1_Pos_Z; + double Ant1_Vel_X; + double Ant1_Vel_Y; + double Ant1_Vel_Z; + double Ant1_Acc_X; + double Ant1_Acc_Y; + double Ant1_Acc_Z; + double Ant1_Lat; + double Ant1_Long; + double Ant1_Height; + double Ant1_DOP; + +private: + std::string d_dump_filename; + std::ifstream d_dump_file; + bool parse_vector(std::vector &vec); +}; + +#endif // GNSS_SDR_SPIRENT_MOTION_CSV_DUMP_READER_H diff --git a/src/tests/system-tests/obs_gps_l1_system_test.cc b/src/tests/system-tests/obs_gps_l1_system_test.cc deleted file mode 100644 index 7af66e15d..000000000 --- a/src/tests/system-tests/obs_gps_l1_system_test.cc +++ /dev/null @@ -1,719 +0,0 @@ -/*! - * \file obs_gps_l1_system_test.cc - * \brief This class implements a test for the validation of generated observables. - * \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es - * - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) - * - * GNSS-SDR is a software defined Global Navigation - * Satellite Systems receiver - * - * This file is part of GNSS-SDR. - * - * GNSS-SDR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNSS-SDR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . - * - * ------------------------------------------------------------------------- - */ - -#include "concurrent_map.h" -#include "concurrent_queue.h" -#include "control_thread.h" -#include "in_memory_configuration.h" -#include "signal_generator_flags.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// For GPS NAVIGATION (L1) -concurrent_queue global_gps_acq_assist_queue; -concurrent_map global_gps_acq_assist_map; - - -class ObsGpsL1SystemTest : public ::testing::Test -{ -public: - std::string generator_binary; - std::string p1; - std::string p2; - std::string p3; - std::string p4; - std::string p5; - - const double baseband_sampling_freq = 2.6e6; - - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; - std::string filename_raw_data = FLAGS_filename_raw_data; - std::string generated_rinex_obs; - int configure_generator(); - int generate_signal(); - int configure_receiver(); - int run_receiver(); - void check_results(); - bool check_valid_rinex_nav(std::string filename); // return true if the file is a valid Rinex navigation file. - bool check_valid_rinex_obs(std::string filename); // return true if the file is a valid Rinex observation file. - double compute_stdev(const std::vector& vec); - - std::shared_ptr config; -}; - - -bool ObsGpsL1SystemTest::check_valid_rinex_nav(std::string filename) -{ - bool res = false; - res = gpstk::isRinexNavFile(filename); - return res; -} - - -double ObsGpsL1SystemTest::compute_stdev(const std::vector& vec) -{ - double sum__ = std::accumulate(vec.begin(), vec.end(), 0.0); - double mean__ = sum__ / vec.size(); - double accum__ = 0.0; - std::for_each(std::begin(vec), std::end(vec), [&](const double d) { - accum__ += (d - mean__) * (d - mean__); - }); - double stdev__ = std::sqrt(accum__ / (vec.size() - 1)); - return stdev__; -} - - -bool ObsGpsL1SystemTest::check_valid_rinex_obs(std::string filename) -{ - bool res = false; - res = gpstk::isRinexObsFile(filename); - return res; -} - - -int ObsGpsL1SystemTest::configure_generator() -{ - // Configure signal generator - generator_binary = FLAGS_generator_binary; - - p1 = std::string("-rinex_nav_file=") + FLAGS_rinex_nav_file; - if (FLAGS_dynamic_position.empty()) - { - p2 = std::string("-static_position=") + FLAGS_static_position + std::string(",") + std::to_string(std::min(FLAGS_duration * 10, 3000)); - if (FLAGS_duration > 300) std::cout << "WARNING: Duration has been set to its maximum value of 300 s" << std::endl; - } - else - { - p2 = std::string("-obs_pos_file=") + std::string(FLAGS_dynamic_position); - } - p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output - p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples - p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); //Baseband sampling frequency [MSps] - return 0; -} - - -int ObsGpsL1SystemTest::generate_signal() -{ - pid_t wait_result; - int child_status; - - char* const parmList[] = {&generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], NULL}; - - int pid; - if ((pid = fork()) == -1) - perror("fork error"); - else if (pid == 0) - { - execv(&generator_binary[0], parmList); - std::cout << "Return not expected. Must be an execv error." << std::endl; - std::terminate(); - } - - wait_result = waitpid(pid, &child_status, 0); - if (wait_result == -1) perror("waitpid error"); - EXPECT_EQ(true, check_valid_rinex_obs(filename_rinex_obs)); - std::cout << "Signal and Observables RINEX files created." << std::endl; - return 0; -} - - -int ObsGpsL1SystemTest::configure_receiver() -{ - config = std::make_shared(); - - const int sampling_rate_internal = baseband_sampling_freq; - - const int number_of_taps = 11; - const int number_of_bands = 2; - const float band1_begin = 0.0; - const float band1_end = 0.48; - const float band2_begin = 0.52; - const float band2_end = 1.0; - const float ampl1_begin = 1.0; - const float ampl1_end = 1.0; - const float ampl2_begin = 0.0; - const float ampl2_end = 0.0; - const float band1_error = 1.0; - const float band2_error = 1.0; - const int grid_density = 16; - - const float zero = 0.0; - const int number_of_channels = 8; - const int in_acquisition = 1; - - const float threshold = 0.01; - const float doppler_max = 8000.0; - const float doppler_step = 500.0; - const int max_dwells = 1; - const int tong_init_val = 2; - const int tong_max_val = 10; - const int tong_max_dwells = 30; - const int coherent_integration_time_ms = 1; - - const float pll_bw_hz = 30.0; - const float dll_bw_hz = 4.0; - const float early_late_space_chips = 0.5; - const float pll_bw_narrow_hz = 20.0; - const float dll_bw_narrow_hz = 2.0; - const int extend_correlation_ms = 1; - - const int display_rate_ms = 500; - const int output_rate_ms = 10; - - config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_rate_internal)); - - // Set the assistance system parameters - config->set_property("GNSS-SDR.SUPL_read_gps_assistance_xml", "false"); - config->set_property("GNSS-SDR.SUPL_gps_enabled", "false"); - config->set_property("GNSS-SDR.SUPL_gps_ephemeris_server", "supl.google.com"); - config->set_property("GNSS-SDR.SUPL_gps_ephemeris_port", std::to_string(7275)); - config->set_property("GNSS-SDR.SUPL_gps_acquisition_server", "supl.google.com"); - config->set_property("GNSS-SDR.SUPL_gps_acquisition_port", std::to_string(7275)); - config->set_property("GNSS-SDR.SUPL_MCC", std::to_string(244)); - config->set_property("GNSS-SDR.SUPL_MNS", std::to_string(5)); - config->set_property("GNSS-SDR.SUPL_LAC", "0x59e2"); - config->set_property("GNSS-SDR.SUPL_CI", "0x31b0"); - - // Set the Signal Source - config->set_property("SignalSource.implementation", "File_Signal_Source"); - config->set_property("SignalSource.filename", "./" + filename_raw_data); - config->set_property("SignalSource.sampling_frequency", std::to_string(sampling_rate_internal)); - config->set_property("SignalSource.item_type", "ibyte"); - config->set_property("SignalSource.samples", std::to_string(zero)); - - // Set the Signal Conditioner - config->set_property("SignalConditioner.implementation", "Signal_Conditioner"); - config->set_property("DataTypeAdapter.implementation", "Ibyte_To_Complex"); - config->set_property("InputFilter.implementation", "Fir_Filter"); - config->set_property("InputFilter.dump", "false"); - config->set_property("InputFilter.input_item_type", "gr_complex"); - config->set_property("InputFilter.output_item_type", "gr_complex"); - config->set_property("InputFilter.taps_item_type", "float"); - config->set_property("InputFilter.number_of_taps", std::to_string(number_of_taps)); - config->set_property("InputFilter.number_of_bands", std::to_string(number_of_bands)); - config->set_property("InputFilter.band1_begin", std::to_string(band1_begin)); - config->set_property("InputFilter.band1_end", std::to_string(band1_end)); - config->set_property("InputFilter.band2_begin", std::to_string(band2_begin)); - config->set_property("InputFilter.band2_end", std::to_string(band2_end)); - config->set_property("InputFilter.ampl1_begin", std::to_string(ampl1_begin)); - config->set_property("InputFilter.ampl1_end", std::to_string(ampl1_end)); - config->set_property("InputFilter.ampl2_begin", std::to_string(ampl2_begin)); - config->set_property("InputFilter.ampl2_end", std::to_string(ampl2_end)); - config->set_property("InputFilter.band1_error", std::to_string(band1_error)); - config->set_property("InputFilter.band2_error", std::to_string(band2_error)); - config->set_property("InputFilter.filter_type", "bandpass"); - config->set_property("InputFilter.grid_density", std::to_string(grid_density)); - config->set_property("InputFilter.sampling_frequency", std::to_string(sampling_rate_internal)); - config->set_property("InputFilter.IF", std::to_string(zero)); - config->set_property("Resampler.implementation", "Pass_Through"); - config->set_property("Resampler.dump", "false"); - config->set_property("Resampler.item_type", "gr_complex"); - config->set_property("Resampler.sample_freq_in", std::to_string(sampling_rate_internal)); - config->set_property("Resampler.sample_freq_out", std::to_string(sampling_rate_internal)); - - // Set the number of Channels - config->set_property("Channels_1C.count", std::to_string(number_of_channels)); - config->set_property("Channels.in_acquisition", std::to_string(in_acquisition)); - config->set_property("Channel.signal", "1C"); - - // Set Acquisition - config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Tong_Acquisition"); - config->set_property("Acquisition_1C.item_type", "gr_complex"); - config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); - config->set_property("Acquisition_1C.threshold", std::to_string(threshold)); - config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); - config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); - config->set_property("Acquisition_1C.bit_transition_flag", "false"); - config->set_property("Acquisition_1C.max_dwells", std::to_string(max_dwells)); - config->set_property("Acquisition_1C.tong_init_val", std::to_string(tong_init_val)); - config->set_property("Acquisition_1C.tong_max_val", std::to_string(tong_max_val)); - config->set_property("Acquisition_1C.tong_max_dwells", std::to_string(tong_max_dwells)); - - // Set Tracking - config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking"); - //config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_C_Aid_Tracking"); - config->set_property("Tracking_1C.item_type", "gr_complex"); - config->set_property("Tracking_1C.dump", "false"); - config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); - config->set_property("Tracking_1C.pll_bw_hz", std::to_string(pll_bw_hz)); - config->set_property("Tracking_1C.dll_bw_hz", std::to_string(dll_bw_hz)); - config->set_property("Tracking_1C.early_late_space_chips", std::to_string(early_late_space_chips)); - - config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(pll_bw_narrow_hz)); - config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(dll_bw_narrow_hz)); - config->set_property("Tracking_1C.extend_correlation_ms", std::to_string(extend_correlation_ms)); - - // Set Telemetry - config->set_property("TelemetryDecoder_1C.implementation", "GPS_L1_CA_Telemetry_Decoder"); - config->set_property("TelemetryDecoder_1C.dump", "false"); - - // Set Observables - config->set_property("Observables.implementation", "Hybrid_Observables"); - config->set_property("Observables.dump", "false"); - config->set_property("Observables.dump_filename", "./observables.dat"); - config->set_property("Observables.averaging_depth", std::to_string(100)); - - // Set PVT - config->set_property("PVT.implementation", "RTKLIB_PVT"); - config->set_property("PVT.positioning_mode", "Single"); - config->set_property("PVT.output_rate_ms", std::to_string(output_rate_ms)); - config->set_property("PVT.display_rate_ms", std::to_string(display_rate_ms)); - config->set_property("PVT.dump_filename", "./PVT"); - config->set_property("PVT.nmea_dump_filename", "./gnss_sdr_pvt.nmea"); - config->set_property("PVT.flag_nmea_tty_port", "false"); - config->set_property("PVT.nmea_dump_devname", "/dev/pts/4"); - config->set_property("PVT.flag_rtcm_server", "false"); - config->set_property("PVT.flag_rtcm_tty_port", "false"); - config->set_property("PVT.rtcm_dump_devname", "/dev/pts/1"); - config->set_property("PVT.dump", "false"); - config->set_property("PVT.rinex_version", std::to_string(2)); - - return 0; -} - - -int ObsGpsL1SystemTest::run_receiver() -{ - std::shared_ptr control_thread; - control_thread = std::make_shared(config); - // start receiver - try - { - control_thread->run(); - } - catch (const boost::exception& e) - { - std::cout << "Boost exception: " << boost::diagnostic_information(e); - } - catch (const std::exception& ex) - { - std::cout << "STD exception: " << ex.what(); - } - // Get the name of the RINEX obs file generated by the receiver - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); - FILE* fp; - std::string argum2 = std::string("/bin/ls *O | grep GSDR | tail -1"); - char buffer[1035]; - fp = popen(&argum2[0], "r"); - if (fp == NULL) - { - std::cout << "Failed to run command: " << argum2 << std::endl; - return -1; - } - while (fgets(buffer, sizeof(buffer), fp) != NULL) - { - std::string aux = std::string(buffer); - ObsGpsL1SystemTest::generated_rinex_obs = aux.erase(aux.length() - 1, 1); - } - pclose(fp); - return 0; -} - - -void ObsGpsL1SystemTest::check_results() -{ - std::vector>> pseudorange_ref(33); - std::vector>> carrierphase_ref(33); - std::vector>> doppler_ref(33); - - std::vector>> pseudorange_meas(33); - std::vector>> carrierphase_meas(33); - std::vector>> doppler_meas(33); - - // Open and read reference RINEX observables file - try - { - gpstk::Rinex3ObsStream r_ref(FLAGS_filename_rinex_obs); - r_ref.exceptions(std::ios::failbit); - gpstk::Rinex3ObsData r_ref_data; - gpstk::Rinex3ObsHeader r_ref_header; - - gpstk::RinexDatum dataobj; - - r_ref >> r_ref_header; - - while (r_ref >> r_ref_data) - { - for (int myprn = 1; myprn < 33; myprn++) - { - gpstk::SatID prn(myprn, gpstk::SatID::systemGPS); - gpstk::CommonTime time = r_ref_data.time; - double sow(static_cast(time).sow); - - gpstk::Rinex3ObsData::DataMap::iterator pointer = r_ref_data.obs.find(prn); - if (pointer == r_ref_data.obs.end()) - { - // PRN not present; do nothing - } - else - { - dataobj = r_ref_data.getObs(prn, "C1C", r_ref_header); - double P1 = dataobj.data; - std::pair pseudo(sow, P1); - pseudorange_ref.at(myprn).push_back(pseudo); - - dataobj = r_ref_data.getObs(prn, "L1C", r_ref_header); - double L1 = dataobj.data; - std::pair carrier(sow, L1); - carrierphase_ref.at(myprn).push_back(carrier); - - dataobj = r_ref_data.getObs(prn, "D1C", r_ref_header); - double D1 = dataobj.data; - std::pair doppler(sow, D1); - doppler_ref.at(myprn).push_back(doppler); - } // End of 'if( pointer == roe.obs.end() )' - } // end for - } // end while - } // End of 'try' block - catch (const gpstk::FFStreamError& e) - { - std::cout << e; - exit(1); - } - catch (const gpstk::Exception& e) - { - std::cout << e; - exit(1); - } - catch (...) - { - std::cout << "unknown error. I don't feel so well..." << std::endl; - exit(1); - } - - try - { - std::string arg2_gen = std::string("./") + ObsGpsL1SystemTest::generated_rinex_obs; - gpstk::Rinex3ObsStream r_meas(arg2_gen); - r_meas.exceptions(std::ios::failbit); - gpstk::Rinex3ObsData r_meas_data; - gpstk::Rinex3ObsHeader r_meas_header; - gpstk::RinexDatum dataobj; - - r_meas >> r_meas_header; - - while (r_meas >> r_meas_data) - { - for (int myprn = 1; myprn < 33; myprn++) - { - gpstk::SatID prn(myprn, gpstk::SatID::systemGPS); - gpstk::CommonTime time = r_meas_data.time; - double sow(static_cast(time).sow); - - gpstk::Rinex3ObsData::DataMap::iterator pointer = r_meas_data.obs.find(prn); - if (pointer == r_meas_data.obs.end()) - { - // PRN not present; do nothing - } - else - { - dataobj = r_meas_data.getObs(prn, "C1C", r_meas_header); - double P1 = dataobj.data; - std::pair pseudo(sow, P1); - pseudorange_meas.at(myprn).push_back(pseudo); - - dataobj = r_meas_data.getObs(prn, "L1C", r_meas_header); - double L1 = dataobj.data; - std::pair carrier(sow, L1); - carrierphase_meas.at(myprn).push_back(carrier); - - dataobj = r_meas_data.getObs(prn, "D1C", r_meas_header); - double D1 = dataobj.data; - std::pair doppler(sow, D1); - doppler_meas.at(myprn).push_back(doppler); - } // End of 'if( pointer == roe.obs.end() )' - } // end for - } // end while - } // End of 'try' block - catch (const gpstk::FFStreamError& e) - { - std::cout << e; - exit(1); - } - catch (const gpstk::Exception& e) - { - std::cout << e; - exit(1); - } - catch (...) - { - std::cout << "unknown error. I don't feel so well..." << std::endl; - exit(1); - } - - // Time alignment - std::vector>> pseudorange_ref_aligned(33); - std::vector>> carrierphase_ref_aligned(33); - std::vector>> doppler_ref_aligned(33); - - std::vector>>::iterator iter; - std::vector>::iterator it; - std::vector>::iterator it2; - - std::vector> pr_diff(33); - std::vector> cp_diff(33); - std::vector> doppler_diff(33); - - std::vector>::iterator iter_diff; - std::vector::iterator iter_v; - - int prn_id = 0; - for (iter = pseudorange_ref.begin(); iter != pseudorange_ref.end(); iter++) - { - for (it = iter->begin(); it != iter->end(); it++) - { - // If a measure exists for this sow, store it - for (it2 = pseudorange_meas.at(prn_id).begin(); it2 != pseudorange_meas.at(prn_id).end(); it2++) - { - if (std::abs(it->first - it2->first) < 0.1) // store measures closer than 10 ms. - { - pseudorange_ref_aligned.at(prn_id).push_back(*it); - pr_diff.at(prn_id).push_back(it->second - it2->second); - //std::cout << "Sat " << prn_id << ": " << "PR_ref=" << it->second << " PR_meas=" << it2->second << " Diff:" << it->second - it2->second << std::endl; - } - } - } - prn_id++; - } - - prn_id = 0; - for (iter = carrierphase_ref.begin(); iter != carrierphase_ref.end(); iter++) - { - for (it = iter->begin(); it != iter->end(); it++) - { - // If a measure exists for this sow, store it - for (it2 = carrierphase_meas.at(prn_id).begin(); it2 != carrierphase_meas.at(prn_id).end(); it2++) - { - if (std::abs(it->first - it2->first) < 0.1) // store measures closer than 10 ms. - { - carrierphase_ref_aligned.at(prn_id).push_back(*it); - cp_diff.at(prn_id).push_back(it->second - it2->second); - // std::cout << "Sat " << prn_id << ": " << "Carrier_ref=" << it->second << " Carrier_meas=" << it2->second << " Diff:" << it->second - it2->second << std::endl; - } - } - } - prn_id++; - } - prn_id = 0; - for (iter = doppler_ref.begin(); iter != doppler_ref.end(); iter++) - { - for (it = iter->begin(); it != iter->end(); it++) - { - // If a measure exists for this sow, store it - for (it2 = doppler_meas.at(prn_id).begin(); it2 != doppler_meas.at(prn_id).end(); it2++) - { - if (std::abs(it->first - it2->first) < 0.01) // store measures closer than 10 ms. - { - doppler_ref_aligned.at(prn_id).push_back(*it); - doppler_diff.at(prn_id).push_back(it->second - it2->second); - } - } - } - prn_id++; - } - - // Compute pseudorange error - prn_id = 0; - std::vector mean_pr_diff_v; - for (iter_diff = pr_diff.begin(); iter_diff != pr_diff.end(); iter_diff++) - { - // For each satellite with reference and measurements aligned in time - int number_obs = 0; - double mean_diff = 0.0; - for (iter_v = iter_diff->begin(); iter_v != iter_diff->end(); iter_v++) - { - mean_diff = mean_diff + *iter_v; - number_obs = number_obs + 1; - } - if (number_obs > 0) - { - mean_diff = mean_diff / number_obs; - mean_pr_diff_v.push_back(mean_diff); - std::cout << "-- Mean pseudorange difference for sat " << prn_id << ": " << mean_diff; - double stdev_ = compute_stdev(*iter_diff); - std::cout << " +/- " << stdev_; - std::cout << " [m]" << std::endl; - } - else - { - mean_diff = 0.0; - } - - prn_id++; - } - double stdev_pr = compute_stdev(mean_pr_diff_v); - std::cout << "Pseudorange diff error stdev = " << stdev_pr << " [m]" << std::endl; - ASSERT_LT(stdev_pr, 10.0); - - // Compute carrier phase error - prn_id = 0; - std::vector mean_cp_diff_v; - for (iter_diff = cp_diff.begin(); iter_diff != cp_diff.end(); iter_diff++) - { - // For each satellite with reference and measurements aligned in time - int number_obs = 0; - double mean_diff = 0.0; - for (iter_v = iter_diff->begin(); iter_v != iter_diff->end(); iter_v++) - { - mean_diff = mean_diff + *iter_v; - number_obs = number_obs + 1; - } - if (number_obs > 0) - { - mean_diff = mean_diff / number_obs; - mean_cp_diff_v.push_back(mean_diff); - std::cout << "-- Mean carrier phase difference for sat " << prn_id << ": " << mean_diff; - double stdev_pr_ = compute_stdev(*iter_diff); - std::cout << " +/- " << stdev_pr_ << " whole cycles (19 cm)" << std::endl; - } - else - { - mean_diff = 0.0; - } - - prn_id++; - } - - // Compute Doppler error - prn_id = 0; - std::vector mean_doppler_v; - for (iter_diff = doppler_diff.begin(); iter_diff != doppler_diff.end(); iter_diff++) - { - // For each satellite with reference and measurements aligned in time - int number_obs = 0; - double mean_diff = 0.0; - for (iter_v = iter_diff->begin(); iter_v != iter_diff->end(); iter_v++) - { - //std::cout << *iter_v << std::endl; - mean_diff = mean_diff + *iter_v; - number_obs = number_obs + 1; - } - if (number_obs > 0) - { - mean_diff = mean_diff / number_obs; - mean_doppler_v.push_back(mean_diff); - std::cout << "-- Mean Doppler difference for sat " << prn_id << ": " << mean_diff << " [Hz]" << std::endl; - } - else - { - mean_diff = 0.0; - } - - prn_id++; - } - - double stdev_dp = compute_stdev(mean_doppler_v); - std::cout << "Doppler error stdev = " << stdev_dp << " [Hz]" << std::endl; - ASSERT_LT(stdev_dp, 10.0); -} - - -TEST_F(ObsGpsL1SystemTest, Observables_system_test) -{ - std::cout << "Validating input RINEX nav file: " << FLAGS_rinex_nav_file << " ..." << std::endl; - bool is_rinex_nav_valid = check_valid_rinex_nav(FLAGS_rinex_nav_file); - EXPECT_EQ(true, is_rinex_nav_valid) << "The RINEX navigation file " << FLAGS_rinex_nav_file << " is not well formed."; - std::cout << "The file is valid." << std::endl; - - // Configure the signal generator - configure_generator(); - - // Generate signal raw signal samples and observations RINEX file - if (!FLAGS_disable_generator) - { - generate_signal(); - } - - std::cout << "Validating generated reference RINEX obs file: " << FLAGS_filename_rinex_obs << " ..." << std::endl; - bool is_gen_rinex_obs_valid = check_valid_rinex_obs("./" + FLAGS_filename_rinex_obs); - EXPECT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << FLAGS_filename_rinex_obs << ", generated by gnss-sim, is not well formed."; - std::cout << "The file is valid." << std::endl; - - // Configure receiver - configure_receiver(); - - // Run the receiver - EXPECT_EQ(run_receiver(), 0) << "Problem executing the software-defined signal generator"; - - std::cout << "Validating RINEX obs file obtained by GNSS-SDR: " << ObsGpsL1SystemTest::generated_rinex_obs << " ..." << std::endl; - is_gen_rinex_obs_valid = check_valid_rinex_obs("./" + ObsGpsL1SystemTest::generated_rinex_obs); - EXPECT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << ObsGpsL1SystemTest::generated_rinex_obs << ", generated by GNSS-SDR, is not well formed."; - std::cout << "The file is valid." << std::endl; - - // Check results - check_results(); -} - - -int main(int argc, char** argv) -{ - std::cout << "Running Observables validation test..." << std::endl; - int res = 0; - try - { - testing::InitGoogleTest(&argc, argv); - } - catch (...) - { - } // catch the "testing::internal::::ClassUniqueToAlwaysTrue" from gtest - - google::ParseCommandLineFlags(&argc, &argv, true); - google::InitGoogleLogging(argv[0]); - - // Run the Tests - try - { - res = RUN_ALL_TESTS(); - } - catch (...) - { - LOG(WARNING) << "Unexpected catch"; - } - google::ShutDownCommandLineFlags(); - return res; -} diff --git a/src/tests/system-tests/obs_system_test.cc b/src/tests/system-tests/obs_system_test.cc deleted file mode 100644 index 391c2a969..000000000 --- a/src/tests/system-tests/obs_system_test.cc +++ /dev/null @@ -1,1030 +0,0 @@ -/*! - * \file obs_system_test.cc - * \brief This class implements a test for the validation of generated observables. - * \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es - * Antonio Ramos, 2017. antonio.ramos(at)cttc.es - * - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) - * - * GNSS-SDR is a software defined Global Navigation - * Satellite Systems receiver - * - * This file is part of GNSS-SDR. - * - * GNSS-SDR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNSS-SDR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNSS-SDR. If not, see . - * - * ------------------------------------------------------------------------- - */ - -#include "gnuplot_i.h" -#include "test_flags.h" -#include "concurrent_map.h" -#include "concurrent_queue.h" -#include "control_thread.h" -#include "file_configuration.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// For GPS NAVIGATION (L1) -concurrent_queue global_gps_acq_assist_queue; -concurrent_map global_gps_acq_assist_map; - -DEFINE_string(configuration_file, "./default_configuration.conf", "Path of configuration file"); -DEFINE_string(filename_rinex_true, "./default_rinex.txt", "Path of RINEX true observations"); -DEFINE_string(filename_rinex_obs, "default_string", "Path of RINEX true observations"); -DEFINE_double(pr_error_mean_max, 25.0, "Maximum mean error in pseudorange"); -DEFINE_double(pr_error_std_max, 15.0, "Maximum standard deviation in pseudorange"); -DEFINE_double(cp_error_mean_max, 5.0, "Maximum mean error in carrier phase"); -DEFINE_double(cp_error_std_max, 2.5, "Maximum standard deviation in carrier phase"); -DEFINE_double(dp_error_mean_max, 75.0, "Maximum mean error in Doppler frequency"); -DEFINE_double(dp_error_std_max, 25.0, "Maximum standard deviation in Doppler frequency"); -DEFINE_bool(plot_obs_sys_test, false, "Plots results of ObsSystemTest with gnuplot"); - -class ObsSystemTest : public ::testing::Test -{ -public: - int configure_receiver(); - int run_receiver(); - void check_results(); - bool check_valid_rinex_obs(std::string filename, int rinex_ver); // return true if the file is a valid Rinex observation file. - void read_rinex_files( - std::vector& pseudorange_ref, - std::vector& carrierphase_ref, - std::vector& doppler_ref, - std::vector& pseudorange_meas, - std::vector& carrierphase_meas, - std::vector& doppler_meas, - arma::mat& sow_prn_ref, - int signal_type); - void time_alignment_diff( - std::vector& ref, - std::vector& meas, - std::vector& diff); - void time_alignment_diff_cp( - std::vector& ref, - std::vector& meas, - std::vector& diff); - void time_alignment_diff_pr( - std::vector& ref, - std::vector& meas, - std::vector& diff, - arma::mat& sow_prn_ref); - void compute_pseudorange_error(std::vector& diff, - double error_th_mean, double error_th_std, - std::string signal_name); - void compute_carrierphase_error( - std::vector& diff, - double error_th_mean, double error_th_std, - std::string signal_name); - void compute_doppler_error( - std::vector& diff, - double error_th_mean, double error_th_std, - std::string signal_name); - std::string filename_rinex_obs = FLAGS_filename_rinex_true; - std::string generated_rinex_obs = FLAGS_filename_rinex_obs; - std::string configuration_file_ = FLAGS_configuration_file; - std::shared_ptr config; - bool gps_1C = false; - bool gps_L5 = false; - bool gal_1B = false; - bool gal_E5a = false; - bool internal_rinex_generation = false; - - /****************/ - const int num_prn_gps = 33; - const int num_prn_gal = 31; - - double pseudorange_error_th_mean = FLAGS_pr_error_mean_max; - double pseudorange_error_th_std = FLAGS_pr_error_std_max; - double carrierphase_error_th_mean = FLAGS_cp_error_mean_max; - double carrierphase_error_th_std = FLAGS_cp_error_std_max; - double doppler_error_th_mean = FLAGS_dp_error_mean_max; - double doppler_error_th_std = FLAGS_dp_error_std_max; -}; - - -bool ObsSystemTest::check_valid_rinex_obs(std::string filename, int rinex_ver) -{ - bool res = false; - if (rinex_ver == 2) - { - res = gpstk::isRinexObsFile(filename); - } - if (rinex_ver == 3) - { - res = gpstk::isRinex3ObsFile(filename); - } - return res; -} - - -void ObsSystemTest::read_rinex_files( - std::vector& pseudorange_ref, - std::vector& carrierphase_ref, - std::vector& doppler_ref, - std::vector& pseudorange_meas, - std::vector& carrierphase_meas, - std::vector& doppler_meas, - arma::mat& sow_prn_ref, - int signal_type) -{ - bool ref_exist = false; - bool meas_exist = false; - gpstk::SatID::SatelliteSystem sat_type = gpstk::SatID::systemUnknown; - int max_prn = 0; - std::string pr_string; - std::string cp_string; - std::string dp_string; - std::string signal_type_string; - sow_prn_ref.reset(); - - switch (signal_type) - { - case 0: //GPS L1 - - sat_type = gpstk::SatID::systemGPS; - max_prn = num_prn_gps; - pr_string = "C1C"; - cp_string = "L1C"; - dp_string = "D1C"; - signal_type_string = "GPS L1 C/A"; - break; - - case 1: //Galileo E1B - - sat_type = gpstk::SatID::systemGalileo; - max_prn = num_prn_gal; - pr_string = "C1B"; - cp_string = "L1B"; - dp_string = "D1B"; - signal_type_string = "Galileo E1B"; - break; - - case 2: //GPS L5 - - sat_type = gpstk::SatID::systemGPS; - max_prn = num_prn_gps; - pr_string = "C5X"; - cp_string = "L5X"; - dp_string = "D5X"; - signal_type_string = "GPS L5"; - break; - - case 3: //Galileo E5a - - sat_type = gpstk::SatID::systemGalileo; - max_prn = num_prn_gal; - pr_string = "C5X"; - cp_string = "L5X"; - dp_string = "D5X"; - signal_type_string = "Galileo E5a"; - break; - } - - // Open and read reference RINEX observables file - std::cout << "Read: RINEX " << signal_type_string << " True" << std::endl; - try - { - gpstk::Rinex3ObsStream r_ref(filename_rinex_obs); - r_ref.exceptions(std::ios::failbit); - gpstk::Rinex3ObsData r_ref_data; - gpstk::Rinex3ObsHeader r_ref_header; - gpstk::RinexDatum dataobj; - r_ref >> r_ref_header; - - while (r_ref >> r_ref_data) - { - for (int myprn = 1; myprn < max_prn; myprn++) - { - gpstk::SatID prn(myprn, sat_type); - gpstk::CommonTime time = r_ref_data.time; - double sow(static_cast(time).sow); - gpstk::Rinex3ObsData::DataMap::iterator pointer = r_ref_data.obs.find(prn); - if (pointer == r_ref_data.obs.end()) - { - // PRN not present; do nothing - } - else - { - dataobj = r_ref_data.getObs(prn, pr_string, r_ref_header); - double P1 = dataobj.data; - pseudorange_ref.at(myprn).insert_rows(pseudorange_ref.at(myprn).n_rows, arma::rowvec({sow, P1})); - - dataobj = r_ref_data.getObs(prn, cp_string, r_ref_header); - double L1 = dataobj.data; - carrierphase_ref.at(myprn).insert_rows(carrierphase_ref.at(myprn).n_rows, arma::rowvec({sow, L1})); - - dataobj = r_ref_data.getObs(prn, dp_string, r_ref_header); - double D1 = dataobj.data; - doppler_ref.at(myprn).insert_rows(doppler_ref.at(myprn).n_rows, arma::rowvec({sow, D1})); - - ref_exist = true; - } // End of 'if( pointer == roe.obs.end() )' - } // end for - } // end while - } // End of 'try' block - catch (const gpstk::FFStreamError& e) - { - std::cout << e; - exit(1); - } - catch (const gpstk::Exception& e) - { - std::cout << e; - exit(1); - } - catch (...) - { - std::cout << "unknown error. I don't feel so well..." << std::endl; - exit(1); - } - - // Open and read measured RINEX observables file - std::cout << "Read: RINEX " << signal_type_string << " measures" << std::endl; - try - { - std::string arg2_gen; - if (internal_rinex_generation) - { - arg2_gen = std::string("./") + generated_rinex_obs; - } - else - { - arg2_gen = generated_rinex_obs; - } - gpstk::Rinex3ObsStream r_meas(arg2_gen); - r_meas.exceptions(std::ios::failbit); - gpstk::Rinex3ObsData r_meas_data; - gpstk::Rinex3ObsHeader r_meas_header; - gpstk::RinexDatum dataobj; - r_meas >> r_meas_header; - - while (r_meas >> r_meas_data) - { - double pr_min = 0.0; - double sow_insert = 0.0; - double prn_min = 0.0; - bool set_pr_min = true; - for (int myprn = 1; myprn < max_prn; myprn++) - { - gpstk::SatID prn(myprn, sat_type); - gpstk::CommonTime time = r_meas_data.time; - double sow(static_cast(time).sow); - gpstk::Rinex3ObsData::DataMap::iterator pointer = r_meas_data.obs.find(prn); - if (pointer == r_meas_data.obs.end()) - { - // PRN not present; do nothing - } - else - { - dataobj = r_meas_data.getObs(prn, pr_string, r_meas_header); - double P1 = dataobj.data; - pseudorange_meas.at(myprn).insert_rows(pseudorange_meas.at(myprn).n_rows, arma::rowvec({sow, P1})); - if (set_pr_min || (P1 < pr_min)) - { - set_pr_min = false; - pr_min = P1; - sow_insert = sow; - prn_min = static_cast(myprn); - } - - dataobj = r_meas_data.getObs(prn, cp_string, r_meas_header); - double L1 = dataobj.data; - carrierphase_meas.at(myprn).insert_rows(carrierphase_meas.at(myprn).n_rows, arma::rowvec({sow, L1})); - - dataobj = r_meas_data.getObs(prn, dp_string, r_meas_header); - double D1 = dataobj.data; - doppler_meas.at(myprn).insert_rows(doppler_meas.at(myprn).n_rows, arma::rowvec({sow, D1})); - - meas_exist = true; - } // End of 'if( pointer == roe.obs.end() )' - } // end for - if (!set_pr_min) - { - sow_prn_ref.insert_rows(sow_prn_ref.n_rows, arma::rowvec({sow_insert, pr_min, prn_min})); - } - } // end while - } // End of 'try' block - catch (const gpstk::FFStreamError& e) - { - std::cout << e; - exit(1); - } - catch (const gpstk::Exception& e) - { - std::cout << e; - exit(1); - } - catch (...) - { - std::cout << "unknown error. I don't feel so well..." << std::endl; - exit(1); - } - EXPECT_TRUE(ref_exist) << "RINEX reference file does not contain " << signal_type_string << " information"; - EXPECT_TRUE(meas_exist) << "RINEX generated file does not contain " << signal_type_string << " information"; -} - - -void ObsSystemTest::time_alignment_diff( - std::vector& ref, - std::vector& meas, - std::vector& diff) -{ - std::vector::iterator iter_ref; - std::vector::iterator iter_meas; - std::vector::iterator iter_diff; - arma::mat mat_aux; - - iter_ref = ref.begin(); - iter_diff = diff.begin(); - for (iter_meas = meas.begin(); iter_meas != meas.end(); iter_meas++) - { - if (!iter_meas->is_empty() && !iter_ref->is_empty()) - { - arma::uvec index_ = arma::find(iter_meas->col(0) > iter_ref->at(0, 0)); - arma::uword index_min = arma::min(index_); - index_ = arma::find(iter_meas->col(0) < iter_ref->at(iter_ref->n_rows - 1, 0)); - arma::uword index_max = arma::max(index_); - mat_aux = iter_meas->rows(index_min, index_max); - arma::vec ref_aligned; - arma::interp1(iter_ref->col(0), iter_ref->col(1), mat_aux.col(0), ref_aligned); - *iter_diff = ref_aligned - mat_aux.col(1); - } - iter_ref++; - iter_diff++; - } -} - - -void ObsSystemTest::time_alignment_diff_cp( - std::vector& ref, - std::vector& meas, - std::vector& diff) -{ - std::vector::iterator iter_ref; - std::vector::iterator iter_meas; - std::vector::iterator iter_diff; - arma::mat mat_aux; - - iter_ref = ref.begin(); - iter_diff = diff.begin(); - for (iter_meas = meas.begin(); iter_meas != meas.end(); iter_meas++) - { - if (!iter_meas->is_empty() && !iter_ref->is_empty()) - { - arma::uvec index_ = arma::find(iter_meas->col(0) > iter_ref->at(0, 0)); - arma::uword index_min = arma::min(index_); - index_ = arma::find(iter_meas->col(0) < iter_ref->at(iter_ref->n_rows - 1, 0)); - arma::uword index_max = arma::max(index_); - mat_aux = iter_meas->rows(index_min, index_max); - mat_aux.col(1) -= mat_aux.col(1)(0); - arma::vec ref_aligned; - arma::interp1(iter_ref->col(0), iter_ref->col(1), mat_aux.col(0), ref_aligned); - ref_aligned -= ref_aligned(0); - *iter_diff = ref_aligned - mat_aux.col(1); - } - iter_ref++; - iter_diff++; - } -} - - -void ObsSystemTest::time_alignment_diff_pr( - std::vector& ref, - std::vector& meas, - std::vector& diff, - arma::mat& sow_prn_ref) -{ - std::vector::iterator iter_ref; - std::vector::iterator iter_meas; - std::vector::iterator iter_diff; - arma::mat mat_aux; - arma::vec subtraction_meas; - arma::vec subtraction_ref; - - arma::mat subtraction_pr_ref = sow_prn_ref; - arma::vec::iterator iter_vec0 = subtraction_pr_ref.begin_col(0); - arma::vec::iterator iter_vec1 = subtraction_pr_ref.begin_col(1); - arma::vec::iterator iter_vec2 = subtraction_pr_ref.begin_col(2); - - for (iter_vec1 = subtraction_pr_ref.begin_col(1); iter_vec1 != subtraction_pr_ref.end_col(1); iter_vec1++) - { - arma::vec aux_pr; //vector with only 1 element - arma::vec aux_sow = {*iter_vec0}; //vector with only 1 element - arma::interp1(ref.at(static_cast(*iter_vec2)).col(0), - ref.at(static_cast(*iter_vec2)).col(1), - aux_sow, - aux_pr); - *iter_vec1 = aux_pr(0); - iter_vec0++; - iter_vec2++; - } - - iter_ref = ref.begin(); - iter_diff = diff.begin(); - for (iter_meas = meas.begin(); iter_meas != meas.end(); iter_meas++) - { - if (!iter_meas->is_empty() && !iter_ref->is_empty()) - { - arma::uvec index_ = arma::find(iter_meas->col(0) > iter_ref->at(0, 0)); - arma::uword index_min = arma::min(index_); - index_ = arma::find(iter_meas->col(0) < iter_ref->at(iter_ref->n_rows - 1, 0)); - arma::uword index_max = arma::max(index_); - mat_aux = iter_meas->rows(index_min, index_max); - arma::interp1(sow_prn_ref.col(0), sow_prn_ref.col(1), mat_aux.col(0), subtraction_meas); - mat_aux.col(1) -= subtraction_meas; - arma::vec ref_aligned; - arma::interp1(iter_ref->col(0), iter_ref->col(1), mat_aux.col(0), ref_aligned); - arma::interp1(subtraction_pr_ref.col(0), subtraction_pr_ref.col(1), mat_aux.col(0), subtraction_ref); - ref_aligned -= subtraction_ref; - *iter_diff = ref_aligned - mat_aux.col(1); - } - iter_ref++; - iter_diff++; - } -} - - -int ObsSystemTest::configure_receiver() -{ - config = std::make_shared(configuration_file_); - - if (config->property("Channels_1C.count", 0) > 0) - { - gps_1C = true; - } - if (config->property("Channels_1B.count", 0) > 0) - { - gal_1B = true; - } - if (config->property("Channels_5X.count", 0) > 0) - { - gal_E5a = true; - } - if (config->property("Channels_7X.count", 0) > 0) //NOT DEFINITIVE!!!!! - { - gps_L5 = true; - } - - return 0; -} - - -int ObsSystemTest::run_receiver() -{ - std::shared_ptr control_thread; - control_thread = std::make_shared(config); - // start receiver - try - { - control_thread->run(); - } - catch (const boost::exception& e) - { - std::cout << "Boost exception: " << boost::diagnostic_information(e); - } - catch (const std::exception& ex) - { - std::cout << "STD exception: " << ex.what(); - } - // Get the name of the RINEX obs file generated by the receiver - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); - FILE* fp; - std::string argum2 = std::string("/bin/ls *O | grep GSDR | tail -1"); - char buffer[1035]; - fp = popen(&argum2[0], "r"); - if (fp == NULL) - { - std::cout << "Failed to run command: " << argum2 << std::endl; - return -1; - } - while (fgets(buffer, sizeof(buffer), fp) != NULL) - { - std::string aux = std::string(buffer); - generated_rinex_obs = aux.erase(aux.length() - 1, 1); - internal_rinex_generation = true; - } - pclose(fp); - return 0; -} - - -void ObsSystemTest::compute_pseudorange_error( - std::vector& diff, - double error_th_mean, double error_th_std, - std::string signal_name) -{ - int prn_id = 0; - std::vector::iterator iter_diff; - std::vector means; - std::vector stddevs; - std::vector prns; - for (iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++) - { - if (!iter_diff->is_empty()) - { - while (iter_diff->has_nan()) - { - bool nan_found = false; - int k_aux = 0; - while (!nan_found) - { - if (!iter_diff->row(k_aux).is_finite()) - { - nan_found = true; - iter_diff->shed_row(k_aux); - } - k_aux++; - } - } - double d_mean = std::sqrt(arma::mean(arma::square(*iter_diff))); - means.push_back(d_mean); - double d_stddev = arma::stddev(*iter_diff); - stddevs.push_back(d_stddev); - prns.push_back(static_cast(prn_id)); - std::cout << "-- RMS pseudorange difference for sat " << prn_id << ": " << d_mean; - std::cout << ". Std. dev.: " << d_stddev; - std::cout << " [m]" << std::endl; - EXPECT_LT(d_mean, error_th_mean); - EXPECT_LT(d_stddev, error_th_std); - } - prn_id++; - } - if (FLAGS_plot_obs_sys_test == true) - { - const std::string gnuplot_executable(FLAGS_gnuplot_executable); - if (gnuplot_executable.empty()) - { - std::cout << "WARNING: Although the flag plot_obs_sys_test has been set to TRUE," << std::endl; - std::cout << "gnuplot has not been found in your system." << std::endl; - std::cout << "Test results will not be plotted." << std::endl; - } - else - { - try - { - boost::filesystem::path p(gnuplot_executable); - boost::filesystem::path dir = p.parent_path(); - std::string gnuplot_path = dir.native(); - Gnuplot::set_GNUPlotPath(gnuplot_path); - - Gnuplot g1("linespoints"); - g1.set_title(signal_name + " Pseudorange error"); - g1.set_grid(); - g1.set_xlabel("PRN"); - g1.set_ylabel("Pseudorange error [m]"); - g1.plot_xy(prns, means, "RMS error"); - g1.plot_xy(prns, stddevs, "Standard deviation"); - size_t char_pos = signal_name.find(" "); - while (char_pos != std::string::npos) - { - signal_name.replace(char_pos, 1, "_"); - char_pos = signal_name.find(" "); - } - char_pos = signal_name.find("/"); - while (char_pos != std::string::npos) - { - signal_name.replace(char_pos, 1, "_"); - char_pos = signal_name.find("/"); - } - g1.savetops("Pseudorange_error_" + signal_name); - g1.savetopdf("Pseudorange_error_" + signal_name, 18); - if (FLAGS_show_plots) g1.showonscreen(); // window output - } - catch (const GnuplotException& ge) - { - std::cout << ge.what() << std::endl; - } - } - } -} - - -void ObsSystemTest::compute_carrierphase_error( - std::vector& diff, - double error_th_mean, double error_th_std, - std::string signal_name) -{ - int prn_id = 0; - std::vector means; - std::vector stddevs; - std::vector prns; - std::vector::iterator iter_diff; - for (iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++) - { - if (!iter_diff->is_empty()) - { - while (iter_diff->has_nan()) - { - bool nan_found = false; - int k_aux = 0; - while (!nan_found) - { - if (!iter_diff->row(k_aux).is_finite()) - { - nan_found = true; - iter_diff->shed_row(k_aux); - } - k_aux++; - } - } - double d_mean = std::sqrt(arma::mean(arma::square(*iter_diff))); - means.push_back(d_mean); - double d_stddev = arma::stddev(*iter_diff); - stddevs.push_back(d_stddev); - prns.push_back(static_cast(prn_id)); - std::cout << "-- RMS carrier phase difference for sat " << prn_id << ": " << d_mean; - std::cout << ". Std. dev.: " << d_stddev; - std::cout << " whole cycles" << std::endl; - EXPECT_LT(d_mean, error_th_mean); - EXPECT_LT(d_stddev, error_th_std); - } - prn_id++; - } - if (FLAGS_plot_obs_sys_test == true) - { - const std::string gnuplot_executable(FLAGS_gnuplot_executable); - if (gnuplot_executable.empty()) - { - std::cout << "WARNING: Although the flag plot_obs_sys_test has been set to TRUE," << std::endl; - std::cout << "gnuplot has not been found in your system." << std::endl; - std::cout << "Test results will not be plotted." << std::endl; - } - else - { - try - { - boost::filesystem::path p(gnuplot_executable); - boost::filesystem::path dir = p.parent_path(); - std::string gnuplot_path = dir.native(); - Gnuplot::set_GNUPlotPath(gnuplot_path); - - Gnuplot g1("linespoints"); - g1.set_title(signal_name + " Carrier phase error"); - g1.set_grid(); - g1.set_xlabel("PRN"); - g1.set_ylabel("Carrier phase error [whole cycles]"); - g1.plot_xy(prns, means, "RMS error"); - g1.plot_xy(prns, stddevs, "Standard deviation"); - size_t char_pos = signal_name.find(" "); - while (char_pos != std::string::npos) - { - signal_name.replace(char_pos, 1, "_"); - char_pos = signal_name.find(" "); - } - char_pos = signal_name.find("/"); - while (char_pos != std::string::npos) - { - signal_name.replace(char_pos, 1, "_"); - char_pos = signal_name.find("/"); - } - g1.savetops("Carrier_phase_error_" + signal_name); - g1.savetopdf("Carrier_phase_error_" + signal_name, 18); - if (FLAGS_show_plots) g1.showonscreen(); // window output - } - catch (const GnuplotException& ge) - { - std::cout << ge.what() << std::endl; - } - } - } -} - - -void ObsSystemTest::compute_doppler_error( - std::vector& diff, - double error_th_mean, double error_th_std, - std::string signal_name) -{ - int prn_id = 0; - std::vector means; - std::vector stddevs; - std::vector prns; - std::vector::iterator iter_diff; - for (iter_diff = diff.begin(); iter_diff != diff.end(); iter_diff++) - { - if (!iter_diff->is_empty()) - { - while (iter_diff->has_nan()) - { - bool nan_found = false; - int k_aux = 0; - while (!nan_found) - { - if (!iter_diff->row(k_aux).is_finite()) - { - nan_found = true; - iter_diff->shed_row(k_aux); - } - k_aux++; - } - } - double d_mean = std::sqrt(arma::mean(arma::square(*iter_diff))); - means.push_back(d_mean); - double d_stddev = arma::stddev(*iter_diff); - stddevs.push_back(d_stddev); - prns.push_back(static_cast(prn_id)); - std::cout << "-- RMS Doppler difference for sat " << prn_id << ": " << d_mean; - std::cout << ". Std. dev.: " << d_stddev; - std::cout << " [Hz]" << std::endl; - EXPECT_LT(d_mean, error_th_mean); - EXPECT_LT(d_stddev, error_th_std); - } - prn_id++; - } - if (FLAGS_plot_obs_sys_test == true) - { - const std::string gnuplot_executable(FLAGS_gnuplot_executable); - if (gnuplot_executable.empty()) - { - std::cout << "WARNING: Although the flag plot_obs_sys_test has been set to TRUE," << std::endl; - std::cout << "gnuplot has not been found in your system." << std::endl; - std::cout << "Test results will not be plotted." << std::endl; - } - else - { - try - { - boost::filesystem::path p(gnuplot_executable); - boost::filesystem::path dir = p.parent_path(); - std::string gnuplot_path = dir.native(); - Gnuplot::set_GNUPlotPath(gnuplot_path); - - Gnuplot g1("linespoints"); - g1.set_title(signal_name + " Doppler error"); - g1.set_grid(); - g1.set_xlabel("PRN"); - g1.set_ylabel("Doppler error [Hz]"); - g1.plot_xy(prns, means, "RMS error"); - g1.plot_xy(prns, stddevs, "Standard deviation"); - size_t char_pos = signal_name.find(" "); - while (char_pos != std::string::npos) - { - signal_name.replace(char_pos, 1, "_"); - char_pos = signal_name.find(" "); - } - char_pos = signal_name.find("/"); - while (char_pos != std::string::npos) - { - signal_name.replace(char_pos, 1, "_"); - char_pos = signal_name.find("/"); - } - g1.savetops("Doppler_error_" + signal_name); - g1.savetopdf("Doppler_error_" + signal_name, 18); - if (FLAGS_show_plots) g1.showonscreen(); // window output - } - catch (const GnuplotException& ge) - { - std::cout << ge.what() << std::endl; - } - } - } -} - - -void ObsSystemTest::check_results() -{ - arma::mat sow_prn_ref; - if (gps_1C) - { - std::vector pseudorange_ref(num_prn_gps); - std::vector carrierphase_ref(num_prn_gps); - std::vector doppler_ref(num_prn_gps); - - std::vector pseudorange_meas(num_prn_gps); - std::vector carrierphase_meas(num_prn_gps); - std::vector doppler_meas(num_prn_gps); - - read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 0); - - // Time alignment and difference computation - - std::vector pr_diff(num_prn_gps); - std::vector cp_diff(num_prn_gps); - std::vector dp_diff(num_prn_gps); - time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref); - time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff); - time_alignment_diff(doppler_ref, doppler_meas, dp_diff); - - // Results - std::cout << std::endl; - std::cout << std::endl; - std::cout << "GPS L1 C/A obs. results" << std::endl; - - // Compute pseudorange error - - compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "GPS L1 C/A"); - - // Compute carrier phase error - - compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "GPS L1 C/A"); - - // Compute Doppler error - - compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "GPS L1 C/A"); - } - if (gps_L5) - { - std::vector pseudorange_ref(num_prn_gps); - std::vector carrierphase_ref(num_prn_gps); - std::vector doppler_ref(num_prn_gps); - - std::vector pseudorange_meas(num_prn_gps); - std::vector carrierphase_meas(num_prn_gps); - std::vector doppler_meas(num_prn_gps); - - read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 2); - - // Time alignment and difference computation - - std::vector pr_diff(num_prn_gps); - std::vector cp_diff(num_prn_gps); - std::vector dp_diff(num_prn_gps); - time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref); - time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff); - time_alignment_diff(doppler_ref, doppler_meas, dp_diff); - - // Results - std::cout << std::endl; - std::cout << std::endl; - std::cout << "GPS L5 obs. results" << std::endl; - - // Compute pseudorange error - - compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "GPS L5"); - - // Compute carrier phase error - - compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "GPS L5"); - - // Compute Doppler error - - compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "GPS L5"); - } - if (gal_1B) - { - std::vector pseudorange_ref(num_prn_gal); - std::vector carrierphase_ref(num_prn_gal); - std::vector doppler_ref(num_prn_gal); - - std::vector pseudorange_meas(num_prn_gal); - std::vector carrierphase_meas(num_prn_gal); - std::vector doppler_meas(num_prn_gal); - - read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 1); - - // Time alignment and difference computation - - std::vector pr_diff(num_prn_gal); - std::vector cp_diff(num_prn_gal); - std::vector dp_diff(num_prn_gal); - time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref); - time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff); - time_alignment_diff(doppler_ref, doppler_meas, dp_diff); - - // Results - std::cout << std::endl; - std::cout << std::endl; - std::cout << "Galileo E1B obs. results" << std::endl; - - // Compute pseudorange error - - compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "Galileo E1B"); - - // Compute carrier phase error - - compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "Galileo E1B"); - - // Compute Doppler error - - compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "Galileo E1B"); - } - if (gal_E5a) - { - std::vector pseudorange_ref(num_prn_gal); - std::vector carrierphase_ref(num_prn_gal); - std::vector doppler_ref(num_prn_gal); - - std::vector pseudorange_meas(num_prn_gal); - std::vector carrierphase_meas(num_prn_gal); - std::vector doppler_meas(num_prn_gal); - - read_rinex_files(pseudorange_ref, carrierphase_ref, doppler_ref, pseudorange_meas, carrierphase_meas, doppler_meas, sow_prn_ref, 3); - - // Time alignment and difference computation - - std::vector pr_diff(num_prn_gal); - std::vector cp_diff(num_prn_gal); - std::vector dp_diff(num_prn_gal); - time_alignment_diff_pr(pseudorange_ref, pseudorange_meas, pr_diff, sow_prn_ref); - time_alignment_diff_cp(carrierphase_ref, carrierphase_meas, cp_diff); - time_alignment_diff(doppler_ref, doppler_meas, dp_diff); - - // Results - std::cout << std::endl; - std::cout << std::endl; - std::cout << "Galileo E5a obs. results" << std::endl; - - // Compute pseudorange error - - compute_pseudorange_error(pr_diff, pseudorange_error_th_mean, pseudorange_error_th_std, "Galileo E5a"); - - // Compute carrier phase error - - compute_carrierphase_error(cp_diff, carrierphase_error_th_mean, carrierphase_error_th_std, "Galileo E5a"); - - // Compute Doppler error - - compute_doppler_error(dp_diff, doppler_error_th_mean, doppler_error_th_std, "Galileo E5a"); - } -} - - -TEST_F(ObsSystemTest, Observables_system_test) -{ - std::cout << "Validating input RINEX obs (TRUE) file: " << filename_rinex_obs << " ..." << std::endl; - bool is_rinex_obs_valid = check_valid_rinex_obs(filename_rinex_obs, 3); - ASSERT_EQ(true, is_rinex_obs_valid) << "The RINEX observation file " << filename_rinex_obs << " is not well formed. Only RINEX v. 3.00 files are allowed"; - std::cout << "The file is valid." << std::endl; - // Configure receiver - configure_receiver(); - if (generated_rinex_obs.compare("default_string") == 0) - { - // Run the receiver - ASSERT_EQ(run_receiver(), 0) << "Problem executing the software-defined signal generator"; - } - std::cout << "Validating RINEX obs file obtained by GNSS-SDR: " << generated_rinex_obs << " ..." << std::endl; - bool is_gen_rinex_obs_valid = false; - if (internal_rinex_generation) - { - is_gen_rinex_obs_valid = check_valid_rinex_obs("./" + generated_rinex_obs, config->property("PVT.rinex_version", 3)); - } - else - { - is_gen_rinex_obs_valid = check_valid_rinex_obs(generated_rinex_obs, config->property("PVT.rinex_version", 3)); - } - ASSERT_EQ(true, is_gen_rinex_obs_valid) << "The RINEX observation file " << generated_rinex_obs << ", generated by GNSS-SDR, is not well formed."; - std::cout << "The file is valid." << std::endl; - // Check results - check_results(); -} - - -int main(int argc, char** argv) -{ - std::cout << "Running GNSS-SDR in Space Observables validation test..." << std::endl; - int res = 0; - try - { - testing::InitGoogleTest(&argc, argv); - } - catch (...) - { - } // catch the "testing::internal::::ClassUniqueToAlwaysTrue" from gtest - - google::ParseCommandLineFlags(&argc, &argv, true); - google::InitGoogleLogging(argv[0]); - - // Run the Tests - try - { - res = RUN_ALL_TESTS(); - } - catch (...) - { - LOG(WARNING) << "Unexpected catch"; - } - google::ShutDownCommandLineFlags(); - return res; -} diff --git a/src/tests/system-tests/position_test.cc b/src/tests/system-tests/position_test.cc index 00e64ccad..f030130e1 100644 --- a/src/tests/system-tests/position_test.cc +++ b/src/tests/system-tests/position_test.cc @@ -1,7 +1,10 @@ /*! * \file position_test.cc * \brief This class implements a test for the validation of computed position. - * \author Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es + * \authors
              + *
            • Carles Fernandez-Prades, 2016. cfernandez(at)cttc.es + *
            • Javier Arribas, 2018. jarribas(at)cttc.es + *
            * * * ------------------------------------------------------------------------- @@ -29,6 +32,10 @@ * ------------------------------------------------------------------------- */ +#include "geofunctions.h" +#include "position_test_flags.h" +#include "rtklib_solver_dump_reader.h" +#include "spirent_motion_csv_dump_reader.h" #include "concurrent_map.h" #include "concurrent_queue.h" #include "control_thread.h" @@ -39,6 +46,7 @@ #include "test_flags.h" #include "signal_generator_flags.h" #include +#include #include #include #include @@ -47,16 +55,14 @@ #include #include #include - - -DEFINE_string(config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); -DEFINE_bool(plot_position_test, false, "Plots results of FFTLengthTest with gnuplot"); +#include +#include // For GPS NAVIGATION (L1) concurrent_queue global_gps_acq_assist_queue; concurrent_map global_gps_acq_assist_map; -class StaticPositionSystemTest : public ::testing::Test +class PositionSystemTest : public ::testing::Test { public: int configure_generator(); @@ -64,6 +70,9 @@ public: int configure_receiver(); int run_receiver(); void check_results(); + bool save_mat_xy(std::vector& x, std::vector& y, std::string filename); + bool save_mat_x(std::vector& x, std::string filename); + std::string config_filename_no_extension; private: std::string generator_binary; @@ -78,119 +87,14 @@ private: std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; - void print_results(const std::vector& east, - const std::vector& north, - const std::vector& up); - - double compute_stdev_precision(const std::vector& vec); - double compute_stdev_accuracy(const std::vector& vec, double ref); - - void geodetic2Enu(const double latitude, const double longitude, const double altitude, - double* east, double* north, double* up); - - void geodetic2Ecef(const double latitude, const double longitude, const double altitude, - double* x, double* y, double* z); - + void print_results(arma::mat R_eb_enu); std::shared_ptr config; std::shared_ptr config_f; std::string generated_kml_file; }; -void StaticPositionSystemTest::geodetic2Ecef(const double latitude, const double longitude, const double altitude, - double* x, double* y, double* z) -{ - const double a = 6378137.0; // WGS84 - const double b = 6356752.314245; // WGS84 - - double aux_x, aux_y, aux_z; - - // Convert to ECEF (See https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_geodetic_to_ECEF_coordinates ) - const double cLat = cos(latitude); - const double cLon = cos(longitude); - const double sLon = sin(longitude); - const double sLat = sin(latitude); - double N = std::pow(a, 2.0) / sqrt(std::pow(a, 2.0) * std::pow(cLat, 2.0) + std::pow(b, 2.0) * std::pow(sLat, 2.0)); - - aux_x = (N + altitude) * cLat * cLon; - aux_y = (N + altitude) * cLat * sLon; - aux_z = ((std::pow(b, 2.0) / std::pow(a, 2.0)) * N + altitude) * sLat; - - *x = aux_x; - *y = aux_y; - *z = aux_z; -} - - -void StaticPositionSystemTest::geodetic2Enu(double latitude, double longitude, double altitude, - double* east, double* north, double* up) -{ - double x, y, z; - const double d2r = PI / 180.0; - - geodetic2Ecef(latitude * d2r, longitude * d2r, altitude, &x, &y, &z); - - double aux_north, aux_east, aux_down; - - std::istringstream iss2(FLAGS_static_position); - std::string str_aux; - std::getline(iss2, str_aux, ','); - double ref_long = std::stod(str_aux); - std::getline(iss2, str_aux, ','); - double ref_lat = std::stod(str_aux); - std::getline(iss2, str_aux, '\n'); - double ref_h = std::stod(str_aux); - double ref_x, ref_y, ref_z; - - geodetic2Ecef(ref_lat * d2r, ref_long * d2r, ref_h, &ref_x, &ref_y, &ref_z); - - double aux_x = x - ref_x; - double aux_y = y - ref_y; - double aux_z = z - ref_z; - - // ECEF to NED matrix - double phiP = atan2(ref_z, sqrt(std::pow(ref_x, 2.0) + std::pow(ref_y, 2.0))); - const double sLat = sin(phiP); - const double sLon = sin(ref_long * d2r); - const double cLat = cos(phiP); - const double cLon = cos(ref_long * d2r); - - aux_north = -aux_x * sLat * cLon - aux_y * sLon + aux_z * cLat * cLon; - aux_east = -aux_x * sLat * sLon + aux_y * cLon + aux_z * cLat * sLon; - aux_down = aux_x * cLat + aux_z * sLat; - - *east = aux_east; - *north = aux_north; - *up = -aux_down; -} - - -double StaticPositionSystemTest::compute_stdev_precision(const std::vector& vec) -{ - double sum__ = std::accumulate(vec.begin(), vec.end(), 0.0); - double mean__ = sum__ / vec.size(); - double accum__ = 0.0; - std::for_each(std::begin(vec), std::end(vec), [&](const double d) { - accum__ += (d - mean__) * (d - mean__); - }); - double stdev__ = std::sqrt(accum__ / (vec.size() - 1)); - return stdev__; -} - - -double StaticPositionSystemTest::compute_stdev_accuracy(const std::vector& vec, const double ref) -{ - const double mean__ = ref; - double accum__ = 0.0; - std::for_each(std::begin(vec), std::end(vec), [&](const double d) { - accum__ += (d - mean__) * (d - mean__); - }); - double stdev__ = std::sqrt(accum__ / (vec.size() - 1)); - return stdev__; -} - - -int StaticPositionSystemTest::configure_generator() +int PositionSystemTest::configure_generator() { // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -212,7 +116,7 @@ int StaticPositionSystemTest::configure_generator() } -int StaticPositionSystemTest::generate_signal() +int PositionSystemTest::generate_signal() { pid_t wait_result; int child_status; @@ -235,7 +139,7 @@ int StaticPositionSystemTest::generate_signal() } -int StaticPositionSystemTest::configure_receiver() +int PositionSystemTest::configure_receiver() { if (FLAGS_config_file_ptest.empty()) { @@ -257,23 +161,23 @@ int StaticPositionSystemTest::configure_receiver() const int grid_density = 16; const float zero = 0.0; - const int number_of_channels = 8; + const int number_of_channels = 11; const int in_acquisition = 1; - const float threshold = 0.01; - const float doppler_max = 8000.0; - const float doppler_step = 500.0; - const int max_dwells = 1; + const float threshold = 2.5; + const float doppler_max = 5000.0; + const float doppler_step = 250.0; + const int max_dwells = 10; const int tong_init_val = 2; const int tong_max_val = 10; const int tong_max_dwells = 30; const int coherent_integration_time_ms = 1; - const float pll_bw_hz = 30.0; - const float dll_bw_hz = 4.0; + const float pll_bw_hz = 35.0; + const float dll_bw_hz = 1.5; const float early_late_space_chips = 0.5; - const float pll_bw_narrow_hz = 20.0; - const float dll_bw_narrow_hz = 2.0; + const float pll_bw_narrow_hz = 1.0; + const float dll_bw_narrow_hz = 0.1; const int extend_correlation_ms = 1; const int display_rate_ms = 500; @@ -289,7 +193,7 @@ int StaticPositionSystemTest::configure_receiver() config->set_property("GNSS-SDR.SUPL_gps_acquisition_server", "supl.google.com"); config->set_property("GNSS-SDR.SUPL_gps_acquisition_port", std::to_string(7275)); config->set_property("GNSS-SDR.SUPL_MCC", std::to_string(244)); - config->set_property("GNSS-SDR.SUPL_MNS", std::to_string(5)); + config->set_property("GNSS-SDR.SUPL_MNC", std::to_string(5)); config->set_property("GNSS-SDR.SUPL_LAC", "0x59e2"); config->set_property("GNSS-SDR.SUPL_CI", "0x31b0"); @@ -303,7 +207,7 @@ int StaticPositionSystemTest::configure_receiver() // Set the Signal Conditioner config->set_property("SignalConditioner.implementation", "Signal_Conditioner"); config->set_property("DataTypeAdapter.implementation", "Ibyte_To_Complex"); - config->set_property("InputFilter.implementation", "Fir_Filter"); + config->set_property("InputFilter.implementation", "Freq_Xlating_Fir_Filter"); config->set_property("InputFilter.dump", "false"); config->set_property("InputFilter.input_item_type", "gr_complex"); config->set_property("InputFilter.output_item_type", "gr_complex"); @@ -320,7 +224,7 @@ int StaticPositionSystemTest::configure_receiver() config->set_property("InputFilter.ampl2_end", std::to_string(ampl2_end)); config->set_property("InputFilter.band1_error", std::to_string(band1_error)); config->set_property("InputFilter.band2_error", std::to_string(band2_error)); - config->set_property("InputFilter.filter_type", "bandpass"); + config->set_property("InputFilter.filter_type", "lowpass"); config->set_property("InputFilter.grid_density", std::to_string(grid_density)); config->set_property("InputFilter.sampling_frequency", std::to_string(sampling_rate_internal)); config->set_property("InputFilter.IF", std::to_string(zero)); @@ -350,10 +254,10 @@ int StaticPositionSystemTest::configure_receiver() config->set_property("Acquisition_1C.dump", "false"); config->set_property("Acquisition_1C.dump_filename", "./acquisition"); config->set_property("Acquisition_1C.dump_channel", "1"); + config->set_property("Acquisition_1C.blocking", "true"); // Set Tracking config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_Tracking"); - //config->set_property("Tracking_1C.implementation", "GPS_L1_CA_DLL_PLL_C_Aid_Tracking"); config->set_property("Tracking_1C.item_type", "gr_complex"); config->set_property("Tracking_1C.dump", "false"); config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); @@ -364,6 +268,8 @@ int StaticPositionSystemTest::configure_receiver() config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(pll_bw_narrow_hz)); config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(dll_bw_narrow_hz)); config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_ms)); + //config->set_property("Tracking_1C.high_dyn", "true"); + //config->set_property("Tracking_1C.smoother_length", "200"); // Set Telemetry config->set_property("TelemetryDecoder_1C.implementation", "GPS_L1_CA_Telemetry_Decoder"); @@ -386,11 +292,12 @@ int StaticPositionSystemTest::configure_receiver() config->set_property("PVT.flag_rtcm_server", "false"); config->set_property("PVT.flag_rtcm_tty_port", "false"); config->set_property("PVT.rtcm_dump_devname", "/dev/pts/1"); - config->set_property("PVT.dump", "false"); + config->set_property("PVT.dump", "true"); config->set_property("PVT.rinex_version", std::to_string(2)); config->set_property("PVT.iono_model", "OFF"); config->set_property("PVT.trop_model", "OFF"); config->set_property("PVT.AR_GPS", "PPP-AR"); + config->set_property("PVT.elevation_mask", std::to_string(15)); config_f = 0; } @@ -403,7 +310,7 @@ int StaticPositionSystemTest::configure_receiver() } -int StaticPositionSystemTest::run_receiver() +int PositionSystemTest::run_receiver() { std::shared_ptr control_thread; if (FLAGS_config_file_ptest.empty()) @@ -444,140 +351,438 @@ int StaticPositionSystemTest::run_receiver() { std::string aux = std::string(buffer); EXPECT_EQ(aux.empty(), false); - StaticPositionSystemTest::generated_kml_file = aux.erase(aux.length() - 1, 1); + PositionSystemTest::generated_kml_file = aux.erase(aux.length() - 1, 1); } pclose(fp); - EXPECT_EQ(StaticPositionSystemTest::generated_kml_file.empty(), false); + EXPECT_EQ(PositionSystemTest::generated_kml_file.empty(), false); return 0; } -void StaticPositionSystemTest::check_results() +bool PositionSystemTest::save_mat_xy(std::vector& x, std::vector& y, std::string filename) { - std::fstream myfile(StaticPositionSystemTest::generated_kml_file, std::ios_base::in); - ASSERT_TRUE(myfile.is_open()) << "No valid kml file could be opened"; - std::string line; - - std::vector pos_e; - std::vector pos_n; - std::vector pos_u; - - // Skip header - std::getline(myfile, line); - bool is_header = true; - while (is_header) + try { - std::getline(myfile, line); - ASSERT_FALSE(myfile.eof()) << "No valid kml file found."; - std::size_t found = line.find(""); - if (found != std::string::npos) is_header = false; - } - bool is_data = true; - - //read data - while (is_data) - { - if (!std::getline(myfile, line)) + // WRITE MAT FILE + mat_t* matfp; + matvar_t* matvar; + filename.append(".mat"); + std::cout << "save_mat_xy write " << filename << std::endl; + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT5); + if (reinterpret_cast(matfp) != NULL) { - is_data = false; - break; + size_t dims[2] = {1, x.size()}; + matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &y[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); } - std::size_t found = line.find(""); - if (found != std::string::npos) - is_data = false; else { - std::string str2; - std::istringstream iss(line); - double value; - double lat = 0.0; - double longitude = 0.0; - double h = 0.0; - for (int i = 0; i < 3; i++) - { - std::getline(iss, str2, ','); - value = std::stod(str2); - if (i == 0) lat = value; - if (i == 1) longitude = value; - if (i == 2) h = value; - } - - double north, east, up; - geodetic2Enu(lat, longitude, h, &east, &north, &up); - //std::cout << "E = " << east << ", N = " << north << " U = " << up << std::endl; - pos_e.push_back(east); - pos_n.push_back(north); - pos_u.push_back(up); + std::cout << "save_mat_xy: error creating file" << std::endl; } + Mat_Close(matfp); + return true; } - myfile.close(); - ASSERT_FALSE(pos_e.size() == 0) << "KML file is empty"; - - double sigma_E_2_precision = std::pow(compute_stdev_precision(pos_e), 2.0); - double sigma_N_2_precision = std::pow(compute_stdev_precision(pos_n), 2.0); - double sigma_U_2_precision = std::pow(compute_stdev_precision(pos_u), 2.0); - - double sigma_E_2_accuracy = std::pow(compute_stdev_accuracy(pos_e, 0.0), 2.0); - double sigma_N_2_accuracy = std::pow(compute_stdev_accuracy(pos_n, 0.0), 2.0); - double sigma_U_2_accuracy = std::pow(compute_stdev_accuracy(pos_u, 0.0), 2.0); - - double sum__e = std::accumulate(pos_e.begin(), pos_e.end(), 0.0); - double mean__e = sum__e / pos_e.size(); - double sum__n = std::accumulate(pos_n.begin(), pos_n.end(), 0.0); - double mean__n = sum__n / pos_n.size(); - double sum__u = std::accumulate(pos_u.begin(), pos_u.end(), 0.0); - double mean__u = sum__u / pos_u.size(); - - std::stringstream stm; - std::ofstream position_test_file; - - if (FLAGS_config_file_ptest.empty()) + catch (const std::exception& ex) { - stm << "---- ACCURACY ----" << std::endl; + std::cout << "save_mat_xy: " << ex.what() << std::endl; + return false; + } +} + +bool PositionSystemTest::save_mat_x(std::vector& x, std::string filename) +{ + try + { + // WRITE MAT FILE + mat_t* matfp; + matvar_t* matvar; + filename.append(".mat"); + std::cout << "save_mat_x write " << filename << std::endl; + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT5); + if (reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, x.size()}; + matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + else + { + std::cout << "save_mat_x: error creating file" << std::endl; + } + Mat_Close(matfp); + return true; + } + catch (const std::exception& ex) + { + std::cout << "save_mat_x: " << ex.what() << std::endl; + return false; + } +} + +void PositionSystemTest::check_results() +{ + arma::mat R_eb_e; //ECEF position (x,y,z) estimation in the Earth frame (Nx3) + arma::mat R_eb_enu; //ENU position (N,E,U) estimation in UTM (Nx3) + arma::mat V_eb_e; //ECEF velocity (x,y,z) estimation in the Earth frame (Nx3) + arma::mat LLH; //Geodetic coordinates (latitude, longitude, height) estimation in WGS84 datum + arma::vec receiver_time_s; + + arma::mat ref_R_eb_e; //ECEF position (x,y,z) reference in the Earth frame (Nx3) + arma::mat ref_V_eb_e; //ECEF velocity (x,y,z) reference in the Earth frame (Nx3) + arma::mat ref_LLH; //Geodetic coordinates (latitude, longitude, height) reference in WGS84 datum + arma::vec ref_time_s; + + std::istringstream iss2(FLAGS_static_position); + std::string str_aux; + std::getline(iss2, str_aux, ','); + double ref_lat = std::stod(str_aux); + std::getline(iss2, str_aux, ','); + double ref_long = std::stod(str_aux); + std::getline(iss2, str_aux, '\n'); + double ref_h = std::stod(str_aux); + int utm_zone = findUtmZone(ref_lat, ref_long); + + arma::vec v_eb_n = {0.0, 0.0, 0.0}; + arma::vec true_r_eb_e = {0.0, 0.0, 0.0}; + arma::vec true_v_eb_e = {0.0, 0.0, 0.0}; + pv_Geo_to_ECEF(degtorad(ref_lat), degtorad(ref_long), ref_h, v_eb_n, true_r_eb_e, true_v_eb_e); + ref_R_eb_e.insert_cols(0, true_r_eb_e); + arma::vec ref_r_enu = {0, 0, 0}; + cart2utm(true_r_eb_e, utm_zone, ref_r_enu); + + rtklib_solver_dump_reader pvt_reader; + pvt_reader.open_obs_file(FLAGS_pvt_solver_dump_filename); + int64_t n_epochs = pvt_reader.num_epochs(); + R_eb_e = arma::zeros(3, n_epochs); + V_eb_e = arma::zeros(3, n_epochs); + LLH = arma::zeros(3, n_epochs); + receiver_time_s = arma::zeros(n_epochs, 1); + int64_t current_epoch = 0; + while (pvt_reader.read_binary_obs()) + { + receiver_time_s(current_epoch) = pvt_reader.RX_time - pvt_reader.clk_offset_s; + R_eb_e(0, current_epoch) = pvt_reader.rr[0]; + R_eb_e(1, current_epoch) = pvt_reader.rr[1]; + R_eb_e(2, current_epoch) = pvt_reader.rr[2]; + V_eb_e(0, current_epoch) = pvt_reader.rr[3]; + V_eb_e(1, current_epoch) = pvt_reader.rr[4]; + V_eb_e(2, current_epoch) = pvt_reader.rr[5]; + LLH(0, current_epoch) = pvt_reader.latitude; + LLH(1, current_epoch) = pvt_reader.longitude; + LLH(2, current_epoch) = pvt_reader.height; + + arma::vec tmp_r_enu = {0, 0, 0}; + cart2utm(R_eb_e.col(current_epoch), utm_zone, tmp_r_enu); + R_eb_enu.insert_cols(current_epoch, tmp_r_enu); + + // debug check + // std::cout << "t1: " << pvt_reader.RX_time << std::endl; + // std::cout << "t2: " << pvt_reader.TOW_at_current_symbol_ms << std::endl; + // std::cout << "offset: " << pvt_reader.clk_offset_s << std::endl; + // getchar(); + current_epoch++; + } + ASSERT_FALSE(current_epoch == 0) << "PVT dump is empty"; + + // compute results + if (FLAGS_static_scenario) + { + double sigma_E_2_precision = arma::var(R_eb_enu.row(0)); + double sigma_N_2_precision = arma::var(R_eb_enu.row(1)); + double sigma_U_2_precision = arma::var(R_eb_enu.row(2)); + + arma::rowvec error_east_m; + error_east_m = R_eb_enu.row(0) - ref_r_enu(0); + double sigma_E_2_accuracy = arma::as_scalar(error_east_m * error_east_m.t()); + sigma_E_2_accuracy = sigma_E_2_accuracy / error_east_m.n_elem; + + arma::rowvec error_north_m; + error_north_m = R_eb_enu.row(1) - ref_r_enu(1); + double sigma_N_2_accuracy = arma::as_scalar(error_north_m * error_north_m.t()); + sigma_N_2_accuracy = sigma_N_2_accuracy / error_north_m.n_elem; + + arma::rowvec error_up_m; + error_up_m = R_eb_enu.row(2) - ref_r_enu(2); + double sigma_U_2_accuracy = arma::as_scalar(error_up_m * error_up_m.t()); + sigma_U_2_accuracy = sigma_U_2_accuracy / error_up_m.n_elem; + + // arma::mat error_enu_mat = arma::zeros(3, error_east_m.n_elem); + // error_enu_mat.row(0) = error_east_m; + // error_enu_mat.row(1) = error_north_m; + // error_enu_mat.row(2) = error_up_m; + // + // arma::vec error_2D_m = arma::zeros(error_enu_mat.n_cols, 1); + // arma::vec error_3D_m = arma::zeros(error_enu_mat.n_cols, 1); + // for (uint64_t n = 0; n < error_enu_mat.n_cols; n++) + // { + // error_2D_m(n) = arma::norm(error_enu_mat.submat(0, n, 1, n)); + // error_3D_m(n) = arma::norm(error_enu_mat.col(n)); + // } + + double static_2D_error_m = sqrt(pow(arma::mean(error_east_m), 2.0) + pow(arma::mean(error_north_m), 2.0)); + double static_3D_error_m = sqrt(pow(arma::mean(error_east_m), 2.0) + pow(arma::mean(error_north_m), 2.0) + pow(arma::mean(error_up_m), 2.0)); + + std::stringstream stm; + std::ofstream position_test_file; + if (!FLAGS_config_file_ptest.empty()) + { + stm << "Configuration file: " << FLAGS_config_file_ptest << std::endl; + } + + stm << "---- STATIC ACCURACY ----" << std::endl; stm << "2DRMS = " << 2 * sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl; stm << "DRMS = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]" << std::endl; - stm << "CEP = " << 0.62 * compute_stdev_accuracy(pos_n, 0.0) + 0.56 * compute_stdev_accuracy(pos_e, 0.0) << " [m]" << std::endl; + stm << "CEP = " << 0.62 * sqrt(sigma_N_2_accuracy) + 0.56 * sqrt(sigma_E_2_accuracy) << " [m]" << std::endl; stm << "99% SAS = " << 1.122 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; stm << "90% SAS = " << 0.833 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; stm << "MRSE = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; stm << "SEP = " << 0.51 * (sigma_E_2_accuracy + sigma_N_2_accuracy + sigma_U_2_accuracy) << " [m]" << std::endl; - stm << "Bias 2D = " << sqrt(std::pow(mean__e, 2.0) + std::pow(mean__n, 2.0)) << " [m]" << std::endl; - stm << "Bias 3D = " << sqrt(std::pow(mean__e, 2.0) + std::pow(mean__n, 2.0) + std::pow(mean__u, 2.0)) << " [m]" << std::endl; + stm << "Static Bias 2D = " << static_2D_error_m << " [m]" << std::endl; + stm << "Static Bias 3D = " << static_3D_error_m << " [m]" << std::endl; stm << std::endl; + + stm << "---- STATIC PRECISION ----" << std::endl; + stm << "2DRMS = " << 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl; + stm << "DRMS = " << sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl; + stm << "CEP = " << 0.62 * sqrt(sigma_N_2_precision) + 0.56 * sqrt(sigma_E_2_precision) << " [m]" << std::endl; + stm << "99% SAS = " << 1.122 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; + stm << "90% SAS = " << 0.833 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; + stm << "MRSE = " << sqrt(sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; + stm << "SEP = " << 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; + + std::cout << stm.rdbuf(); + std::string output_filename = "position_test_output_" + PositionSystemTest::generated_kml_file.erase(PositionSystemTest::generated_kml_file.length() - 3, 3) + "txt"; + position_test_file.open(output_filename.c_str()); + if (position_test_file.is_open()) + { + position_test_file << stm.str(); + position_test_file.close(); + } + + // Sanity Check + double accuracy_CEP = 0.62 * sqrt(sigma_N_2_accuracy) + 0.56 * sqrt(sigma_E_2_accuracy); + double precision_SEP = 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision); + + EXPECT_LT(static_2D_error_m, FLAGS_static_2D_error_m); + EXPECT_LT(static_2D_error_m, FLAGS_static_2D_error_m); + ASSERT_LT(accuracy_CEP, FLAGS_accuracy_CEP); + ASSERT_LT(precision_SEP, FLAGS_precision_SEP); + + if (FLAGS_plot_position_test == true) + { + print_results(R_eb_enu); + } } - - stm << "---- PRECISION ----" << std::endl; - stm << "2DRMS = " << 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl; - stm << "DRMS = " << sqrt(sigma_E_2_precision + sigma_N_2_precision) << " [m]" << std::endl; - stm << "CEP = " << 0.62 * compute_stdev_precision(pos_n) + 0.56 * compute_stdev_precision(pos_e) << " [m]" << std::endl; - stm << "99% SAS = " << 1.122 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; - stm << "90% SAS = " << 0.833 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; - stm << "MRSE = " << sqrt(sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; - stm << "SEP = " << 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision) << " [m]" << std::endl; - - std::cout << stm.rdbuf(); - std::string output_filename = "position_test_output_" + StaticPositionSystemTest::generated_kml_file.erase(StaticPositionSystemTest::generated_kml_file.length() - 3, 3) + "txt"; - position_test_file.open(output_filename.c_str()); - if (position_test_file.is_open()) + else { - position_test_file << stm.str(); - position_test_file.close(); - } + //dynamic position + spirent_motion_csv_dump_reader ref_reader; + ref_reader.open_obs_file(FLAGS_ref_motion_filename); + int64_t n_epochs = ref_reader.num_epochs(); + ref_R_eb_e = arma::zeros(3, n_epochs); + ref_V_eb_e = arma::zeros(3, n_epochs); + ref_LLH = arma::zeros(3, n_epochs); + ref_time_s = arma::zeros(n_epochs, 1); + int64_t current_epoch = 0; + while (ref_reader.read_csv_obs()) + { + ref_time_s(current_epoch) = ref_reader.TOW_ms / 1000.0; + ref_R_eb_e(0, current_epoch) = ref_reader.Pos_X; + ref_R_eb_e(1, current_epoch) = ref_reader.Pos_Y; + ref_R_eb_e(2, current_epoch) = ref_reader.Pos_Z; + ref_V_eb_e(0, current_epoch) = ref_reader.Vel_X; + ref_V_eb_e(1, current_epoch) = ref_reader.Vel_Y; + ref_V_eb_e(2, current_epoch) = ref_reader.Vel_Z; + ref_LLH(0, current_epoch) = ref_reader.Lat; + ref_LLH(1, current_epoch) = ref_reader.Long; + ref_LLH(2, current_epoch) = ref_reader.Height; + current_epoch++; + } + //interpolation of reference data to receiver epochs timestamps + arma::mat ref_interp_R_eb_e = arma::zeros(3, R_eb_e.n_cols); + arma::mat ref_interp_V_eb_e = arma::zeros(3, V_eb_e.n_cols); + arma::mat ref_interp_LLH = arma::zeros(3, LLH.n_cols); + arma::vec tmp_vector; + for (int n = 0; n < 3; n++) + { + arma::interp1(ref_time_s, ref_R_eb_e.row(n), receiver_time_s, tmp_vector); + ref_interp_R_eb_e.row(n) = tmp_vector.t(); + arma::interp1(ref_time_s, ref_V_eb_e.row(n), receiver_time_s, tmp_vector); + ref_interp_V_eb_e.row(n) = tmp_vector.t(); + arma::interp1(ref_time_s, ref_LLH.row(n), receiver_time_s, tmp_vector); + ref_interp_LLH.row(n) = tmp_vector.t(); + } - // Sanity Check - double precision_SEP = 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision); - ASSERT_LT(precision_SEP, 20.0); + //compute error vectors + arma::mat error_R_eb_e = arma::zeros(3, R_eb_e.n_cols); + arma::mat error_V_eb_e = arma::zeros(3, V_eb_e.n_cols); + arma::mat error_LLH = arma::zeros(3, LLH.n_cols); + error_R_eb_e = R_eb_e - ref_interp_R_eb_e; + error_V_eb_e = V_eb_e - ref_interp_V_eb_e; + error_LLH = LLH - ref_interp_LLH; + arma::vec error_module_R_eb_e = arma::zeros(R_eb_e.n_cols, 1); + arma::vec error_module_V_eb_e = arma::zeros(V_eb_e.n_cols, 1); + for (uint64_t n = 0; n < R_eb_e.n_cols; n++) + { + error_module_R_eb_e(n) = arma::norm(error_R_eb_e.col(n)); + error_module_V_eb_e(n) = arma::norm(error_V_eb_e.col(n)); + } - if (FLAGS_plot_position_test == true) - { - print_results(pos_e, pos_n, pos_u); + //Error statistics + arma::vec tmp_vec; + //RMSE, Mean, Variance and peaks + tmp_vec = arma::square(error_module_R_eb_e); + double rmse_R_eb_e = sqrt(arma::mean(tmp_vec)); + double error_mean_R_eb_e = arma::mean(error_module_R_eb_e); + double error_var_R_eb_e = arma::var(error_module_R_eb_e); + double max_error_R_eb_e = arma::max(error_module_R_eb_e); + double min_error_R_eb_e = arma::min(error_module_R_eb_e); + + tmp_vec = arma::square(error_module_V_eb_e); + double rmse_V_eb_e = sqrt(arma::mean(tmp_vec)); + double error_mean_V_eb_e = arma::mean(error_module_V_eb_e); + double error_var_V_eb_e = arma::var(error_module_V_eb_e); + double max_error_V_eb_e = arma::max(error_module_V_eb_e); + double min_error_V_eb_e = arma::min(error_module_V_eb_e); + + //report + std::cout << "----- Position and Velocity 3D ECEF error statistics -----" << std::endl; + if (!FLAGS_config_file_ptest.empty()) + { + std::cout << "---- Configuration file: " << FLAGS_config_file_ptest << std::endl; + } + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(10) << "---- 3D ECEF Position RMSE = " + << rmse_R_eb_e << ", mean = " << error_mean_R_eb_e + << ", stdev = " << sqrt(error_var_R_eb_e) + << " (max,min) = " << max_error_R_eb_e + << "," << min_error_R_eb_e + << " [m]" << std::endl; + std::cout << "---- 3D ECEF Velocity RMSE = " + << rmse_V_eb_e << ", mean = " << error_mean_V_eb_e + << ", stdev = " << sqrt(error_var_V_eb_e) + << " (max,min) = " << max_error_V_eb_e + << "," << min_error_V_eb_e + << " [m/s]" << std::endl; + std::cout.precision(ss); + + // plots + if (FLAGS_plot_position_test == true) + { + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if (!gnuplot_executable.empty()) + { + Gnuplot g1("points"); + if (FLAGS_show_plots) + { + g1.showonscreen(); // window output + } + else + { + g1.disablescreen(); + } + g1.set_title("3D ECEF error coordinates"); + g1.set_grid(); + //conversion between arma::vec and std:vector + arma::rowvec arma_vec_error_x = error_R_eb_e.row(0); + arma::rowvec arma_vec_error_y = error_R_eb_e.row(1); + arma::rowvec arma_vec_error_z = error_R_eb_e.row(2); + + std::vector X(arma_vec_error_x.colptr(0), arma_vec_error_x.colptr(0) + arma_vec_error_x.n_rows); + std::vector Y(arma_vec_error_y.colptr(0), arma_vec_error_y.colptr(0) + arma_vec_error_y.n_rows); + std::vector Z(arma_vec_error_z.colptr(0), arma_vec_error_z.colptr(0) + arma_vec_error_z.n_rows); + + g1.cmd("set key box opaque"); + g1.plot_xyz(X, Y, Z, "ECEF 3D error"); + g1.set_legend(); + if (FLAGS_config_file_ptest.empty()) + { + g1.savetops("ECEF_3d_error"); + } + else + { + g1.savetops("ECEF_3d_error_" + config_filename_no_extension); + } + arma::vec time_vector_from_start_s = receiver_time_s - receiver_time_s(0); + Gnuplot g3("linespoints"); + if (FLAGS_show_plots) + { + g3.showonscreen(); // window output + } + else + { + g3.disablescreen(); + } + g3.set_title("3D Position estimation error module [m]"); + g3.set_grid(); + g3.set_xlabel("Receiver epoch time from first valid PVT [s]"); + g3.set_ylabel("3D Position error [m]"); + //conversion between arma::vec and std:vector + std::vector error_vec(error_module_R_eb_e.colptr(0), error_module_R_eb_e.colptr(0) + error_module_R_eb_e.n_rows); + g3.cmd("set key box opaque"); + g3.plot_xy(time_vector_from_start_s, error_vec, "Position 3D error"); + double mean3d = std::accumulate(error_vec.begin(), error_vec.end(), 0.0) / error_vec.size(); + std::vector error_mean(error_module_R_eb_e.n_rows, mean3d); + g3.set_style("lines"); + g3.plot_xy(time_vector_from_start_s, error_mean, "Mean"); + g3.set_legend(); + if (FLAGS_config_file_ptest.empty()) + { + g3.savetops("Position_3d_error"); + } + else + { + g3.savetops("Position_3d_error_" + config_filename_no_extension); + } + + Gnuplot g4("linespoints"); + if (FLAGS_show_plots) + { + g4.showonscreen(); // window output + } + else + { + g4.disablescreen(); + } + g4.set_title("3D Velocity estimation error module [m/s]"); + g4.set_grid(); + g4.set_xlabel("Receiver epoch time from first valid PVT [s]"); + g4.set_ylabel("3D Velocity error [m/s]"); + //conversion between arma::vec and std:vector + std::vector error_vec2(error_module_V_eb_e.colptr(0), error_module_V_eb_e.colptr(0) + error_module_V_eb_e.n_rows); + g4.cmd("set key box opaque"); + g4.plot_xy(time_vector_from_start_s, error_vec2, "Velocity 3D error"); + double mean3dv = std::accumulate(error_vec2.begin(), error_vec2.end(), 0.0) / error_vec2.size(); + std::vector error_mean_v(error_module_V_eb_e.n_rows, mean3dv); + g4.set_style("lines"); + g4.plot_xy(time_vector_from_start_s, error_mean_v, "Mean"); + g4.set_legend(); + if (FLAGS_config_file_ptest.empty()) + { + g4.savetops("Velocity_3d_error"); + } + else + { + g4.savetops("Velocity_3d_error_" + config_filename_no_extension); + } + } + } + + //ERROR CHECK + //todo: reduce the error tolerance or enable the option to pass the error tolerance by parameter + EXPECT_LT(rmse_R_eb_e, FLAGS_dynamic_3D_position_RMSE); //3D RMS positioning error less than 10 meters + EXPECT_LT(rmse_V_eb_e, FLAGS_dynamic_3D_velocity_RMSE); //3D RMS speed error less than 5 meters/s (18 km/h) } } -void StaticPositionSystemTest::print_results(const std::vector& east, - const std::vector& north, - const std::vector& up) +void PositionSystemTest::print_results(arma::mat R_eb_enu) { const std::string gnuplot_executable(FLAGS_gnuplot_executable); if (gnuplot_executable.empty()) @@ -588,29 +793,40 @@ void StaticPositionSystemTest::print_results(const std::vector& east, } else { - double sigma_E_2_precision = std::pow(compute_stdev_precision(east), 2.0); - double sigma_N_2_precision = std::pow(compute_stdev_precision(north), 2.0); - double sigma_U_2_precision = std::pow(compute_stdev_precision(up), 2.0); + double sigma_E_2_precision = arma::var(R_eb_enu.row(0)); + double sigma_N_2_precision = arma::var(R_eb_enu.row(1)); + double sigma_U_2_precision = arma::var(R_eb_enu.row(2)); - double mean_east = std::accumulate(east.begin(), east.end(), 0.0) / east.size(); - double mean_north = std::accumulate(north.begin(), north.end(), 0.0) / north.size(); + double mean_east = arma::mean(R_eb_enu.row(0)); + double mean_north = arma::mean(R_eb_enu.row(1)); + double mean_up = arma::mean(R_eb_enu.row(2)); - auto it_max_east = std::max_element(std::begin(east), std::end(east)); - auto it_min_east = std::min_element(std::begin(east), std::end(east)); - auto it_max_north = std::max_element(std::begin(north), std::end(north)); - auto it_min_north = std::min_element(std::begin(north), std::end(north)); - auto it_max_up = std::max_element(std::begin(up), std::end(up)); - auto it_min_up = std::min_element(std::begin(up), std::end(up)); + double it_max_east = arma::max(R_eb_enu.row(0) - mean_east); + double it_min_east = arma::min(R_eb_enu.row(0) - mean_east); - auto east_range = std::max(*it_max_east, std::abs(*it_min_east)); - auto north_range = std::max(*it_max_north, std::abs(*it_min_north)); - auto up_range = std::max(*it_max_up, std::abs(*it_min_up)); + double it_max_north = arma::max(R_eb_enu.row(1) - mean_north); + double it_min_north = arma::min(R_eb_enu.row(1) - mean_north); + + double it_max_up = arma::max(R_eb_enu.row(2) - mean_up); + double it_min_up = arma::min(R_eb_enu.row(2) - mean_up); + + double east_range = std::max(it_max_east, std::abs(it_min_east)); + double north_range = std::max(it_max_north, std::abs(it_min_north)); + double up_range = std::max(it_max_up, std::abs(it_min_up)); double range = std::max(east_range, north_range) * 1.1; double range_3d = std::max(std::max(east_range, north_range), up_range) * 1.1; double two_drms = 2 * sqrt(sigma_E_2_precision + sigma_N_2_precision); double ninty_sas = 0.833 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision); + arma::rowvec arma_east = R_eb_enu.row(0) - mean_east; + arma::rowvec arma_north = R_eb_enu.row(1) - mean_north; + arma::rowvec arma_up = R_eb_enu.row(2) - mean_up; + + std::vector east(arma_east.colptr(0), arma_east.row(0).colptr(0) + arma_east.row(0).n_cols); + std::vector north(arma_north.colptr(0), arma_north.colptr(0) + arma_north.n_cols); + std::vector up(arma_up.colptr(0), arma_up.colptr(0) + arma_up.n_cols); + try { boost::filesystem::path p(gnuplot_executable); @@ -619,6 +835,14 @@ void StaticPositionSystemTest::print_results(const std::vector& east, Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("points"); + if (FLAGS_show_plots) + { + g1.showonscreen(); // window output + } + else + { + g1.disablescreen(); + } g1.set_title("2D precision"); g1.set_xlabel("East [m]"); g1.set_ylabel("North [m]"); @@ -626,18 +850,33 @@ void StaticPositionSystemTest::print_results(const std::vector& east, g1.cmd("set xrange [-" + std::to_string(range) + ":" + std::to_string(range) + "]"); g1.cmd("set yrange [-" + std::to_string(range) + ":" + std::to_string(range) + "]"); + g1.plot_xy(east, north, "2D Position Fixes"); g1.set_style("lines").plot_circle(mean_east, mean_north, two_drms, "2DRMS"); g1.set_style("lines").plot_circle(mean_east, mean_north, two_drms / 2.0, "DRMS"); g1.cmd("set grid front"); g1.cmd("replot"); - - g1.savetops("Position_test_2D"); - g1.savetopdf("Position_test_2D", 18); - if (FLAGS_show_plots) g1.showonscreen(); // window output + if (FLAGS_config_file_ptest.empty()) + { + g1.savetops("Position_test_2D"); + g1.savetopdf("Position_test_2D", 18); + } + else + { + g1.savetops("Position_test_2D_" + config_filename_no_extension); + g1.savetopdf("Position_test_2D_" + config_filename_no_extension, 18); + } Gnuplot g2("points"); + if (FLAGS_show_plots) + { + g2.showonscreen(); // window output + } + else + { + g2.disablescreen(); + } g2.set_title("3D precision"); g2.set_xlabel("East [m]"); g2.set_ylabel("North [m]"); @@ -653,10 +892,16 @@ void StaticPositionSystemTest::print_results(const std::vector& east, std::to_string(ninty_sas) + "\n fx(v,u) = r*cos(v)*cos(u)\n fy(v,u) = r*cos(v)*sin(u)\n fz(v) = r*sin(v) \n splot fx(v,u),fy(v,u),fz(v) title \"90\%-SAS\" lt rgb \"gray\"\n"); g2.plot_xyz(east, north, up, "3D Position Fixes"); - - g2.savetops("Position_test_3D"); - g2.savetopdf("Position_test_3D"); - if (FLAGS_show_plots) g2.showonscreen(); // window output + if (FLAGS_config_file_ptest.empty()) + { + g2.savetops("Position_test_3D"); + g2.savetopdf("Position_test_3D"); + } + else + { + g2.savetops("Position_test_3D_" + config_filename_no_extension); + g2.savetopdf("Position_test_3D_" + config_filename_no_extension); + } } catch (const GnuplotException& ge) { @@ -665,7 +910,7 @@ void StaticPositionSystemTest::print_results(const std::vector& east, } } -TEST_F(StaticPositionSystemTest, Position_system_test) +TEST_F(PositionSystemTest, Position_system_test) { if (FLAGS_config_file_ptest.empty()) { @@ -678,12 +923,17 @@ TEST_F(StaticPositionSystemTest, Position_system_test) generate_signal(); } } + else + { + config_filename_no_extension = FLAGS_config_file_ptest.substr(FLAGS_config_file_ptest.find_last_of("/\\") + 1); + config_filename_no_extension = config_filename_no_extension.erase(config_filename_no_extension.length() - 5); + } // Configure receiver configure_receiver(); // Run the receiver - EXPECT_EQ(run_receiver(), 0) << "Problem executing the software-defined signal generator"; + EXPECT_EQ(run_receiver(), 0) << "Problem executing GNSS-SDR"; // Check results check_results(); diff --git a/src/tests/system-tests/ttff.cc b/src/tests/system-tests/ttff.cc index 2d5dbba44..6bea0a570 100644 --- a/src/tests/system-tests/ttff.cc +++ b/src/tests/system-tests/ttff.cc @@ -135,7 +135,7 @@ void TtffTest::config_1() config->set_property("GNSS-SDR.SUPL_gps_acquisition_server", "supl.google.com"); config->set_property("GNSS-SDR.SUPL_gps_acquisition_port", std::to_string(7275)); config->set_property("GNSS-SDR.SUPL_MCC", std::to_string(244)); - config->set_property("GNSS-SDR.SUPL_MNS", std::to_string(5)); + config->set_property("GNSS-SDR.SUPL_MNC", std::to_string(5)); config->set_property("GNSS-SDR.SUPL_LAC", "0x59e2"); config->set_property("GNSS-SDR.SUPL_CI", "0x31b0"); diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index eb010b807..79627ae9a 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -69,6 +69,21 @@ using google::LogMessage; DECLARE_string(log_dir); +#if UNIT_TESTING_MINIMAL + +#include "unit-tests/arithmetic/matio_test.cc" +#if EXTRA_TESTS +#include "unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc" +#include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc" +#if ENABLE_FPGA +#include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc" +#endif +#include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc" +#endif + + +#else + #include "unit-tests/arithmetic/complex_carrier_test.cc" #include "unit-tests/arithmetic/conjugate_test.cc" #include "unit-tests/arithmetic/magnitude_squared_test.cc" @@ -127,6 +142,7 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc" #include "unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_test.cc" #include "unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc" +#include "unit-tests/signal-processing-blocks/tracking/bayesian_estimation_test.cc" #if CUDA_BLOCKS_TEST #include "unit-tests/signal-processing-blocks/tracking/gpu_multicorrelator_test.cc" @@ -137,24 +153,33 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc" #endif +#include "unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc" +#include "unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc" +#include "unit-tests/system-parameters/glonass_gnav_nav_message_test.cc" + #include "unit-tests/signal-processing-blocks/pvt/rtcm_test.cc" #include "unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc" #include "unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc" #include "unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc" + #if EXTRA_TESTS #include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc" -#include "unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc" +#include "unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc" -#include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc" +#include "unit-tests/signal-processing-blocks/tracking/gps_l1_ca_kf_tracking_test.cc" +#include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc" +#include "unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc" +#if ENABLE_FPGA +#include "unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc" +#endif #include "unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc" #include "unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc" #endif -#include "unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc" -#include "unit-tests/system-parameters/glonass_gnav_nav_message_test.cc" +#endif // UNIT_TESTING_MINIMAL // For GPS NAVIGATION (L1) concurrent_queue global_gps_acq_assist_queue; diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/src/tests/unit-tests/arithmetic/fft_length_test.cc index 78961dd2b..f7f006d99 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/src/tests/unit-tests/arithmetic/fft_length_test.cc @@ -116,6 +116,14 @@ TEST(FFTLengthTest, MeasureExecutionTime) Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("linespoints"); + if (FLAGS_show_plots) + { + g1.showonscreen(); // window output + } + else + { + g1.disablescreen(); + } g1.set_title("FFT execution times for different lengths"); g1.set_grid(); g1.set_xlabel("FFT length"); @@ -124,9 +132,16 @@ TEST(FFTLengthTest, MeasureExecutionTime) g1.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); g1.savetops("FFT_execution_times_extended"); g1.savetopdf("FFT_execution_times_extended", 18); - if (FLAGS_show_plots) g1.showonscreen(); // window output Gnuplot g2("linespoints"); + if (FLAGS_show_plots) + { + g2.showonscreen(); // window output + } + else + { + g2.disablescreen(); + } g2.set_title("FFT execution times for different lengths (up to 2^{14}=16384)"); g2.set_grid(); g2.set_xlabel("FFT length"); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc similarity index 78% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc rename to src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc index 164dd96b4..d0dcc4673 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_acq_performance_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc @@ -1,5 +1,5 @@ /*! - * \file gps_l1_acq_performance_test.cc + * \file acq_performance_test.cc * \brief This class implements an acquisition performance test * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.cat * @@ -29,39 +29,54 @@ * ------------------------------------------------------------------------- */ -#include "test_flags.h" -#include "signal_generator_flags.h" -#include "tracking_true_obs_reader.h" -#include "true_observables_reader.h" #include "gps_l1_ca_pcps_acquisition.h" #include "gps_l1_ca_pcps_acquisition_fine_doppler.h" +#include "galileo_e1_pcps_ambiguous_acquisition.h" +#include "galileo_e5a_pcps_acquisition.h" +#include "glonass_l1_ca_pcps_acquisition.h" +#include "glonass_l2_ca_pcps_acquisition.h" +#include "gps_l2_m_pcps_acquisition.h" +#include "gps_l5i_pcps_acquisition.h" +#include "in_memory_configuration.h" +#include "file_configuration.h" +#include "gnss_sdr_valve.h" +#include "acquisition_dump_reader.h" #include "display.h" #include "gnuplot_i.h" +#include "signal_generator_flags.h" +#include "test_flags.h" +#include "tracking_true_obs_reader.h" +#include "true_observables_reader.h" #include #include -#include -#include +#include +#include +#include + DEFINE_string(config_file_ptest, std::string(""), "File containing alternative configuration parameters for the acquisition performance test."); DEFINE_string(acq_test_input_file, std::string(""), "File containing raw signal data, must be in int8_t format. The signal generator will not be used."); -DEFINE_string(acq_test_implementation, std::string("GPS_L1_CA_PCPS_Acquisition"), "Acquisition block implementation under test. Alternative: GPS_L1_CA_PCPS_Acquisition_Fine_Doppler"); +DEFINE_string(acq_test_implementation, std::string("GPS_L1_CA_PCPS_Acquisition"), "Acquisition block implementation under test. Alternatives: GPS_L1_CA_PCPS_Acquisition, GPS_L1_CA_PCPS_Acquisition_Fine_Doppler, Galileo_E1_PCPS_Ambiguous_Acquisition, GLONASS_L1_CA_PCPS_Acquisition, GLONASS_L2_CA_PCPS_Acquisition, GPS_L2_M_PCPS_Acquisition, Galileo_E5a_Pcps_Acquisition, GPS_L5i_PCPS_Acquisition"); DEFINE_int32(acq_test_doppler_max, 5000, "Maximum Doppler, in Hz"); DEFINE_int32(acq_test_doppler_step, 125, "Doppler step, in Hz."); DEFINE_int32(acq_test_coherent_time_ms, 1, "Acquisition coherent time, in ms"); -DEFINE_int32(acq_test_max_dwells, 1, "Number of non-coherent integrations"); -DEFINE_bool(acq_test_use_CFAR_algorithm, true, "Use CFAR algorithm"); -DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag"); +DEFINE_int32(acq_test_max_dwells, 1, "Number of non-coherent integrations."); +DEFINE_bool(acq_test_use_CFAR_algorithm, true, "Use CFAR algorithm."); +DEFINE_bool(acq_test_bit_transition_flag, false, "Bit transition flag."); +DEFINE_bool(acq_test_make_two_steps, false, "Perform second step in a thinner grid."); +DEFINE_int32(acq_test_second_nbins, 4, "If --acq_test_make_two_steps is set to true, this parameter sets the number of bins done in the acquisition refinement stage."); +DEFINE_int32(acq_test_second_doppler_step, 10, "If --acq_test_make_two_steps is set to true, this parameter sets the Doppler step applied in the acquisition refinement stage, in Hz."); DEFINE_int32(acq_test_signal_duration_s, 2, "Generated signal duration, in s"); DEFINE_int32(acq_test_num_meas, 0, "Number of measurements per run. 0 means the complete file."); -DEFINE_double(acq_test_cn0_init, 33.0, "Initial CN0, in dBHz."); +DEFINE_double(acq_test_cn0_init, 30.0, "Initial CN0, in dBHz."); DEFINE_double(acq_test_cn0_final, 45.0, "Final CN0, in dBHz."); DEFINE_double(acq_test_cn0_step, 3.0, "CN0 step, in dB."); -DEFINE_double(acq_test_threshold_init, 11.0, "Initial acquisition threshold"); -DEFINE_double(acq_test_threshold_final, 16.0, "Final acquisition threshold"); -DEFINE_double(acq_test_threshold_step, 1.0, "Acquisition threshold step"); +DEFINE_double(acq_test_threshold_init, 3.0, "Initial acquisition threshold"); +DEFINE_double(acq_test_threshold_final, 4.0, "Final acquisition threshold"); +DEFINE_double(acq_test_threshold_step, 0.5, "Acquisition threshold step"); DEFINE_double(acq_test_pfa_init, 1e-5, "Set initial threshold via probability of false alarm. Disable with -1.0"); @@ -70,6 +85,7 @@ DEFINE_int32(acq_test_fake_PRN, 33, "PRN number of a non-present satellite"); DEFINE_int32(acq_test_iterations, 1, "Number of iterations (same signal, different noise realization)"); DEFINE_bool(plot_acq_test, false, "Plots results with gnuplot, if available"); +DEFINE_int32(acq_test_skiphead, 0, "Number of samples to skip in the input file"); // ######## GNURADIO BLOCK MESSAGE RECEVER ######### class AcqPerfTest_msg_rx; @@ -102,7 +118,7 @@ void AcqPerfTest_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } @@ -154,6 +170,84 @@ protected: { cn0_vector = {0.0}; } + + if (implementation.compare("GPS_L1_CA_PCPS_Acquisition") == 0) + { + signal_id = "1C"; + system_id = 'G'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + min_integration_ms = 1; + } + else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0) + { + signal_id = "1C"; + system_id = 'G'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + min_integration_ms = 1; + } + else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0) + { + signal_id = "1B"; + system_id = 'E'; + min_integration_ms = 4; + if (FLAGS_acq_test_coherent_time_ms == 1) + { + coherent_integration_time_ms = 4; + } + else + { + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + } + } + else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0) + { + signal_id = "1G"; + system_id = 'R'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + min_integration_ms = 1; + } + else if (implementation.compare("GLONASS_L2_CA_PCPS_Acquisition") == 0) + { + signal_id = "2G"; + system_id = 'R'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + min_integration_ms = 1; + } + else if (implementation.compare("GPS_L2_M_PCPS_Acquisition") == 0) + { + signal_id = "2S"; + system_id = 'G'; + if (FLAGS_acq_test_coherent_time_ms == 1) + { + coherent_integration_time_ms = 20; + } + else + { + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + } + min_integration_ms = 20; + } + else if (implementation.compare("Galileo_E5a_Pcps_Acquisition") == 0) + { + signal_id = "5X"; + system_id = 'E'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + min_integration_ms = 1; + } + else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0) + { + signal_id = "L5"; + system_id = 'G'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + } + else + { + signal_id = "1C"; + system_id = 'G'; + coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + min_integration_ms = 1; + } + init(); if (FLAGS_acq_test_pfa_init > 0.0) @@ -181,7 +275,7 @@ protected: num_thresholds = pfa_vector.size(); - int aux2 = ((generated_signal_duration_s * 1000 - FLAGS_acq_test_coherent_time_ms) / FLAGS_acq_test_coherent_time_ms); + int aux2 = ((generated_signal_duration_s * 1000 - (FLAGS_acq_test_coherent_time_ms * FLAGS_acq_test_max_dwells)) / (FLAGS_acq_test_coherent_time_ms * FLAGS_acq_test_max_dwells)); if ((FLAGS_acq_test_num_meas > 0) and (FLAGS_acq_test_num_meas < aux2)) { num_of_measurements = static_cast(FLAGS_acq_test_num_meas); @@ -240,7 +334,7 @@ protected: std::string implementation = FLAGS_acq_test_implementation; const double baseband_sampling_freq = static_cast(FLAGS_fs_gen_sps); - const int coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; + int coherent_integration_time_ms; const int in_acquisition = 1; const int dump_channel = 0; @@ -252,11 +346,14 @@ protected: std::string path_str = "./acq-perf-test"; int num_thresholds; + unsigned int min_integration_ms; std::vector> Pd; std::vector> Pfa; std::vector> Pd_correct; + std::string signal_id; + private: std::string generator_binary; std::string p1; @@ -268,6 +365,7 @@ private: std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; + char system_id; double compute_stdev_precision(const std::vector& vec); double compute_stdev_accuracy(const std::vector& vec, double ref); @@ -277,8 +375,8 @@ private: void AcquisitionPerformanceTest::init() { gnss_synchro.Channel_ID = 0; - gnss_synchro.System = 'G'; - std::string signal = "1C"; + gnss_synchro.System = system_id; + std::string signal = signal_id; signal.copy(gnss_synchro.Signal, 2, 0); gnss_synchro.PRN = observed_satellite; message = 0; @@ -378,51 +476,59 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_rate_internal)); // Set Acquisition - config->set_property("Acquisition_1C.implementation", implementation); - config->set_property("Acquisition_1C.item_type", "gr_complex"); - config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max)); - config->set_property("Acquisition_1C.doppler_min", std::to_string(-doppler_max)); - config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step)); + config->set_property("Acquisition.implementation", implementation); + config->set_property("Acquisition.item_type", "gr_complex"); + config->set_property("Acquisition.doppler_max", std::to_string(doppler_max)); + config->set_property("Acquisition.doppler_min", std::to_string(-doppler_max)); + config->set_property("Acquisition.doppler_step", std::to_string(doppler_step)); - config->set_property("Acquisition_1C.threshold", std::to_string(pfa)); - //if (FLAGS_acq_test_pfa_init > 0.0) config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); + config->set_property("Acquisition.threshold", std::to_string(pfa)); + //if (FLAGS_acq_test_pfa_init > 0.0) config->supersede_property("Acquisition.pfa", std::to_string(pfa)); if (FLAGS_acq_test_pfa_init > 0.0) { - config->supersede_property("Acquisition_1C.pfa", std::to_string(pfa)); + config->supersede_property("Acquisition.pfa", std::to_string(pfa)); } if (FLAGS_acq_test_use_CFAR_algorithm) { - config->set_property("Acquisition_1C.use_CFAR_algorithm", "true"); + config->set_property("Acquisition.use_CFAR_algorithm", "true"); } else { - config->set_property("Acquisition_1C.use_CFAR_algorithm", "false"); + config->set_property("Acquisition.use_CFAR_algorithm", "false"); } - config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); + config->set_property("Acquisition.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); if (FLAGS_acq_test_bit_transition_flag) { - config->set_property("Acquisition_1C.bit_transition_flag", "true"); + config->set_property("Acquisition.bit_transition_flag", "true"); } else { - config->set_property("Acquisition_1C.bit_transition_flag", "false"); + config->set_property("Acquisition.bit_transition_flag", "false"); } - config->set_property("Acquisition_1C.max_dwells", std::to_string(FLAGS_acq_test_max_dwells)); + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_acq_test_max_dwells)); - config->set_property("Acquisition_1C.repeat_satellite", "true"); + config->set_property("Acquisition.repeat_satellite", "true"); - config->set_property("Acquisition_1C.blocking", "true"); - config->set_property("Acquisition_1C.make_two_steps", "false"); - config->set_property("Acquisition_1C.second_nbins", std::to_string(4)); - config->set_property("Acquisition_1C.second_doppler_step", std::to_string(125)); + config->set_property("Acquisition.blocking", "true"); + if (FLAGS_acq_test_make_two_steps) + { + config->set_property("Acquisition.make_two_steps", "true"); + config->set_property("Acquisition.second_nbins", std::to_string(FLAGS_acq_test_second_nbins)); + config->set_property("Acquisition.second_doppler_step", std::to_string(FLAGS_acq_test_second_doppler_step)); + } + else + { + config->set_property("Acquisition.make_two_steps", "false"); + } - config->set_property("Acquisition_1C.dump", "true"); + + config->set_property("Acquisition.dump", "true"); std::string dump_file = path_str + std::string("/acquisition_") + std::to_string(cn0) + "_" + std::to_string(iter) + "_" + std::to_string(pfa); - config->set_property("Acquisition_1C.dump_filename", dump_file); - config->set_property("Acquisition_1C.dump_channel", std::to_string(dump_channel)); - config->set_property("Acquisition_1C.blocking_on_standby", "true"); + config->set_property("Acquisition.dump_filename", dump_file); + config->set_property("Acquisition.dump_channel", std::to_string(dump_channel)); + config->set_property("Acquisition.blocking_on_standby", "true"); config_f = 0; } @@ -453,6 +559,7 @@ int AcquisitionPerformanceTest::run_receiver() top_block = gr::make_top_block("Acquisition test"); boost::shared_ptr msg_rx = AcqPerfTest_msg_rx_make(channel_internal_queue); + gr::blocks::skiphead::sptr skiphead = gr::blocks::skiphead::make(sizeof(gr_complex), FLAGS_acq_test_skiphead); queue = gr::msg_queue::make(0); gnss_synchro = Gnss_Synchro(); @@ -462,26 +569,47 @@ int AcquisitionPerformanceTest::run_receiver() boost::shared_ptr valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue); if (implementation.compare("GPS_L1_CA_PCPS_Acquisition") == 0) { - acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 0); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GLONASS_L1_CA_PCPS_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GLONASS_L2_CA_PCPS_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L2_M_PCPS_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("Galileo_E5a_Pcps_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L5i_PCPS_Acquisition") == 0) + { + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } else { - if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") == 0) - { - acquisition = std::make_shared(config.get(), "Acquisition_1C", 1, 0); - } - else - { - bool aux = false; - EXPECT_EQ(true, aux); - } + bool aux = false; + EXPECT_EQ(true, aux); } acquisition->set_gnss_synchro(&gnss_synchro); acquisition->set_channel(0); - acquisition->set_doppler_max(config->property("Acquisition_1C.doppler_max", 10000)); - acquisition->set_doppler_step(config->property("Acquisition_1C.doppler_step", 500)); - acquisition->set_threshold(config->property("Acquisition_1C.threshold", 0.0)); + acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); + acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); + acquisition->set_threshold(config->property("Acquisition.threshold", 0.0)); acquisition->init(); acquisition->set_local_code(); @@ -490,7 +618,8 @@ int AcquisitionPerformanceTest::run_receiver() acquisition->reset(); top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); - top_block->connect(gr_interleaved_char_to_complex, 0, valve, 0); + top_block->connect(gr_interleaved_char_to_complex, 0, skiphead, 0); + top_block->connect(skiphead, 0, valve, 0); top_block->connect(valve, 0, acquisition->get_left_block(), 0); top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); @@ -563,7 +692,7 @@ void AcquisitionPerformanceTest::plot_results() } g1.cmd("set font \"Times,18\""); g1.set_title("Receiver Operating Characteristic for GPS L1 C/A acquisition"); - g1.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition_1C.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\""); + g1.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\""); g1.cmd("set logscale x"); g1.cmd("set yrange [0:1]"); g1.cmd("set xrange[0.0001:1]"); @@ -599,7 +728,7 @@ void AcquisitionPerformanceTest::plot_results() } g2.cmd("set font \"Times,18\""); g2.set_title("Receiver Operating Characteristic for GPS L1 C/A valid acquisition"); - g2.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition_1C.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition_1C.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\""); + g2.cmd("set label 1 \"" + std::string("Coherent integration time: ") + std::to_string(config->property("Acquisition.coherent_integration_time_ms", 1)) + " ms, Non-coherent integrations: " + std::to_string(config->property("Acquisition.max_dwells", 1)) + " \" at screen 0.12, 0.83 font \"Times,16\""); g2.cmd("set logscale x"); g2.cmd("set yrange [0:1]"); g2.cmd("set xrange[0.0001:1]"); @@ -692,22 +821,40 @@ TEST_F(AcquisitionPerformanceTest, ROC) run_receiver(); // count executions - std::string basename = path_str + std::string("/acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + std::to_string(pfa_vector[pfa_iter]) + "_" + gnss_synchro.System + "_1C"; + std::string basename = path_str + std::string("/acquisition_") + std::to_string(*it) + "_" + std::to_string(iter) + "_" + std::to_string(pfa_vector[pfa_iter]) + "_" + gnss_synchro.System + "_" + signal_id; int num_executions = count_executions(basename, observed_satellite); // Read measured data - int ch = config->property("Acquisition_1C.dump_channel", 0); + int ch = config->property("Acquisition.dump_channel", 0); arma::vec meas_timestamp_s = arma::zeros(num_executions, 1); arma::vec meas_doppler = arma::zeros(num_executions, 1); arma::vec positive_acq = arma::zeros(num_executions, 1); arma::vec meas_acq_delay_chips = arma::zeros(num_executions, 1); - double coh_time_ms = config->property("Acquisition_1C.coherent_integration_time_ms", 1); + double coh_time_ms = config->property("Acquisition.coherent_integration_time_ms", 1); std::cout << "Num executions: " << num_executions << std::endl; + + unsigned int fft_size = 0; + unsigned int d_consumed_samples = coh_time_ms * config->property("GNSS-SDR.internal_fs_sps", 0) * 0.001; // * (config->property("Acquisition.bit_transition_flag", false) ? 2 : 1); + if (coh_time_ms == min_integration_ms) + { + fft_size = d_consumed_samples; + } + else + { + fft_size = d_consumed_samples * 2; + } + for (int execution = 1; execution <= num_executions; execution++) { - acquisition_dump_reader acq_dump(basename, observed_satellite, config->property("Acquisition_1C.doppler_max", 0), config->property("Acquisition_1C.doppler_step", 0), config->property("GNSS-SDR.internal_fs_sps", 0) * GPS_L1_CA_CODE_PERIOD * static_cast(coh_time_ms), ch, execution); + acquisition_dump_reader acq_dump(basename, + observed_satellite, + config->property("Acquisition.doppler_max", 0), + config->property("Acquisition.doppler_step", 0), + fft_size, + ch, + execution); acq_dump.read_binary_acq(); if (acq_dump.positive_acq) { @@ -735,14 +882,14 @@ TEST_F(AcquisitionPerformanceTest, ROC) true_trk_data.open_obs_file(true_trk_file); // load the true values - long int n_true_epochs = true_trk_data.num_epochs(); + int64_t n_true_epochs = true_trk_data.num_epochs(); arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); arma::vec true_acc_carrier_phase_cycles = arma::zeros(n_true_epochs, 1); arma::vec true_Doppler_Hz = arma::zeros(n_true_epochs, 1); arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); - long int epoch_counter = 0; + int64_t epoch_counter = 0; int num_clean_executions = 0; while (true_trk_data.read_binary_obs()) { @@ -827,7 +974,7 @@ TEST_F(AcquisitionPerformanceTest, ROC) for (int i = 0; i < num_clean_executions - 1; i++) { - if (abs(clean_delay_estimation_error(i)) < 0.5 and abs(clean_doppler_estimation_error(i)) < static_cast(config->property("Acquisition_1C.doppler_step", 1)) / 2.0) + if (abs(clean_delay_estimation_error(i)) < 0.5 and abs(clean_doppler_estimation_error(i)) < static_cast(config->property("Acquisition.doppler_step", 1)) / 2.0) { correctly_detected = correctly_detected + 1.0; } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc index b2784c69f..edc2eb3ce 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc @@ -35,7 +35,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include "gnss_block_interface.h" @@ -80,7 +84,7 @@ void GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test_msg_rx::msg_handler_events { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc index 18ef7b8dc..d5cbef8c0 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc @@ -35,7 +35,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include "gnss_block_interface.h" @@ -81,7 +85,7 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test_msg_rx::msg_handler_events(pm { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc index df03b85b7..e0c6b4534 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc @@ -45,7 +45,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -89,7 +93,7 @@ void GalileoE1PcpsAmbiguousAcquisitionGSoCTest_msg_rx::msg_handler_events(pmt::p { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } @@ -306,7 +310,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionGSoCTest, ValidationOfResults) stop_queue(); - unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples; + uint64_t nsamples = gnss_synchro.Acq_samplestamp_samples; std::cout << "Acquired " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; EXPECT_EQ(2, message) << "Acquisition failure. Expected message: 0=ACQ STOP."; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc index d4477ee8d..10ed1e676 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc @@ -37,7 +37,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -83,7 +87,7 @@ void GalileoE1PcpsAmbiguousAcquisitionTest_msg_rx::msg_handler_events(pmt::pmt_t { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast& e) @@ -201,6 +205,14 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid() Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("lines"); + if (FLAGS_show_plots) + { + g1.showonscreen(); // window output + } + else + { + g1.disablescreen(); + } g1.set_title("Galileo E1b/c signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN)); g1.set_xlabel("Doppler [Hz]"); g1.set_ylabel("Sample"); @@ -209,7 +221,6 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid() g1.savetops("Galileo_E1_acq_grid"); g1.savetopdf("Galileo_E1_acq_grid"); - if (FLAGS_show_plots) g1.showonscreen(); } catch (const GnuplotException& ge) { @@ -332,7 +343,7 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, ValidationOfResults) elapsed_seconds = end - start; }) << "Failure running the top_block."; - unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples; + uint64_t nsamples = gnss_synchro.Acq_samplestamp_samples; std::cout << "Acquired " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; ASSERT_EQ(1, msg_rx->rx_message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS."; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc index a2489cfe1..d2738a9a3 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc @@ -36,7 +36,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include "gnss_block_interface.h" @@ -81,7 +85,7 @@ void GalileoE1PcpsCccwsrAmbiguousAcquisitionTest_msg_rx::msg_handler_events(pmt: { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc index a8177c1a6..9acd50a0a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc @@ -39,7 +39,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include "gnss_block_interface.h" #include "in_memory_configuration.h" @@ -89,7 +93,7 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test_msg_rx::msg_handler_ { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc index 326b44f48..ce86126ea 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc @@ -36,7 +36,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -83,7 +87,7 @@ void GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test_msg_rx::msg_handler_event { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc index 2423257b6..63cf64e3e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc @@ -33,7 +33,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include "gnss_block_interface.h" @@ -80,7 +84,7 @@ void GalileoE5aPcpsAcquisitionGSoC2014GensourceTest_msg_rx::msg_handler_events(p { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc index 2f7c23a2c..30758feac 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc @@ -35,7 +35,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -85,7 +89,7 @@ void GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx::msg_handler_events(pmt::pmt_ { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } @@ -341,7 +345,7 @@ void GlonassL1CaPcpsAcquisitionGSoC2017Test::config_2() std::to_string(integration_time_ms)); config->set_property("Acquisition.max_dwells", "1"); config->set_property("Acquisition.implementation", "GLONASS_L1_CA_PCPS_Acquisition"); - config->set_property("Acquisition.pfa", "0.1"); + //config->set_property("Acquisition.pfa", "0.1"); config->set_property("Acquisition.doppler_max", "10000"); config->set_property("Acquisition.doppler_step", "250"); config->set_property("Acquisition.bit_transition_flag", "false"); @@ -359,8 +363,8 @@ void GlonassL1CaPcpsAcquisitionGSoC2017Test::start_queue() void GlonassL1CaPcpsAcquisitionGSoC2017Test::wait_message() { struct timeval tv; - long long int begin = 0; - long long int end = 0; + int64_t begin = 0; + int64_t end = 0; while (!stop) { @@ -496,7 +500,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionGSoC2017Test, ValidationOfResults) }) << "Failure setting doppler_step."; ASSERT_NO_THROW({ - acquisition->set_threshold(0.5); + acquisition->set_threshold(0.05); }) << "Failure setting threshold."; ASSERT_NO_THROW({ diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc index 928bef457..b250b7e64 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc @@ -37,7 +37,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -80,7 +84,7 @@ void GlonassL1CaPcpsAcquisitionTest_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast& e) @@ -269,7 +273,7 @@ TEST_F(GlonassL1CaPcpsAcquisitionTest, ValidationOfResults) elapsed_seconds = end - begin; }) << "Failure running the top_block."; - unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples; + uint64_t nsamples = gnss_synchro.Acq_samplestamp_samples; std::cout << "Acquired " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; ASSERT_EQ(1, msg_rx->rx_message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS."; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc index c02f40558..cf2af8a56 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc @@ -34,7 +34,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -84,7 +88,7 @@ void GlonassL2CaPcpsAcquisitionTest_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } @@ -354,8 +358,8 @@ void GlonassL2CaPcpsAcquisitionTest::start_queue() void GlonassL2CaPcpsAcquisitionTest::wait_message() { struct timeval tv; - long long int begin = 0; - long long int end = 0; + int64_t begin = 0; + int64_t end = 0; while (!stop) { diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc index 419538dcd..7fe814a5c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc @@ -35,7 +35,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -85,7 +89,7 @@ void GpsL1CaPcpsAcquisitionGSoC2013Test_msg_rx::msg_handler_events(pmt::pmt_t ms { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc index e9ee38210..6f028cd4a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc @@ -38,7 +38,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -84,7 +88,7 @@ void GpsL1CaPcpsAcquisitionTest_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast &e) @@ -202,6 +206,14 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid() Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("lines"); + if (FLAGS_show_plots) + { + g1.showonscreen(); // window output + } + else + { + g1.disablescreen(); + } g1.set_title("GPS L1 C/A signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN)); g1.set_xlabel("Doppler [Hz]"); g1.set_ylabel("Sample"); @@ -210,7 +222,6 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid() g1.savetops("GPS_L1_acq_grid"); g1.savetopdf("GPS_L1_acq_grid"); - if (FLAGS_show_plots) g1.showonscreen(); } catch (const GnuplotException &ge) { @@ -333,7 +344,7 @@ TEST_F(GpsL1CaPcpsAcquisitionTest, ValidationOfResults) elapsed_seconds = end - start; }) << "Failure running the top_block."; - unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples; + uint64_t nsamples = gnss_synchro.Acq_samplestamp_samples; std::cout << "Acquired " << nsamples << " samples in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; ASSERT_EQ(1, msg_rx->rx_message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS."; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc index 050d6df2a..4fba7a4b9 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc @@ -36,7 +36,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -200,7 +204,7 @@ void GpsL1CaPcpsAcquisitionTestFpga_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast &e) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc index f2ee949dc..4ff687b66 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc @@ -36,7 +36,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include "gnss_block_interface.h" @@ -82,7 +86,7 @@ void GpsL1CaPcpsOpenClAcquisitionGSoC2013Test_msg_rx::msg_handler_events(pmt::pm { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc index faf3f433f..2ffd1bd15 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc @@ -37,7 +37,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -87,7 +91,7 @@ void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test_msg_rx::msg_handler_events(pmt: { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc index d5383e16c..d069fd703 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc @@ -36,7 +36,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -83,7 +87,7 @@ void GpsL1CaPcpsTongAcquisitionGSoC2013Test_msg_rx::msg_handler_events(pmt::pmt_ { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc index 7092fac26..d6cb2813c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc @@ -37,7 +37,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -83,7 +87,7 @@ void GpsL2MPcpsAcquisitionTest_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast &e) @@ -205,6 +209,14 @@ void GpsL2MPcpsAcquisitionTest::plot_grid() Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("impulses"); + if (FLAGS_show_plots) + { + g1.showonscreen(); // window output + } + else + { + g1.disablescreen(); + } g1.set_title("GPS L2CM signal acquisition for satellite PRN #" + std::to_string(gnss_synchro.PRN)); g1.set_xlabel("Doppler [Hz]"); g1.set_ylabel("Sample"); @@ -213,7 +225,6 @@ void GpsL2MPcpsAcquisitionTest::plot_grid() g1.savetops("GPS_L2CM_acq_grid"); g1.savetopdf("GPS_L2CM_acq_grid"); - if (FLAGS_show_plots) g1.showonscreen(); } catch (const GnuplotException &ge) { diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc index 51181dd2f..142802256 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc @@ -34,7 +34,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc index 8c5e02dbb..9028403bf 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc @@ -34,7 +34,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc index 9db3593a6..2010b646c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc @@ -34,7 +34,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc index 0ca1840aa..4cff0f421 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc @@ -34,7 +34,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt b/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt index b9a0eb93e..d0bd655d7 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt +++ b/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt @@ -19,26 +19,38 @@ set(SIGNAL_PROCESSING_TESTING_LIB_SOURCES acquisition_dump_reader.cc + acquisition_msg_rx.cc tracking_dump_reader.cc - tlm_dump_reader.cc - observables_dump_reader.cc + tlm_dump_reader.cc + observables_dump_reader.cc tracking_true_obs_reader.cc true_observables_reader.cc ) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${GLOG_INCLUDE_DIRS} - ${GFlags_INCLUDE_DIRS} - ${MATIO_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${Boost_INCLUDE_DIRS} + ${GLOG_INCLUDE_DIRS} + ${GFlags_INCLUDE_DIRS} + ${MATIO_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} ) file(GLOB SIGNAL_PROCESSING_TESTING_LIB_HEADERS "*.h") list(SORT SIGNAL_PROCESSING_TESTING_LIB_HEADERS) -add_library(signal_processing_testing_lib ${SIGNAL_PROCESSING_TESTING_LIB_SOURCES} ${SIGNAL_PROCESSING_TESTING_LIB_HEADERS}) + +add_library(signal_processing_testing_lib + ${SIGNAL_PROCESSING_TESTING_LIB_SOURCES} + ${SIGNAL_PROCESSING_TESTING_LIB_HEADERS} +) + source_group(Headers FILES ${SIGNAL_PROCESSING_TESTING_LIB_HEADERS}) if(NOT MATIO_FOUND) - add_dependencies(signal_processing_testing_lib matio-${GNSSSDR_MATIO_LOCAL_VERSION}) -endif(NOT MATIO_FOUND) \ No newline at end of file + add_dependencies(signal_processing_testing_lib + matio-${GNSSSDR_MATIO_LOCAL_VERSION} glog-${glog_RELEASE} + ) +else() + add_dependencies(signal_processing_testing_lib glog-${glog_RELEASE}) +endif() diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc index 992c6a528..4cb401ab2 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc @@ -102,13 +102,17 @@ bool acquisition_dump_reader::read_binary_acq() Mat_VarFree(var2_); var2_ = Mat_VarRead(matfile, "sample_counter"); - sample_counter = *static_cast(var2_->data); + sample_counter = *static_cast(var2_->data); Mat_VarFree(var2_); var2_ = Mat_VarRead(matfile, "d_positive_acq"); positive_acq = *static_cast(var2_->data); Mat_VarFree(var2_); + var2_ = Mat_VarRead(matfile, "num_dwells"); + num_dwells = *static_cast(var2_->data); + Mat_VarFree(var2_); + var2_ = Mat_VarRead(matfile, "PRN"); PRN = *static_cast(var2_->data); Mat_VarFree(var2_); @@ -180,6 +184,7 @@ acquisition_dump_reader::acquisition_dump_reader(const std::string& basename, d_doppler_step = doppler_step_; d_samples_per_code = samples_per_code_; d_num_doppler_bins = 0; + num_dwells = 0; acquisition_dump_reader(basename, sat_, @@ -211,6 +216,7 @@ acquisition_dump_reader::acquisition_dump_reader(const std::string& basename, threshold = 0.0; positive_acq = 0; sample_counter = 0; + num_dwells = 0; PRN = 0; if (d_doppler_step == 0) d_doppler_step = 1; d_num_doppler_bins = static_cast(ceil(static_cast(static_cast(d_doppler_max) - static_cast(-d_doppler_max)) / static_cast(d_doppler_step))); diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h index 3958b98b2..be5779f38 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h @@ -32,6 +32,7 @@ #ifndef GNSS_SDR_ACQUISITION_DUMP_READER_H #define GNSS_SDR_ACQUISITION_DUMP_READER_H +#include #include #include @@ -64,7 +65,8 @@ public: float threshold; int positive_acq; unsigned int PRN; - long unsigned int sample_counter; + unsigned int num_dwells; + uint64_t sample_counter; private: std::string d_basename; diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.cc b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.cc new file mode 100644 index 000000000..5f7d18b77 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.cc @@ -0,0 +1,70 @@ +/*! + * \file acquisition_msg_rx.cc + * \brief This is a helper class to catch the asynchronous messages + * emitted by an acquisition block. + * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.cat + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2012-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "acquisition_msg_rx.h" +#include +#include +#include +#include + + +Acquisition_msg_rx_sptr Acquisition_msg_rx_make() +{ + return Acquisition_msg_rx_sptr(new Acquisition_msg_rx()); +} + + +void Acquisition_msg_rx::msg_handler_events(pmt::pmt_t msg) +{ + try + { + int64_t message = pmt::to_long(msg); + rx_message = message; + top_block->stop(); // stop the flowgraph + } + catch (boost::bad_any_cast& e) + { + LOG(WARNING) << "msg_handler_acquisition Bad cast!\n"; + rx_message = 0; + } +} + + +Acquisition_msg_rx::Acquisition_msg_rx() : gr::block("Acquisition_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) +{ + this->message_port_register_in(pmt::mp("events")); + this->set_msg_handler(pmt::mp("events"), boost::bind(&Acquisition_msg_rx::msg_handler_events, this, _1)); + rx_message = 0; +} + + +Acquisition_msg_rx::~Acquisition_msg_rx() {} diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.h b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.h new file mode 100644 index 000000000..2095bff72 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.h @@ -0,0 +1,62 @@ +/*! + * \file acquisition_msg_rx.h + * \brief This is a helper class to catch the asynchronous messages + * emitted by an acquisition block. + * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.cat + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2012-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_ACQUISITION_MSG_RX_H +#define GNSS_SDR_ACQUISITION_MSG_RX_H + +#include +#include +#include + +// ######## GNURADIO ACQUISITION BLOCK MESSAGE RECEVER ######### +class Acquisition_msg_rx; + +typedef boost::shared_ptr Acquisition_msg_rx_sptr; + +Acquisition_msg_rx_sptr Acquisition_msg_rx_make(); + + +class Acquisition_msg_rx : public gr::block +{ +private: + friend Acquisition_msg_rx_sptr Acquisition_msg_rx_make(); + void msg_handler_events(pmt::pmt_t msg); + Acquisition_msg_rx(); + +public: + int rx_message; + gr::top_block_sptr top_block; + ~Acquisition_msg_rx(); //!< Default destructor +}; + + +#endif diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc index eb0cb8fac..08f891810 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc @@ -69,7 +69,7 @@ bool observables_dump_reader::restart() } -long int observables_dump_reader::num_epochs() +int64_t observables_dump_reader::num_epochs() { std::ifstream::pos_type size; int number_of_vars_in_epoch = n_channels * 7; @@ -78,7 +78,7 @@ long int observables_dump_reader::num_epochs() if (tmpfile.is_open()) { size = tmpfile.tellg(); - long int nepoch = size / epoch_size_bytes; + int64_t nepoch = size / epoch_size_bytes; return nepoch; } else diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h index c87062eaf..9548829ac 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h @@ -31,6 +31,7 @@ #ifndef GNSS_SDR_OBSERVABLES_DUMP_READER_H #define GNSS_SDR_OBSERVABLES_DUMP_READER_H +#include #include #include #include @@ -42,7 +43,7 @@ public: ~observables_dump_reader(); bool read_binary_obs(); bool restart(); - long int num_epochs(); + int64_t num_epochs(); bool open_obs_file(std::string out_file); void close_obs_file(); diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc index 228a2edbe..64508e56e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc @@ -36,7 +36,7 @@ bool tlm_dump_reader::read_binary_obs() try { d_dump_file.read(reinterpret_cast(&TOW_at_current_symbol), sizeof(double)); - d_dump_file.read(reinterpret_cast(&Tracking_sample_counter), sizeof(unsigned long int)); + d_dump_file.read(reinterpret_cast(&Tracking_sample_counter), sizeof(uint64_t)); d_dump_file.read(reinterpret_cast(&d_TOW_at_Preamble), sizeof(double)); } catch (const std::ifstream::failure &e) @@ -62,16 +62,16 @@ bool tlm_dump_reader::restart() } -long int tlm_dump_reader::num_epochs() +int64_t tlm_dump_reader::num_epochs() { std::ifstream::pos_type size; int number_of_vars_in_epoch = 2; - int epoch_size_bytes = sizeof(double) * number_of_vars_in_epoch + sizeof(unsigned long int); + int epoch_size_bytes = sizeof(double) * number_of_vars_in_epoch + sizeof(uint64_t); std::ifstream tmpfile(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); if (tmpfile.is_open()) { size = tmpfile.tellg(); - long int nepoch = size / epoch_size_bytes; + int64_t nepoch = size / epoch_size_bytes; return nepoch; } else diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h index 1f8a1419f..43178bdc6 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h @@ -31,6 +31,7 @@ #ifndef GNSS_SDR_TLM_DUMP_READER_H #define GNSS_SDR_TLM_DUMP_READER_H +#include #include #include #include @@ -41,12 +42,12 @@ public: ~tlm_dump_reader(); bool read_binary_obs(); bool restart(); - long int num_epochs(); + int64_t num_epochs(); bool open_obs_file(std::string out_file); //telemetry decoder dump variables double TOW_at_current_symbol; - unsigned long int Tracking_sample_counter; + uint64_t Tracking_sample_counter; double d_TOW_at_Preamble; private: diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc index ff82a6a01..5ed6a0fec 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc @@ -42,10 +42,12 @@ bool tracking_dump_reader::read_binary_obs() d_dump_file.read(reinterpret_cast(&abs_VL), sizeof(float)); d_dump_file.read(reinterpret_cast(&prompt_I), sizeof(float)); d_dump_file.read(reinterpret_cast(&prompt_Q), sizeof(float)); - d_dump_file.read(reinterpret_cast(&PRN_start_sample_count), sizeof(unsigned long int)); + d_dump_file.read(reinterpret_cast(&PRN_start_sample_count), sizeof(uint64_t)); d_dump_file.read(reinterpret_cast(&acc_carrier_phase_rad), sizeof(float)); d_dump_file.read(reinterpret_cast(&carrier_doppler_hz), sizeof(float)); + d_dump_file.read(reinterpret_cast(&carrier_doppler_rate_hz_s), sizeof(float)); d_dump_file.read(reinterpret_cast(&code_freq_chips), sizeof(float)); + d_dump_file.read(reinterpret_cast(&code_freq_rate_chips), sizeof(float)); d_dump_file.read(reinterpret_cast(&carr_error_hz), sizeof(float)); d_dump_file.read(reinterpret_cast(&carr_error_filt_hz), sizeof(float)); d_dump_file.read(reinterpret_cast(&code_error_chips), sizeof(float)); @@ -79,18 +81,18 @@ bool tracking_dump_reader::restart() } -long int tracking_dump_reader::num_epochs() +int64_t tracking_dump_reader::num_epochs() { std::ifstream::pos_type size; int number_of_double_vars = 1; - int number_of_float_vars = 17; - int epoch_size_bytes = sizeof(unsigned long int) + sizeof(double) * number_of_double_vars + + int number_of_float_vars = 19; + int epoch_size_bytes = sizeof(uint64_t) + sizeof(double) * number_of_double_vars + sizeof(float) * number_of_float_vars + sizeof(unsigned int); std::ifstream tmpfile(d_dump_filename.c_str(), std::ios::binary | std::ios::ate); if (tmpfile.is_open()) { size = tmpfile.tellg(); - long int nepoch = size / epoch_size_bytes; + int64_t nepoch = size / epoch_size_bytes; return nepoch; } else diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.h index 106a7efdc..790838a8a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.h @@ -31,6 +31,7 @@ #ifndef GNSS_SDR_TRACKING_DUMP_READER_H #define GNSS_SDR_TRACKING_DUMP_READER_H +#include #include #include #include @@ -41,7 +42,7 @@ public: ~tracking_dump_reader(); bool read_binary_obs(); bool restart(); - long int num_epochs(); + int64_t num_epochs(); bool open_obs_file(std::string out_file); //tracking dump variables @@ -55,14 +56,16 @@ public: float prompt_I; float prompt_Q; // PRN start sample stamp - unsigned long int PRN_start_sample_count; + uint64_t PRN_start_sample_count; // accumulated carrier phase float acc_carrier_phase_rad; // carrier and code frequency float carrier_doppler_hz; + float carrier_doppler_rate_hz_s; float code_freq_chips; + float code_freq_rate_chips; // PLL commands float carr_error_hz; diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc index b2e00a1e8..2c03737cd 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc @@ -64,7 +64,7 @@ bool tracking_true_obs_reader::restart() } -long int tracking_true_obs_reader::num_epochs() +int64_t tracking_true_obs_reader::num_epochs() { std::ifstream::pos_type size; int number_of_vars_in_epoch = 5; @@ -73,7 +73,7 @@ long int tracking_true_obs_reader::num_epochs() if (tmpfile.is_open()) { size = tmpfile.tellg(); - long int nepoch = size / epoch_size_bytes; + int64_t nepoch = size / epoch_size_bytes; return nepoch; } else diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h index 84bd2d7b0..5b8990325 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h @@ -31,6 +31,7 @@ #ifndef GNSS_SDR_TRACKING_TRUE_OBS_READER_H #define GNSS_SDR_TRACKING_TRUE_OBS_READER_H +#include #include #include #include @@ -41,7 +42,7 @@ public: ~tracking_true_obs_reader(); bool read_binary_obs(); bool restart(); - long int num_epochs(); + int64_t num_epochs(); bool open_obs_file(std::string out_file); void close_obs_file(); bool d_dump; diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc b/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc index b1f9d1d9b..f662f76dc 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc +++ b/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc @@ -38,7 +38,7 @@ bool true_observables_reader::read_binary_obs() for (int i = 0; i < 12; i++) { d_dump_file.read(reinterpret_cast(&gps_time_sec[i]), sizeof(double)); - d_dump_file.read(reinterpret_cast(&doppler_l1_hz), sizeof(double)); + d_dump_file.read(reinterpret_cast(&doppler_l1_hz[i]), sizeof(double)); d_dump_file.read(reinterpret_cast(&acc_carrier_phase_l1_cycles[i]), sizeof(double)); d_dump_file.read(reinterpret_cast(&dist_m[i]), sizeof(double)); d_dump_file.read(reinterpret_cast(&true_dist_m[i]), sizeof(double)); @@ -69,7 +69,7 @@ bool true_observables_reader::restart() } -long int true_observables_reader::num_epochs() +int64_t true_observables_reader::num_epochs() { std::ifstream::pos_type size; int number_of_vars_in_epoch = 6 * 12; @@ -78,7 +78,7 @@ long int true_observables_reader::num_epochs() if (tmpfile.is_open()) { size = tmpfile.tellg(); - long int nepoch = size / epoch_size_bytes; + int64_t nepoch = size / epoch_size_bytes; return nepoch; } else diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.h b/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.h index 41c04002a..86e1c868d 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.h +++ b/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.h @@ -31,6 +31,7 @@ #ifndef GNSS_SDR_TRUE_OBSERVABLES_READER_H #define GNSS_SDR_TRUE_OBSERVABLES_READER_H +#include #include #include #include @@ -41,7 +42,7 @@ public: ~true_observables_reader(); bool read_binary_obs(); bool restart(); - long int num_epochs(); + int64_t num_epochs(); bool open_obs_file(std::string out_file); double gps_time_sec[12]; diff --git a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc index f93f780cc..4883b3c60 100644 --- a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc @@ -39,15 +39,29 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include "GPS_L1_CA.h" #include "gnss_satellite.h" #include "gnss_block_factory.h" #include "gnss_block_interface.h" +#include "acquisition_msg_rx.h" +#include "gps_l1_ca_pcps_acquisition.h" +#include "galileo_e1_pcps_ambiguous_acquisition.h" +#include "galileo_e5a_pcps_acquisition.h" +#include "galileo_e5a_noncoherent_iq_acquisition_caf.h" +#include "glonass_l1_ca_pcps_acquisition.h" +#include "glonass_l2_ca_pcps_acquisition.h" +#include "gps_l2_m_pcps_acquisition.h" +#include "gps_l5i_pcps_acquisition.h" #include "tracking_interface.h" #include "telemetry_decoder_interface.h" #include "in_memory_configuration.h" #include "gnss_synchro.h" -#include "gps_l1_ca_telemetry_decoder.h" #include "tracking_true_obs_reader.h" #include "true_observables_reader.h" #include "tracking_dump_reader.h" @@ -57,7 +71,10 @@ #include "hybrid_observables.h" #include "signal_generator_flags.h" #include "gnss_sdr_sample_counter.h" -#include +#include "test_flags.h" +#include "tracking_tests_flags.h" +#include "observable_tests_flags.h" +#include "gnuplot_i.h" // ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES ######### @@ -88,7 +105,7 @@ void HybridObservablesTest_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast& e) @@ -141,7 +158,7 @@ void HybridObservablesTest_tlm_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast& e) @@ -175,6 +192,7 @@ public: std::string p3; std::string p4; std::string p5; + std::string implementation = FLAGS_trk_test_implementation; const int baseband_sampling_freq = FLAGS_fs_gen_sps; @@ -183,39 +201,75 @@ public: int configure_generator(); int generate_signal(); + bool save_mat_xy(std::vector& x, std::vector& y, std::string filename); void check_results_carrier_phase( arma::mat& true_ch0, - arma::mat& true_ch1, arma::vec& true_tow_s, arma::mat& measured_ch0, - arma::mat& measured_ch1); - void check_results_code_psudorange( + std::string data_title); + void check_results_carrier_phase_double_diff( arma::mat& true_ch0, arma::mat& true_ch1, + arma::vec& true_tow_ch0_s, + arma::vec& true_tow_ch1_s, + arma::mat& measured_ch0, + arma::mat& measured_ch1, + std::string data_title); + void check_results_carrier_doppler(arma::mat& true_ch0, arma::vec& true_tow_s, arma::mat& measured_ch0, - arma::mat& measured_ch1); + std::string data_title); + void check_results_carrier_doppler_double_diff( + arma::mat& true_ch0, + arma::mat& true_ch1, + arma::vec& true_tow_ch0_s, + arma::vec& true_tow_ch1_s, + arma::mat& measured_ch0, + arma::mat& measured_ch1, + std::string data_title); + void check_results_code_pseudorange( + arma::mat& true_ch0, + arma::mat& true_ch1, + arma::vec& true_tow_ch0_s, + arma::vec& true_tow_ch1_s, + arma::mat& measured_ch0, + arma::mat& measured_ch1, + std::string data_title); + + void check_results_duplicated_satellite( + arma::mat& measured_sat1, + arma::mat& measured_sat2, + int ch_id, + std::string data_title); HybridObservablesTest() { factory = std::make_shared(); config = std::make_shared(); item_size = sizeof(gr_complex); - gnss_synchro_ch0 = Gnss_Synchro(); - gnss_synchro_ch1 = Gnss_Synchro(); } ~HybridObservablesTest() { } - void configure_receiver(); + bool ReadRinexObs(std::vector* obs_vec, Gnss_Synchro gnss); + + bool acquire_signal(); + void configure_receiver( + double PLL_wide_bw_hz, + double DLL_wide_bw_hz, + double PLL_narrow_bw_hz, + double DLL_narrow_bw_hz, + int extend_correlation_symbols, + uint32_t smoother_length, + bool high_dyn); gr::top_block_sptr top_block; std::shared_ptr factory; std::shared_ptr config; - Gnss_Synchro gnss_synchro_ch0; - Gnss_Synchro gnss_synchro_ch1; + Gnss_Synchro gnss_synchro_master; + std::vector gnss_synchro_vec; size_t item_size; }; @@ -263,67 +317,382 @@ int HybridObservablesTest::generate_signal() } -void HybridObservablesTest::configure_receiver() +bool HybridObservablesTest::acquire_signal() { - gnss_synchro_ch0.Channel_ID = 0; - gnss_synchro_ch0.System = 'G'; - std::string signal = "1C"; - signal.copy(gnss_synchro_ch0.Signal, 2, 0); - gnss_synchro_ch0.PRN = FLAGS_test_satellite_PRN; + // 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m) + gr::top_block_sptr top_block; + top_block = gr::make_top_block("Acquisition test"); + int SV_ID = 1; //initial sv id + // Satellite signal definition + Gnss_Synchro tmp_gnss_synchro; + tmp_gnss_synchro.Channel_ID = 0; + config = std::make_shared(); + config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); + config->set_property("Acquisition.blocking_on_standby", "true"); + config->set_property("Acquisition.blocking", "true"); + config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition.dump_filename", "./data/acquisition.dat"); + config->set_property("Acquisition.use_CFAR_algorithm", "false"); - gnss_synchro_ch1.Channel_ID = 1; - gnss_synchro_ch1.System = 'G'; - signal.copy(gnss_synchro_ch1.Signal, 2, 0); - gnss_synchro_ch1.PRN = FLAGS_test_satellite_PRN2; + std::shared_ptr acquisition; + + std::string System_and_Signal; + //create the correspondign acquisition block according to the desired tracking signal + if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'G'; + std::string signal = "1C"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "GPS L1 CA"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + //acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0) + { + tmp_gnss_synchro.System = 'E'; + std::string signal = "1B"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "Galileo E1B"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'G'; + std::string signal = "2S"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "GPS L2CM"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + { + tmp_gnss_synchro.System = 'E'; + std::string signal = "5X"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "Galileo E5a"; + config->set_property("Acquisition_5X.coherent_integration_time_ms", "1"); + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + config->set_property("Acquisition.CAF_window_hz", "0"); // **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz + config->set_property("Acquisition.Zero_padding", "0"); //**Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF. + config->set_property("Acquisition.bit_transition_flag", "false"); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'E'; + std::string signal = "5X"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "Galileo E5a"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'G'; + std::string signal = "L5"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "GPS L5I"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else + { + std::cout << "The test can not run with the selected tracking implementation\n "; + throw(std::exception()); + } + + acquisition->set_gnss_synchro(&tmp_gnss_synchro); + acquisition->set_channel(0); + acquisition->set_doppler_max(config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz)); + acquisition->set_doppler_step(config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz)); + acquisition->set_threshold(config->property("Acquisition.threshold", FLAGS_external_signal_acquisition_threshold)); + acquisition->init(); + acquisition->set_local_code(); + acquisition->set_state(1); // Ensure that acquisition starts at the first sample + acquisition->connect(top_block); + + gr::blocks::file_source::sptr file_source; + std::string file = FLAGS_signal_file; + const char* file_name = file.c_str(); + file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); + file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample + gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); + //gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration); + + top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); + top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0); + //top_block->connect(head_samples, 0, acquisition->get_left_block(), 0); + + boost::shared_ptr msg_rx; + try + { + msg_rx = Acquisition_msg_rx_make(); + } + catch (const std::exception& e) + { + std::cout << "Failure connecting the message port system: " << e.what() << std::endl; + exit(0); + } + + msg_rx->top_block = top_block; + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + + // 5. Run the flowgraph + // Get visible GPS satellites (positive acquisitions with Doppler measurements) + // record startup time + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds; + start = std::chrono::system_clock::now(); + + bool start_msg = true; + + unsigned int MAX_PRN_IDX = 0; + + switch (tmp_gnss_synchro.System) + { + case 'G': + MAX_PRN_IDX = 33; + break; + case 'E': + MAX_PRN_IDX = 37; + break; + default: + MAX_PRN_IDX = 33; + } + + for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++) + { + tmp_gnss_synchro.PRN = PRN; + acquisition->set_gnss_synchro(&tmp_gnss_synchro); + acquisition->init(); + acquisition->set_local_code(); + acquisition->reset(); + acquisition->set_state(1); + msg_rx->rx_message = 0; + top_block->run(); + if (start_msg == true) + { + std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl; + std::cout << "Searching for " << System_and_Signal << " Satellites..." << std::endl; + std::cout << "["; + start_msg = false; + } + while (msg_rx->rx_message == 0) + { + usleep(100000); + } + if (msg_rx->rx_message == 1) + { + std::cout << " " << PRN << " "; + gnss_synchro_vec.push_back(tmp_gnss_synchro); + } + else + { + std::cout << " . "; + } + top_block->stop(); + file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample + std::cout.flush(); + } + std::cout << "]" << std::endl; + std::cout << "-------------------------------------------\n"; + + for (auto& x : gnss_synchro_vec) + { + std::cout << "DETECTED SATELLITE " << System_and_Signal + << " PRN: " << x.PRN + << " with Doppler: " << x.Acq_doppler_hz + << " [Hz], code phase: " << x.Acq_delay_samples + << " [samples] at signal SampleStamp " << x.Acq_samplestamp_samples << "\n"; + } + + // report the elapsed time + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + std::cout << "Total signal acquisition run time " + << elapsed_seconds.count() + << " [seconds]" << std::endl; + if (gnss_synchro_vec.size() > 0) + { + return true; + } + else + { + return false; + } +} +void HybridObservablesTest::configure_receiver( + double PLL_wide_bw_hz, + double DLL_wide_bw_hz, + double PLL_narrow_bw_hz, + double DLL_narrow_bw_hz, + int extend_correlation_symbols, + uint32_t smoother_length, + bool high_dyn) +{ + config = std::make_shared(); + config->set_property("Tracking.dump", "true"); + if (high_dyn) + config->set_property("Tracking.high_dyn", "true"); + else + config->set_property("Tracking.high_dyn", "false"); + config->set_property("Tracking.smoother_length", std::to_string(smoother_length)); + config->set_property("Tracking.dump_filename", "./tracking_ch_"); + config->set_property("Tracking.implementation", implementation); + config->set_property("Tracking.item_type", "gr_complex"); + config->set_property("Tracking.pll_bw_hz", std::to_string(PLL_wide_bw_hz)); + config->set_property("Tracking.dll_bw_hz", std::to_string(DLL_wide_bw_hz)); + config->set_property("Tracking.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); + config->set_property("Tracking.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); + config->set_property("Tracking.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); + config->set_property("Observables.implementation", "Hybrid_Observables"); + config->set_property("Observables.dump", "true"); + config->set_property("TelemetryDecoder.dump", "true"); + + gnss_synchro_master.Channel_ID = 0; config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); - // Set Tracking - config->set_property("Tracking_1C.item_type", "gr_complex"); - config->set_property("Tracking_1C.dump", "true"); - config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); - config->set_property("Tracking_1C.pll_bw_hz", "35.0"); - config->set_property("Tracking_1C.dll_bw_hz", "0.5"); - config->set_property("Tracking_1C.early_late_space_chips", "0.5"); - config->set_property("Tracking_1C.unified", "true"); + std::string System_and_Signal; + if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0) + { + gnss_synchro_master.System = 'G'; + std::string signal = "1C"; + System_and_Signal = "GPS L1 CA"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(gnss_synchro_master.Signal), str, 3); // copy string into synchro char array: 2 char + null - config->set_property("TelemetryDecoder_1C.dump", "true"); - config->set_property("Observables.dump", "true"); + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.early_late_space_narrow_chips", "0.5"); + + config->set_property("TelemetryDecoder.implementation", "GPS_L1_CA_Telemetry_Decoder"); + } + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0) + { + gnss_synchro_master.System = 'E'; + std::string signal = "1B"; + System_and_Signal = "Galileo E1B"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(gnss_synchro_master.Signal), str, 3); // copy string into synchro char array: 2 char + null + + config->set_property("Tracking.early_late_space_chips", "0.15"); + config->set_property("Tracking.very_early_late_space_chips", "0.6"); + config->set_property("Tracking.early_late_space_narrow_chips", "0.15"); + config->set_property("Tracking.very_early_late_space_narrow_chips", "0.6"); + config->set_property("Tracking.track_pilot", "true"); + + config->set_property("TelemetryDecoder.implementation", "Galileo_E1B_Telemetry_Decoder"); + } + else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0) + { + gnss_synchro_master.System = 'G'; + std::string signal = "2S"; + System_and_Signal = "GPS L2CM"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(gnss_synchro_master.Signal), str, 3); // copy string into synchro char array: 2 char + null + + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.track_pilot", "true"); + + config->set_property("TelemetryDecoder.implementation", "GPS_L2C_Telemetry_Decoder"); + } + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0 or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + { + gnss_synchro_master.System = 'E'; + std::string signal = "5X"; + System_and_Signal = "Galileo E5a"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(gnss_synchro_master.Signal), str, 3); // copy string into synchro char array: 2 char + null + + if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + { + config->supersede_property("Tracking.implementation", std::string("Galileo_E5a_DLL_PLL_Tracking")); + } + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.track_pilot", "true"); + config->set_property("Tracking.order", "2"); + + config->set_property("TelemetryDecoder.implementation", "Galileo_E5a_Telemetry_Decoder"); + } + else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0) + { + gnss_synchro_master.System = 'G'; + std::string signal = "L5"; + System_and_Signal = "GPS L5I"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(gnss_synchro_master.Signal), str, 3); // copy string into synchro char array: 2 char + null + + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.track_pilot", "true"); + config->set_property("Tracking.order", "2"); + + config->set_property("TelemetryDecoder.implementation", "GPS_L5_Telemetry_Decoder"); + } + else + { + std::cout << "The test can not run with the selected tracking implementation\n "; + throw(std::exception()); + } + + std::cout << "*****************************************\n"; + std::cout << "*** Tracking configuration parameters ***\n"; + std::cout << "*****************************************\n"; + std::cout << "Signal: " << System_and_Signal << "\n"; + std::cout << "implementation: " << config->property("Tracking.implementation", std::string("undefined")) << " \n"; + std::cout << "pll_bw_hz: " << config->property("Tracking.pll_bw_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_hz: " << config->property("Tracking.dll_bw_hz", 0.0) << " Hz\n"; + std::cout << "pll_bw_narrow_hz: " << config->property("Tracking.pll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_narrow_hz: " << config->property("Tracking.dll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "extend_correlation_symbols: " << config->property("Tracking.extend_correlation_symbols", 0) << " Symbols\n"; + std::cout << "high_dyn: " << config->property("Tracking.high_dyn", false) << "\n"; + std::cout << "smoother_length: " << config->property("Tracking.smoother_length", 0) << "\n"; + std::cout << "*****************************************\n"; + std::cout << "*****************************************\n"; } void HybridObservablesTest::check_results_carrier_phase( arma::mat& true_ch0, - arma::mat& true_ch1, arma::vec& true_tow_s, arma::mat& measured_ch0, - arma::mat& measured_ch1) + std::string data_title) { //1. True value interpolation to match the measurement times - double t0 = std::max(measured_ch0(0, 0), measured_ch1(0, 0)); + double t0 = measured_ch0(0, 0); int size1 = measured_ch0.col(0).n_rows; - int size2 = measured_ch1.col(0).n_rows; - double t1 = std::min(measured_ch0(size1 - 1, 0), measured_ch1(size2 - 1, 0)); + double t1 = measured_ch0(size1 - 1, 0); arma::vec t = arma::linspace(t0, t1, floor((t1 - t0) * 1e3)); + //conversion between arma::vec and std:vector + arma::vec t_from_start = arma::linspace(0, t1 - t0, floor((t1 - t0) * 1e3)); + std::vector time_vector(t_from_start.colptr(0), t_from_start.colptr(0) + t_from_start.n_rows); arma::vec true_ch0_phase_interp; - arma::vec true_ch1_phase_interp; arma::interp1(true_tow_s, true_ch0.col(3), t, true_ch0_phase_interp); - arma::interp1(true_tow_s, true_ch1.col(3), t, true_ch1_phase_interp); arma::vec meas_ch0_phase_interp; - arma::vec meas_ch1_phase_interp; arma::interp1(measured_ch0.col(0), measured_ch0.col(3), t, meas_ch0_phase_interp); - arma::interp1(measured_ch1.col(0), measured_ch1.col(3), t, meas_ch1_phase_interp); //2. RMSE arma::vec err_ch0_cycles; - arma::vec err_ch1_cycles; //compute error without the accumulated carrier phase offsets (which depends on the receiver starting time) err_ch0_cycles = meas_ch0_phase_interp - true_ch0_phase_interp - meas_ch0_phase_interp(0) + true_ch0_phase_interp(0); - err_ch1_cycles = meas_ch1_phase_interp - true_ch1_phase_interp - meas_ch1_phase_interp(0) + true_ch1_phase_interp(0); arma::vec err2_ch0 = arma::square(err_ch0_cycles); double rmse_ch0 = sqrt(arma::mean(err2_ch0)); @@ -336,21 +705,9 @@ void HybridObservablesTest::check_results_carrier_phase( double max_error_ch0 = arma::max(err_ch0_cycles); double min_error_ch0 = arma::min(err_ch0_cycles); - arma::vec err2_ch1 = arma::square(err_ch1_cycles); - double rmse_ch1 = sqrt(arma::mean(err2_ch1)); - - //3. Mean err and variance - double error_mean_ch1 = arma::mean(err_ch1_cycles); - double error_var_ch1 = arma::var(err_ch1_cycles); - - // 4. Peaks - double max_error_ch1 = arma::max(err_ch1_cycles); - double min_error_ch1 = arma::min(err_ch1_cycles); - - //5. report std::streamsize ss = std::cout.precision(); - std::cout << std::setprecision(10) << "Channel 0 Carrier phase RMSE = " + std::cout << std::setprecision(10) << data_title << " Accumulated Carrier phase RMSE = " << rmse_ch0 << ", mean = " << error_mean_ch0 << ", stdev = " << sqrt(error_var_ch0) << " (max,min) = " << max_error_ch0 @@ -358,38 +715,43 @@ void HybridObservablesTest::check_results_carrier_phase( << " [cycles]" << std::endl; std::cout.precision(ss); - ASSERT_LT(rmse_ch0, 5e-2); - ASSERT_LT(error_mean_ch0, 5e-2); - ASSERT_GT(error_mean_ch0, -5e-2); - ASSERT_LT(error_var_ch0, 5e-2); - ASSERT_LT(max_error_ch0, 5e-2); - ASSERT_GT(min_error_ch0, -5e-2); + //plots + if (FLAGS_show_plots) + { + Gnuplot g3("linespoints"); + g3.set_title(data_title + "Accumulated Carrier phase error [cycles]"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Carrier Phase error [cycles]"); + //conversion between arma::vec and std:vector + std::vector error_vec(err_ch0_cycles.colptr(0), err_ch0_cycles.colptr(0) + err_ch0_cycles.n_rows); + g3.cmd("set key box opaque"); + g3.plot_xy(time_vector, error_vec, + "Carrier Phase error"); + g3.set_legend(); + g3.savetops(data_title + "Carrier_phase_error"); - //5. report - ss = std::cout.precision(); - std::cout << std::setprecision(10) << "Channel 1 Carrier phase RMSE = " - << rmse_ch1 << ", mean = " << error_mean_ch1 - << ", stdev = " << sqrt(error_var_ch1) - << " (max,min) = " << max_error_ch1 - << "," << min_error_ch1 - << " [cycles]" << std::endl; - std::cout.precision(ss); + g3.showonscreen(); // window output + } - ASSERT_LT(rmse_ch1, 5e-2); - ASSERT_LT(error_mean_ch1, 5e-2); - ASSERT_GT(error_mean_ch1, -5e-2); - ASSERT_LT(error_var_ch1, 5e-2); - ASSERT_LT(max_error_ch1, 5e-2); - ASSERT_GT(min_error_ch1, -5e-2); + //check results against the test tolerance + ASSERT_LT(rmse_ch0, 0.25); + ASSERT_LT(error_mean_ch0, 0.2); + ASSERT_GT(error_mean_ch0, -0.2); + ASSERT_LT(error_var_ch0, 0.5); + ASSERT_LT(max_error_ch0, 0.5); + ASSERT_GT(min_error_ch0, -0.5); } -void HybridObservablesTest::check_results_code_psudorange( +void HybridObservablesTest::check_results_carrier_phase_double_diff( arma::mat& true_ch0, arma::mat& true_ch1, - arma::vec& true_tow_s, + arma::vec& true_tow_ch0_s, + arma::vec& true_tow_ch1_s, arma::mat& measured_ch0, - arma::mat& measured_ch1) + arma::mat& measured_ch1, + std::string data_title) { //1. True value interpolation to match the measurement times @@ -397,12 +759,562 @@ void HybridObservablesTest::check_results_code_psudorange( int size1 = measured_ch0.col(0).n_rows; int size2 = measured_ch1.col(0).n_rows; double t1 = std::min(measured_ch0(size1 - 1, 0), measured_ch1(size2 - 1, 0)); + arma::vec t = arma::linspace(t0, t1, floor((t1 - t0) * 1e3)); + //conversion between arma::vec and std:vector + arma::vec t_from_start = arma::linspace(0, t1 - t0, floor((t1 - t0) * 1e3)); + std::vector time_vector(t_from_start.colptr(0), t_from_start.colptr(0) + t_from_start.n_rows); + + + arma::vec true_ch0_carrier_phase_interp; + arma::vec true_ch1_carrier_phase_interp; + arma::interp1(true_tow_ch0_s, true_ch0.col(3), t, true_ch0_carrier_phase_interp); + arma::interp1(true_tow_ch1_s, true_ch1.col(3), t, true_ch1_carrier_phase_interp); + + arma::vec meas_ch0_carrier_phase_interp; + arma::vec meas_ch1_carrier_phase_interp; + arma::interp1(measured_ch0.col(0), measured_ch0.col(3), t, meas_ch0_carrier_phase_interp); + arma::interp1(measured_ch1.col(0), measured_ch1.col(3), t, meas_ch1_carrier_phase_interp); + + // generate double difference accumulated carrier phases + //compute error without the accumulated carrier phase offsets (which depends on the receiver starting time) + arma::vec delta_true_carrier_phase_cycles = (true_ch0_carrier_phase_interp - true_ch0_carrier_phase_interp(0)) - (true_ch1_carrier_phase_interp - true_ch1_carrier_phase_interp(0)); + arma::vec delta_measured_carrier_phase_cycles = (meas_ch0_carrier_phase_interp - meas_ch0_carrier_phase_interp(0)) - (meas_ch1_carrier_phase_interp - meas_ch1_carrier_phase_interp(0)); + + //2. RMSE + arma::vec err; + + err = delta_measured_carrier_phase_cycles - delta_true_carrier_phase_cycles; + arma::vec err2 = arma::square(err); + double rmse = sqrt(arma::mean(err2)); + + //3. Mean err and variance + double error_mean = arma::mean(err); + double error_var = arma::var(err); + + // 4. Peaks + double max_error = arma::max(err); + double min_error = arma::min(err); + + //5. report + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(10) << data_title << "Double diff Carrier Phase RMSE = " + << rmse << ", mean = " << error_mean + << ", stdev = " << sqrt(error_var) + << " (max,min) = " << max_error + << "," << min_error + << " [Cycles]" << std::endl; + std::cout.precision(ss); + + //plots + if (FLAGS_show_plots) + { + Gnuplot g3("linespoints"); + g3.set_title(data_title + "Double diff Carrier Phase error [Cycles]"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Double diff Carrier Phase error [Cycles]"); + //conversion between arma::vec and std:vector + std::vector range_error_m(err.colptr(0), err.colptr(0) + err.n_rows); + g3.cmd("set key box opaque"); + g3.plot_xy(time_vector, range_error_m, + "Double diff Carrier Phase error"); + g3.set_legend(); + g3.savetops(data_title + "double_diff_carrier_phase_error"); + + g3.showonscreen(); // window output + } + + //check results against the test tolerance + ASSERT_LT(rmse, 0.25); + ASSERT_LT(error_mean, 0.2); + ASSERT_GT(error_mean, -0.2); + ASSERT_LT(error_var, 0.5); + ASSERT_LT(max_error, 0.5); + ASSERT_GT(min_error, -0.5); +} + + +void HybridObservablesTest::check_results_carrier_doppler_double_diff( + arma::mat& true_ch0, + arma::mat& true_ch1, + arma::vec& true_tow_ch0_s, + arma::vec& true_tow_ch1_s, + arma::mat& measured_ch0, + arma::mat& measured_ch1, + std::string data_title) +{ + //1. True value interpolation to match the measurement times + + double t0 = std::max(measured_ch0(0, 0), measured_ch1(0, 0)); + int size1 = measured_ch0.col(0).n_rows; + int size2 = measured_ch1.col(0).n_rows; + double t1 = std::min(measured_ch0(size1 - 1, 0), measured_ch1(size2 - 1, 0)); + + arma::vec t = arma::linspace(t0, t1, floor((t1 - t0) * 1e3)); + //conversion between arma::vec and std:vector + arma::vec t_from_start = arma::linspace(0, t1 - t0, floor((t1 - t0) * 1e3)); + std::vector time_vector(t_from_start.colptr(0), t_from_start.colptr(0) + t_from_start.n_rows); + + + arma::vec true_ch0_carrier_doppler_interp; + arma::vec true_ch1_carrier_doppler_interp; + arma::interp1(true_tow_ch0_s, true_ch0.col(2), t, true_ch0_carrier_doppler_interp); + arma::interp1(true_tow_ch1_s, true_ch1.col(2), t, true_ch1_carrier_doppler_interp); + + arma::vec meas_ch0_carrier_doppler_interp; + arma::vec meas_ch1_carrier_doppler_interp; + arma::interp1(measured_ch0.col(0), measured_ch0.col(2), t, meas_ch0_carrier_doppler_interp); + arma::interp1(measured_ch1.col(0), measured_ch1.col(2), t, meas_ch1_carrier_doppler_interp); + + // generate double difference carrier Doppler + arma::vec delta_true_carrier_doppler_cycles = true_ch0_carrier_doppler_interp - true_ch1_carrier_doppler_interp; + arma::vec delta_measured_carrier_doppler_cycles = meas_ch0_carrier_doppler_interp - meas_ch1_carrier_doppler_interp; + + //2. RMSE + arma::vec err; + + err = delta_measured_carrier_doppler_cycles - delta_true_carrier_doppler_cycles; + arma::vec err2 = arma::square(err); + double rmse = sqrt(arma::mean(err2)); + + //3. Mean err and variance + double error_mean = arma::mean(err); + double error_var = arma::var(err); + + // 4. Peaks + double max_error = arma::max(err); + double min_error = arma::min(err); + + //5. report + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(10) << data_title << "Double diff Carrier Doppler RMSE = " + << rmse << ", mean = " << error_mean + << ", stdev = " << sqrt(error_var) + << " (max,min) = " << max_error + << "," << min_error + << " [Hz]" << std::endl; + std::cout.precision(ss); + + //plots + if (FLAGS_show_plots) + { + Gnuplot g3("linespoints"); + g3.set_title(data_title + "Double diff Carrier Doppler error [Hz]"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Double diff Carrier Doppler error [Hz]"); + //conversion between arma::vec and std:vector + std::vector range_error_m(err.colptr(0), err.colptr(0) + err.n_rows); + g3.cmd("set key box opaque"); + g3.plot_xy(time_vector, range_error_m, + "Double diff Carrier Doppler error"); + g3.set_legend(); + g3.savetops(data_title + "double_diff_carrier_doppler_error"); + + g3.showonscreen(); // window output + } + + //check results against the test tolerance + ASSERT_LT(error_mean, 5); + ASSERT_GT(error_mean, -5); + //assuming PLL BW=35 + ASSERT_LT(error_var, 250); + ASSERT_LT(max_error, 100); + ASSERT_GT(min_error, -100); + ASSERT_LT(rmse, 30); +} + + +void HybridObservablesTest::check_results_carrier_doppler( + arma::mat& true_ch0, + arma::vec& true_tow_s, + arma::mat& measured_ch0, + std::string data_title) +{ + //1. True value interpolation to match the measurement times + + double t0 = measured_ch0(0, 0); + int size1 = measured_ch0.col(0).n_rows; + double t1 = measured_ch0(size1 - 1, 0); + arma::vec t = arma::linspace(t0, t1, floor((t1 - t0) * 1e3)); + //conversion between arma::vec and std:vector + arma::vec t_from_start = arma::linspace(0, t1 - t0, floor((t1 - t0) * 1e3)); + std::vector time_vector(t_from_start.colptr(0), t_from_start.colptr(0) + t_from_start.n_rows); + + arma::vec true_ch0_doppler_interp; + arma::interp1(true_tow_s, true_ch0.col(2), t, true_ch0_doppler_interp); + + arma::vec meas_ch0_doppler_interp; + arma::interp1(measured_ch0.col(0), measured_ch0.col(2), t, meas_ch0_doppler_interp); + + //2. RMSE + arma::vec err_ch0_hz; + + //compute error + err_ch0_hz = meas_ch0_doppler_interp - true_ch0_doppler_interp; + + arma::vec err2_ch0 = arma::square(err_ch0_hz); + double rmse_ch0 = sqrt(arma::mean(err2_ch0)); + + //3. Mean err and variance + double error_mean_ch0 = arma::mean(err_ch0_hz); + double error_var_ch0 = arma::var(err_ch0_hz); + + // 4. Peaks + double max_error_ch0 = arma::max(err_ch0_hz); + double min_error_ch0 = arma::min(err_ch0_hz); + + //5. report + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(10) << data_title << "Carrier Doppler RMSE = " + << rmse_ch0 << ", mean = " << error_mean_ch0 + << ", stdev = " << sqrt(error_var_ch0) + << " (max,min) = " << max_error_ch0 + << "," << min_error_ch0 + << " [Hz]" << std::endl; + std::cout.precision(ss); + + //plots + if (FLAGS_show_plots) + { + Gnuplot g3("linespoints"); + g3.set_title(data_title + "Carrier Doppler error [Hz]"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Carrier Doppler error [Hz]"); + //conversion between arma::vec and std:vector + std::vector error_vec(err_ch0_hz.colptr(0), err_ch0_hz.colptr(0) + err_ch0_hz.n_rows); + g3.cmd("set key box opaque"); + g3.plot_xy(time_vector, error_vec, + "Carrier Doppler error"); + g3.set_legend(); + g3.savetops(data_title + "Carrier_doppler_error"); + + g3.showonscreen(); // window output + } + + //check results against the test tolerance + ASSERT_LT(error_mean_ch0, 5); + ASSERT_GT(error_mean_ch0, -5); + //assuming PLL BW=35 + ASSERT_LT(error_var_ch0, 250); + ASSERT_LT(max_error_ch0, 100); + ASSERT_GT(min_error_ch0, -100); + ASSERT_LT(rmse_ch0, 30); +} + +void HybridObservablesTest::check_results_duplicated_satellite( + arma::mat& measured_sat1, + arma::mat& measured_sat2, + int ch_id, + std::string data_title) +{ + //1. True value interpolation to match the measurement times + + //define the common measured time interval + double t0_sat1 = measured_sat1(0, 0); + int size1 = measured_sat1.col(0).n_rows; + double t1_sat1 = measured_sat1(size1 - 1, 0); + + double t0_sat2 = measured_sat2(0, 0); + int size2 = measured_sat2.col(0).n_rows; + double t1_sat2 = measured_sat2(size2 - 1, 0); + + double t0; + double t1; + if (t0_sat1 > t0_sat2) + { + t0 = t0_sat1; + } + else + { + t0 = t0_sat2; + } + + if (t1_sat1 > t1_sat2) + { + t1 = t1_sat2; + } + else + { + t1 = t1_sat1; + } + + arma::vec t = arma::linspace(t0, t1, floor((t1 - t0) * 1e3)); + //conversion between arma::vec and std:vector + arma::vec t_from_start = arma::linspace(0, t1 - t0, floor((t1 - t0) * 1e3)); + std::vector time_vector(t_from_start.colptr(0), t_from_start.colptr(0) + t_from_start.n_rows); + //Doppler + arma::vec meas_sat1_doppler_interp; + arma::interp1(measured_sat1.col(0), measured_sat1.col(2), t, meas_sat1_doppler_interp); + arma::vec meas_sat2_doppler_interp; + arma::interp1(measured_sat2.col(0), measured_sat2.col(2), t, meas_sat2_doppler_interp); + + //Carrier Phase + arma::vec meas_sat1_carrier_phase_interp; + arma::vec meas_sat2_carrier_phase_interp; + arma::interp1(measured_sat1.col(0), measured_sat1.col(3), t, meas_sat1_carrier_phase_interp); + arma::interp1(measured_sat2.col(0), measured_sat2.col(3), t, meas_sat2_carrier_phase_interp); + + // generate double difference accumulated carrier phases + //compute error without the accumulated carrier phase offsets (which depends on the receiver starting time) + arma::vec delta_measured_carrier_phase_cycles = (meas_sat1_carrier_phase_interp - meas_sat1_carrier_phase_interp(0)) - (meas_sat2_carrier_phase_interp - meas_sat2_carrier_phase_interp(0)); + + //Pseudoranges + arma::vec meas_sat1_dist_interp; + arma::vec meas_sat2_dist_interp; + arma::interp1(measured_sat1.col(0), measured_sat1.col(4), t, meas_sat1_dist_interp); + arma::interp1(measured_sat2.col(0), measured_sat2.col(4), t, meas_sat2_dist_interp); + // generate delta pseudoranges + arma::vec delta_measured_dist_m = meas_sat1_dist_interp - meas_sat2_dist_interp; + + //Carrier Doppler error + //2. RMSE + arma::vec err_ch0_hz; + + //compute error + err_ch0_hz = meas_sat1_doppler_interp - meas_sat2_doppler_interp; + + //save matlab file for further analysis + std::vector tmp_vector_common_time_s(t.colptr(0), + t.colptr(0) + t.n_rows); + + std::vector tmp_vector_err_ch0_hz(err_ch0_hz.colptr(0), + err_ch0_hz.colptr(0) + err_ch0_hz.n_rows); + save_mat_xy(tmp_vector_common_time_s, tmp_vector_err_ch0_hz, std::string("measured_doppler_error_ch_" + std::to_string(ch_id))); + + //compute statistics + arma::vec err2_ch0 = arma::square(err_ch0_hz); + double rmse_ch0 = sqrt(arma::mean(err2_ch0)); + + //3. Mean err and variance + double error_mean_ch0 = arma::mean(err_ch0_hz); + double error_var_ch0 = arma::var(err_ch0_hz); + + // 4. Peaks + double max_error_ch0 = arma::max(err_ch0_hz); + double min_error_ch0 = arma::min(err_ch0_hz); + + //5. report + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(10) << data_title << "Carrier Doppler RMSE = " + << rmse_ch0 << ", mean = " << error_mean_ch0 + << ", stdev = " << sqrt(error_var_ch0) + << " (max,min) = " << max_error_ch0 + << "," << min_error_ch0 + << " [Hz]" << std::endl; + std::cout.precision(ss); + + //plots + if (FLAGS_show_plots) + { + Gnuplot g3("linespoints"); + g3.set_title(data_title + "Carrier Doppler error [Hz]"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Carrier Doppler error [Hz]"); + //conversion between arma::vec and std:vector + std::vector error_vec(err_ch0_hz.colptr(0), err_ch0_hz.colptr(0) + err_ch0_hz.n_rows); + g3.cmd("set key box opaque"); + g3.plot_xy(time_vector, error_vec, + "Carrier Doppler error"); + g3.set_legend(); + g3.savetops(data_title + "Carrier_doppler_error"); + + g3.showonscreen(); // window output + } + + //check results against the test tolerance + EXPECT_LT(error_mean_ch0, 5); + EXPECT_GT(error_mean_ch0, -5); + //assuming PLL BW=35 + EXPECT_LT(error_var_ch0, 250); + EXPECT_LT(max_error_ch0, 100); + EXPECT_GT(min_error_ch0, -100); + EXPECT_LT(rmse_ch0, 30); + + //Carrier Phase error + //2. RMSE + arma::vec err_carrier_phase; + + err_carrier_phase = delta_measured_carrier_phase_cycles; + + //save matlab file for further analysis + std::vector tmp_vector_err_carrier_phase(err_carrier_phase.colptr(0), + err_carrier_phase.colptr(0) + err_carrier_phase.n_rows); + save_mat_xy(tmp_vector_common_time_s, tmp_vector_err_carrier_phase, std::string("measured_carrier_phase_error_ch_" + std::to_string(ch_id))); + + + arma::vec err2_carrier_phase = arma::square(err_carrier_phase); + double rmse_carrier_phase = sqrt(arma::mean(err2_carrier_phase)); + + //3. Mean err and variance + double error_mean_carrier_phase = arma::mean(err_carrier_phase); + double error_var_carrier_phase = arma::var(err_carrier_phase); + + // 4. Peaks + double max_error_carrier_phase = arma::max(err_carrier_phase); + double min_error_carrier_phase = arma::min(err_carrier_phase); + + //5. report + ss = std::cout.precision(); + std::cout << std::setprecision(10) << data_title << "Carrier Phase RMSE = " + << rmse_carrier_phase << ", mean = " << error_mean_carrier_phase + << ", stdev = " << sqrt(error_var_carrier_phase) + << " (max,min) = " << max_error_carrier_phase + << "," << min_error_carrier_phase + << " [Cycles]" << std::endl; + std::cout.precision(ss); + + //plots + if (FLAGS_show_plots) + { + Gnuplot g3("linespoints"); + g3.set_title(data_title + "Carrier Phase error [Cycles]"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Carrier Phase error [Cycles]"); + //conversion between arma::vec and std:vector + std::vector range_error_m(err_carrier_phase.colptr(0), err_carrier_phase.colptr(0) + err_carrier_phase.n_rows); + g3.cmd("set key box opaque"); + g3.plot_xy(time_vector, range_error_m, + "Carrier Phase error"); + g3.set_legend(); + g3.savetops(data_title + "duplicated_satellite_carrier_phase_error"); + + g3.showonscreen(); // window output + } + + //check results against the test tolerance + EXPECT_LT(rmse_carrier_phase, 0.25); + EXPECT_LT(error_mean_carrier_phase, 0.2); + EXPECT_GT(error_mean_carrier_phase, -0.2); + EXPECT_LT(error_var_carrier_phase, 0.5); + EXPECT_LT(max_error_carrier_phase, 0.5); + EXPECT_GT(min_error_carrier_phase, -0.5); + + //Pseudorange error + //2. RMSE + arma::vec err_pseudorange; + + err_pseudorange = delta_measured_dist_m; + + //save matlab file for further analysis + std::vector tmp_vector_err_pseudorange(err_pseudorange.colptr(0), + err_pseudorange.colptr(0) + err_pseudorange.n_rows); + save_mat_xy(tmp_vector_common_time_s, tmp_vector_err_pseudorange, std::string("measured_pr_error_ch_" + std::to_string(ch_id))); + + arma::vec err2_pseudorange = arma::square(err_pseudorange); + double rmse_pseudorange = sqrt(arma::mean(err2_pseudorange)); + + //3. Mean err and variance + double error_mean_pseudorange = arma::mean(err_pseudorange); + double error_var_pseudorange = arma::var(err_pseudorange); + + // 4. Peaks + double max_error_pseudorange = arma::max(err_pseudorange); + double min_error_pseudorange = arma::min(err_pseudorange); + + //5. report + ss = std::cout.precision(); + std::cout << std::setprecision(10) << data_title << "Pseudorange RMSE = " + << rmse_pseudorange << ", mean = " << error_mean_pseudorange + << ", stdev = " << sqrt(error_var_pseudorange) + << " (max,min) = " << max_error_pseudorange + << "," << min_error_pseudorange + << " [meters]" << std::endl; + std::cout.precision(ss); + + //plots + if (FLAGS_show_plots) + { + Gnuplot g3("linespoints"); + g3.set_title(data_title + "Pseudorange error [m]"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Pseudorange error [m]"); + //conversion between arma::vec and std:vector + std::vector range_error_m(err_pseudorange.colptr(0), err_pseudorange.colptr(0) + err_pseudorange.n_rows); + g3.cmd("set key box opaque"); + g3.plot_xy(time_vector, range_error_m, + "Pseudorrange error"); + g3.set_legend(); + g3.savetops(data_title + "duplicated_satellite_pseudorrange_error"); + + g3.showonscreen(); // window output + } + + //check results against the test tolerance + EXPECT_LT(rmse_pseudorange, 3.0); + EXPECT_LT(error_mean_pseudorange, 1.0); + EXPECT_GT(error_mean_pseudorange, -1.0); + EXPECT_LT(error_var_pseudorange, 10.0); + EXPECT_LT(max_error_pseudorange, 10.0); + EXPECT_GT(min_error_pseudorange, -10.0); +} + +bool HybridObservablesTest::save_mat_xy(std::vector& x, std::vector& y, std::string filename) +{ + try + { + // WRITE MAT FILE + mat_t* matfp; + matvar_t* matvar; + filename.append(".mat"); + std::cout << "save_mat_xy write " << filename << std::endl; + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT5); + if (reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, x.size()}; + matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &y[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + else + { + std::cout << "save_mat_xy: error creating file" << std::endl; + } + Mat_Close(matfp); + return true; + } + catch (const std::exception& ex) + { + std::cout << "save_mat_xy: " << ex.what() << std::endl; + return false; + } +} + +void HybridObservablesTest::check_results_code_pseudorange( + arma::mat& true_ch0, + arma::mat& true_ch1, + arma::vec& true_tow_ch0_s, + arma::vec& true_tow_ch1_s, + arma::mat& measured_ch0, + arma::mat& measured_ch1, + std::string data_title) +{ + //1. True value interpolation to match the measurement times + + double t0 = std::max(measured_ch0(0, 0), measured_ch1(0, 0)); + int size1 = measured_ch0.col(0).n_rows; + int size2 = measured_ch1.col(0).n_rows; + double t1 = std::min(measured_ch0(size1 - 1, 0), measured_ch1(size2 - 1, 0)); + + arma::vec t = arma::linspace(t0, t1, floor((t1 - t0) * 1e3)); + //conversion between arma::vec and std:vector + arma::vec t_from_start = arma::linspace(0, t1 - t0, floor((t1 - t0) * 1e3)); + std::vector time_vector(t_from_start.colptr(0), t_from_start.colptr(0) + t_from_start.n_rows); + arma::vec true_ch0_dist_interp; arma::vec true_ch1_dist_interp; - arma::interp1(true_tow_s, true_ch0.col(1), t, true_ch0_dist_interp); - arma::interp1(true_tow_s, true_ch1.col(1), t, true_ch1_dist_interp); + arma::interp1(true_tow_ch0_s, true_ch0.col(1), t, true_ch0_dist_interp); + arma::interp1(true_tow_ch1_s, true_ch1.col(1), t, true_ch1_dist_interp); arma::vec meas_ch0_dist_interp; arma::vec meas_ch1_dist_interp; @@ -430,7 +1342,7 @@ void HybridObservablesTest::check_results_code_psudorange( //5. report std::streamsize ss = std::cout.precision(); - std::cout << std::setprecision(10) << "Delta Observables RMSE = " + std::cout << std::setprecision(10) << data_title << "Double diff Pseudorange RMSE = " << rmse << ", mean = " << error_mean << ", stdev = " << sqrt(error_var) << " (max,min) = " << max_error @@ -438,15 +1350,174 @@ void HybridObservablesTest::check_results_code_psudorange( << " [meters]" << std::endl; std::cout.precision(ss); - ASSERT_LT(rmse, 0.5); - ASSERT_LT(error_mean, 0.5); - ASSERT_GT(error_mean, -0.5); - ASSERT_LT(error_var, 0.5); - ASSERT_LT(max_error, 2.0); - ASSERT_GT(min_error, -2.0); + //plots + if (FLAGS_show_plots) + { + Gnuplot g3("linespoints"); + g3.set_title(data_title + "Double diff Pseudorange error [m]"); + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Double diff Pseudorange error [m]"); + //conversion between arma::vec and std:vector + std::vector range_error_m(err.colptr(0), err.colptr(0) + err.n_rows); + g3.cmd("set key box opaque"); + g3.plot_xy(time_vector, range_error_m, + "Double diff Pseudorrange error"); + g3.set_legend(); + g3.savetops(data_title + "double_diff_pseudorrange_error"); + + g3.showonscreen(); // window output + } + + //check results against the test tolerance + ASSERT_LT(rmse, 3.0); + ASSERT_LT(error_mean, 1.0); + ASSERT_GT(error_mean, -1.0); + ASSERT_LT(error_var, 10.0); + ASSERT_LT(max_error, 10.0); + ASSERT_GT(min_error, -10.0); } +bool HybridObservablesTest::ReadRinexObs(std::vector* obs_vec, Gnss_Synchro gnss) +{ + // Open and read reference RINEX observables file + try + { + gpstk::Rinex3ObsStream r_ref(FLAGS_filename_rinex_obs); + r_ref.exceptions(std::ios::failbit); + gpstk::Rinex3ObsData r_ref_data; + gpstk::Rinex3ObsHeader r_ref_header; + gpstk::RinexDatum dataobj; + + r_ref >> r_ref_header; + + std::vector first_row; + gpstk::SatID prn; + for (unsigned int n = 0; n < gnss_synchro_vec.size(); n++) + { + first_row.push_back(true); + obs_vec->push_back(arma::zeros(1, 4)); + } + while (r_ref >> r_ref_data) + { + for (unsigned int n = 0; n < gnss_synchro_vec.size(); n++) + { + int myprn = gnss_synchro_vec.at(n).PRN; + + switch (gnss.System) + { + case 'G': + prn = gpstk::SatID(myprn, gpstk::SatID::systemGPS); + break; + case 'E': + prn = gpstk::SatID(myprn, gpstk::SatID::systemGalileo); + break; + default: + prn = gpstk::SatID(myprn, gpstk::SatID::systemGPS); + } + + gpstk::CommonTime time = r_ref_data.time; + double sow(static_cast(time).sow); + + gpstk::Rinex3ObsData::DataMap::iterator pointer = r_ref_data.obs.find(prn); + if (pointer == r_ref_data.obs.end()) + { + // PRN not present; do nothing + } + else + { + if (first_row.at(n) == false) + { + //insert next column + obs_vec->at(n).insert_rows(obs_vec->at(n).n_rows, 1); + } + else + { + first_row.at(n) = false; + } + if (strcmp("1C\0", gnss.Signal) == 0) + { + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 0) = sow; + dataobj = r_ref_data.getObs(prn, "C1C", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 1) = dataobj.data; //C1C P1 (psudorange L1) + dataobj = r_ref_data.getObs(prn, "D1C", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 2) = dataobj.data; //D1C Carrier Doppler + dataobj = r_ref_data.getObs(prn, "L1C", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 3) = dataobj.data; //L1C Carrier Phase + } + else if (strcmp("1B\0", gnss.Signal) == 0) + { + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 0) = sow; + dataobj = r_ref_data.getObs(prn, "C1B", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 1) = dataobj.data; + dataobj = r_ref_data.getObs(prn, "D1B", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 2) = dataobj.data; + dataobj = r_ref_data.getObs(prn, "L1B", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 3) = dataobj.data; + } + else if (strcmp("2S\0", gnss.Signal) == 0) //L2M + { + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 0) = sow; + dataobj = r_ref_data.getObs(prn, "C2S", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 1) = dataobj.data; + dataobj = r_ref_data.getObs(prn, "D2S", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 2) = dataobj.data; + dataobj = r_ref_data.getObs(prn, "L2S", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 3) = dataobj.data; + } + else if (strcmp("L5\0", gnss.Signal) == 0) + { + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 0) = sow; + dataobj = r_ref_data.getObs(prn, "C5I", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 1) = dataobj.data; + dataobj = r_ref_data.getObs(prn, "D5I", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 2) = dataobj.data; + dataobj = r_ref_data.getObs(prn, "L5I", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 3) = dataobj.data; + } + else if (strcmp("5X\0", gnss.Signal) == 0) //Simulator gives RINEX with E5a+E5b. Doppler and accumulated Carrier phase WILL differ + { + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 0) = sow; + dataobj = r_ref_data.getObs(prn, "C8I", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 1) = dataobj.data; + dataobj = r_ref_data.getObs(prn, "D8I", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 2) = dataobj.data; + dataobj = r_ref_data.getObs(prn, "L8I", r_ref_header); + obs_vec->at(n)(obs_vec->at(n).n_rows - 1, 3) = dataobj.data; + } + else + { + std::cout << "ReadRinexObs unknown signal requested: " << gnss.Signal << std::endl; + return false; + } + } + } + } // end while + } // End of 'try' block + catch (const gpstk::FFStreamError& e) + { + std::cout << e; + return false; + } + catch (const gpstk::Exception& e) + { + std::cout << e; + return false; + } + catch (const std::exception& e) + { + std::cout << "Exception: " << e.what(); + std::cout << "unknown error. I don't feel so well..." << std::endl; + return false; + } + std::cout << "ReadRinexObs info:" << std::endl; + for (unsigned int n = 0; n < gnss_synchro_vec.size(); n++) + { + std::cout << "SAT PRN " << gnss_synchro_vec.at(n).PRN << " RINEX epoch readed: " << obs_vec->at(n).n_rows << std::endl; + } + return true; +} TEST_F(HybridObservablesTest, ValidationOfResults) { // Configure the signal generator @@ -461,135 +1532,181 @@ TEST_F(HybridObservablesTest, ValidationOfResults) std::chrono::time_point start, end; std::chrono::duration elapsed_seconds(0); - configure_receiver(); + // use generator or use an external capture file + if (FLAGS_enable_external_signal_file) + { + //create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters + ASSERT_EQ(acquire_signal(), true); + } + else + { + Gnss_Synchro tmp_gnss_synchro; + tmp_gnss_synchro.System = 'G'; + std::string signal = "1C"; + signal.copy(tmp_gnss_synchro.Signal, 2, 0); - //open true observables log file written by the simulator - tracking_true_obs_reader true_obs_data_ch0; - tracking_true_obs_reader true_obs_data_ch1; - int test_satellite_PRN = FLAGS_test_satellite_PRN; - int test_satellite_PRN2 = FLAGS_test_satellite_PRN2; - std::cout << "Testing satellite PRNs " << test_satellite_PRN << "," << test_satellite_PRN << std::endl; - std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); - true_obs_file.append(std::to_string(test_satellite_PRN)); - true_obs_file.append(".dat"); - ASSERT_NO_THROW({ - if (true_obs_data_ch0.open_obs_file(true_obs_file) == false) - { - throw std::exception(); - }; - }) << "Failure opening true observables file"; + std::istringstream ss(FLAGS_test_satellite_PRN_list); + std::string token; - true_obs_file = std::string("./gps_l1_ca_obs_prn"); - true_obs_file.append(std::to_string(test_satellite_PRN2)); - true_obs_file.append(".dat"); - ASSERT_NO_THROW({ - if (true_obs_data_ch1.open_obs_file(true_obs_file) == false) - { - throw std::exception(); - }; - }) << "Failure opening true observables file"; + while (std::getline(ss, token, ',')) + { + tmp_gnss_synchro.PRN = boost::lexical_cast(token); + gnss_synchro_vec.push_back(tmp_gnss_synchro); + } + } + + + configure_receiver(FLAGS_PLL_bw_hz_start, + FLAGS_DLL_bw_hz_start, + FLAGS_PLL_narrow_bw_hz, + FLAGS_DLL_narrow_bw_hz, + FLAGS_extend_correlation_symbols, + FLAGS_smoother_length, + FLAGS_high_dyn); + + + for (unsigned int n = 0; n < gnss_synchro_vec.size(); n++) + { + //setup the signal synchronization, simulating an acquisition + if (!FLAGS_enable_external_signal_file) + { + //based on true observables metadata (for custom sdr generator) + //open true observables log file written by the simulator or based on provided RINEX obs + std::vector> true_reader_vec; + //read true data from the generator logs + true_reader_vec.push_back(std::make_shared()); + std::cout << "Loading true observable data for PRN " << gnss_synchro_vec.at(n).PRN << std::endl; + std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); + true_obs_file.append(std::to_string(gnss_synchro_vec.at(n).PRN)); + true_obs_file.append(".dat"); + ASSERT_NO_THROW({ + if (true_reader_vec.back()->open_obs_file(true_obs_file) == false) + { + throw std::exception(); + }; + }) << "Failure opening true observables file"; + + // load acquisition data based on the first epoch of the true observations + ASSERT_NO_THROW({ + if (true_reader_vec.back()->read_binary_obs() == false) + { + throw std::exception(); + }; + }) << "Failure reading true observables file"; + + //restart the epoch counter + true_reader_vec.back()->restart(); + + std::cout << "Initial Doppler [Hz]=" << true_reader_vec.back()->doppler_l1_hz << " Initial code delay [Chips]=" + << true_reader_vec.back()->prn_delay_chips << std::endl; + gnss_synchro_vec.at(n).Acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_reader_vec.back()->prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD; + gnss_synchro_vec.at(n).Acq_doppler_hz = true_reader_vec.back()->doppler_l1_hz; + gnss_synchro_vec.at(n).Acq_samplestamp_samples = 0; + } + else + { + //based on the signal acquisition process + std::cout << "Estimated Initial Doppler " << gnss_synchro_vec.at(n).Acq_doppler_hz + << " [Hz], estimated Initial code delay " << gnss_synchro_vec.at(n).Acq_delay_samples << " [Samples]" + << " Acquisition SampleStamp is " << gnss_synchro_vec.at(n).Acq_samplestamp_samples << std::endl; + gnss_synchro_vec.at(n).Acq_samplestamp_samples = 0; + } + } + + std::vector> tracking_ch_vec; + std::vector> tlm_ch_vec; + + std::vector null_sink_vec; + for (unsigned int n = 0; n < gnss_synchro_vec.size(); n++) + { + //set channels ids + gnss_synchro_vec.at(n).Channel_ID = n; + + //create the tracking channels and create the telemetry decoders + + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking", config->property("Tracking.implementation", std::string("undefined")), 1, 1); + tracking_ch_vec.push_back(std::dynamic_pointer_cast(trk_)); + std::shared_ptr tlm_ = factory->GetBlock(config, "TelemetryDecoder", config->property("TelemetryDecoder.implementation", std::string("undefined")), 1, 1); + tlm_ch_vec.push_back(std::dynamic_pointer_cast(tlm_)); + + //create null sinks for observables output + null_sink_vec.push_back(gr::blocks::null_sink::make(sizeof(Gnss_Synchro))); + + ASSERT_NO_THROW({ + tlm_ch_vec.back()->set_channel(gnss_synchro_vec.at(n).Channel_ID); + + switch (gnss_synchro_master.System) + { + case 'G': + tlm_ch_vec.back()->set_satellite(Gnss_Satellite(std::string("GPS"), gnss_synchro_vec.at(n).PRN)); + break; + case 'E': + tlm_ch_vec.back()->set_satellite(Gnss_Satellite(std::string("Galileo"), gnss_synchro_vec.at(n).PRN)); + break; + default: + tlm_ch_vec.back()->set_satellite(Gnss_Satellite(std::string("GPS"), gnss_synchro_vec.at(n).PRN)); + } + }) << "Failure setting gnss_synchro."; + + ASSERT_NO_THROW({ + tracking_ch_vec.back()->set_channel(gnss_synchro_vec.at(n).Channel_ID); + }) << "Failure setting channel."; + + ASSERT_NO_THROW({ + tracking_ch_vec.back()->set_gnss_synchro(&gnss_synchro_vec.at(n)); + }) << "Failure setting gnss_synchro."; + } top_block = gr::make_top_block("Telemetry_Decoder test"); - std::shared_ptr tracking_ch0 = std::make_shared(config.get(), "Tracking_1C", 1, 1); - std::shared_ptr tracking_ch1 = std::make_shared(config.get(), "Tracking_1C", 1, 1); - - boost::shared_ptr msg_rx_ch0 = HybridObservablesTest_msg_rx_make(); - boost::shared_ptr msg_rx_ch1 = HybridObservablesTest_msg_rx_make(); - - // load acquisition data based on the first epoch of the true observations - ASSERT_NO_THROW({ - if (true_obs_data_ch0.read_binary_obs() == false) - { - throw std::exception(); - }; - }) << "Failure reading true observables file"; - - ASSERT_NO_THROW({ - if (true_obs_data_ch1.read_binary_obs() == false) - { - throw std::exception(); - }; - }) << "Failure reading true observables file"; - - //restart the epoch counter - true_obs_data_ch0.restart(); - true_obs_data_ch1.restart(); - - std::cout << "Initial Doppler [Hz]=" << true_obs_data_ch0.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data_ch0.prn_delay_chips << std::endl; - - gnss_synchro_ch0.Acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data_ch0.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD; - gnss_synchro_ch0.Acq_doppler_hz = true_obs_data_ch0.doppler_l1_hz; - gnss_synchro_ch0.Acq_samplestamp_samples = 0; - - std::cout << "Initial Doppler [Hz]=" << true_obs_data_ch1.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data_ch1.prn_delay_chips << std::endl; - - gnss_synchro_ch1.Acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data_ch1.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD; - gnss_synchro_ch1.Acq_doppler_hz = true_obs_data_ch1.doppler_l1_hz; - gnss_synchro_ch1.Acq_samplestamp_samples = 0; - - //telemetry decoders - std::shared_ptr tlm_ch0(new GpsL1CaTelemetryDecoder(config.get(), "TelemetryDecoder_1C", 1, 1)); - std::shared_ptr tlm_ch1(new GpsL1CaTelemetryDecoder(config.get(), "TelemetryDecoder_1C", 1, 1)); - - ASSERT_NO_THROW({ - tlm_ch0->set_channel(0); - tlm_ch1->set_channel(1); - - tlm_ch0->set_satellite(Gnss_Satellite(std::string("GPS"), gnss_synchro_ch0.PRN)); - tlm_ch1->set_satellite(Gnss_Satellite(std::string("GPS"), gnss_synchro_ch1.PRN)); - }) << "Failure setting gnss_synchro."; - - boost::shared_ptr tlm_msg_rx_ch1 = HybridObservablesTest_tlm_msg_rx_make(); - boost::shared_ptr tlm_msg_rx_ch2 = HybridObservablesTest_tlm_msg_rx_make(); - + boost::shared_ptr dummy_msg_rx_trk = HybridObservablesTest_msg_rx_make(); + boost::shared_ptr dummy_tlm_msg_rx = HybridObservablesTest_tlm_msg_rx_make(); //Observables - std::shared_ptr observables(new HybridObservables(config.get(), "Observables", 3, 2)); + std::shared_ptr observables(new HybridObservables(config.get(), "Observables", tracking_ch_vec.size() + 1, tracking_ch_vec.size())); + + for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) + { + ASSERT_NO_THROW({ + tracking_ch_vec.at(n)->connect(top_block); + }) << "Failure connecting tracking to the top_block."; + } + ASSERT_NO_THROW({ - tracking_ch0->set_channel(gnss_synchro_ch0.Channel_ID); - tracking_ch1->set_channel(gnss_synchro_ch1.Channel_ID); - }) << "Failure setting channel."; - - ASSERT_NO_THROW({ - tracking_ch0->set_gnss_synchro(&gnss_synchro_ch0); - tracking_ch1->set_gnss_synchro(&gnss_synchro_ch1); - }) << "Failure setting gnss_synchro."; - - ASSERT_NO_THROW({ - tracking_ch0->connect(top_block); - tracking_ch1->connect(top_block); - }) << "Failure connecting tracking to the top_block."; - - ASSERT_NO_THROW({ - std::string file = "./" + filename_raw_data; + std::string file; + if (!FLAGS_enable_external_signal_file) + { + file = "./" + filename_raw_data; + } + else + { + file = FLAGS_signal_file; + } const char* file_name = file.c_str(); gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); - gr::blocks::null_sink::sptr sink_ch0 = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); - gr::blocks::null_sink::sptr sink_ch1 = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); - gnss_sdr_sample_counter_sptr samp_counter = gnss_sdr_make_sample_counter(static_cast(baseband_sampling_freq), sizeof(gr_complex)); + int observable_interval_ms = 20; + gnss_sdr_sample_counter_sptr samp_counter = gnss_sdr_make_sample_counter(static_cast(baseband_sampling_freq), observable_interval_ms, sizeof(gr_complex)); top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); top_block->connect(gr_interleaved_char_to_complex, 0, samp_counter, 0); - //ch0 - top_block->connect(gr_interleaved_char_to_complex, 0, tracking_ch0->get_left_block(), 0); - top_block->connect(tracking_ch0->get_right_block(), 0, tlm_ch0->get_left_block(), 0); - top_block->connect(tlm_ch0->get_right_block(), 0, observables->get_left_block(), 0); - top_block->msg_connect(tracking_ch0->get_right_block(), pmt::mp("events"), msg_rx_ch0, pmt::mp("events")); - //ch1 - top_block->connect(gr_interleaved_char_to_complex, 0, tracking_ch1->get_left_block(), 0); - top_block->connect(tracking_ch1->get_right_block(), 0, tlm_ch1->get_left_block(), 0); - top_block->connect(tlm_ch1->get_right_block(), 0, observables->get_left_block(), 1); - top_block->msg_connect(tracking_ch1->get_right_block(), pmt::mp("events"), msg_rx_ch1, pmt::mp("events")); - - top_block->connect(observables->get_right_block(), 0, sink_ch0, 0); - top_block->connect(observables->get_right_block(), 1, sink_ch1, 0); - top_block->connect(samp_counter, 0, observables->get_left_block(), 2); + for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) + { + top_block->connect(gr_interleaved_char_to_complex, 0, tracking_ch_vec.at(n)->get_left_block(), 0); + top_block->connect(tracking_ch_vec.at(n)->get_right_block(), 0, tlm_ch_vec.at(n)->get_left_block(), 0); + top_block->connect(tlm_ch_vec.at(n)->get_right_block(), 0, observables->get_left_block(), n); + top_block->msg_connect(tracking_ch_vec.at(n)->get_right_block(), pmt::mp("events"), dummy_msg_rx_trk, pmt::mp("events")); + top_block->connect(observables->get_right_block(), n, null_sink_vec.at(n), 0); + } + //connect sample counter and timmer to the last channel in observables block (extra channel) + top_block->connect(samp_counter, 0, observables->get_left_block(), tracking_ch_vec.size()); + file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample }) << "Failure connecting the blocks."; - tracking_ch0->start_tracking(); - tracking_ch1->start_tracking(); + for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) + { + tracking_ch_vec.at(n)->start_tracking(); + } EXPECT_NO_THROW({ start = std::chrono::system_clock::now(); @@ -599,55 +1716,61 @@ TEST_F(HybridObservablesTest, ValidationOfResults) }) << "Failure running the top_block."; //check results - //load the true values - - true_observables_reader true_observables; - - ASSERT_NO_THROW({ - if (true_observables.open_obs_file(std::string("./obs_out.bin")) == false) - { - throw std::exception(); - } - }) << "Failure opening true observables file"; - - unsigned int nepoch = static_cast(true_observables.num_epochs()); - - std::cout << "True observation epochs = " << nepoch << std::endl; // Matrices for storing columnwise true GPS time, Range, Doppler and Carrier phase - arma::mat true_ch0 = arma::zeros(nepoch, 4); - arma::mat true_ch1 = arma::zeros(nepoch, 4); + std::vector true_obs_vec; - true_observables.restart(); - long int epoch_counter = 0; - ASSERT_NO_THROW({ - while (true_observables.read_binary_obs()) - { - if (round(true_observables.prn[0]) != gnss_synchro_ch0.PRN) + if (!FLAGS_enable_external_signal_file) + { + //load the true values + true_observables_reader true_observables; + ASSERT_NO_THROW({ + if (true_observables.open_obs_file(std::string("./obs_out.bin")) == false) { - std::cout << "True observables SV PRN does not match " << round(true_observables.prn[1]) << std::endl; throw std::exception(); } - if (round(true_observables.prn[1]) != gnss_synchro_ch1.PRN) + }) << "Failure opening true observables file"; + + unsigned int nepoch = static_cast(true_observables.num_epochs()); + + std::cout << "True observation epochs = " << nepoch << std::endl; + + true_observables.restart(); + int64_t epoch_counter = 0; + for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) + { + true_obs_vec.push_back(arma::zeros(nepoch, 4)); + } + + ASSERT_NO_THROW({ + while (true_observables.read_binary_obs()) { - std::cout << "True observables SV PRN does not match " << round(true_observables.prn[1]) << std::endl; - throw std::exception(); + for (unsigned int n = 0; n < true_obs_vec.size(); n++) + { + if (round(true_observables.prn[n]) != gnss_synchro_vec.at(n).PRN) + { + std::cout << "True observables SV PRN does not match measured ones: " + << round(true_observables.prn[n]) << " vs. " << gnss_synchro_vec.at(n).PRN << std::endl; + throw std::exception(); + } + true_obs_vec.at(n)(epoch_counter, 0) = true_observables.gps_time_sec[n]; + true_obs_vec.at(n)(epoch_counter, 1) = true_observables.dist_m[n]; + true_obs_vec.at(n)(epoch_counter, 2) = true_observables.doppler_l1_hz[n]; + true_obs_vec.at(n)(epoch_counter, 3) = true_observables.acc_carrier_phase_l1_cycles[n]; + } + epoch_counter++; } - true_ch0(epoch_counter, 0) = true_observables.gps_time_sec[0]; - true_ch0(epoch_counter, 1) = true_observables.dist_m[0]; - true_ch0(epoch_counter, 2) = true_observables.doppler_l1_hz[0]; - true_ch0(epoch_counter, 3) = true_observables.acc_carrier_phase_l1_cycles[0]; - - true_ch1(epoch_counter, 0) = true_observables.gps_time_sec[1]; - true_ch1(epoch_counter, 1) = true_observables.dist_m[1]; - true_ch1(epoch_counter, 2) = true_observables.doppler_l1_hz[1]; - true_ch1(epoch_counter, 3) = true_observables.acc_carrier_phase_l1_cycles[1]; - - epoch_counter++; - } - }); - + }); + } + else + { + if (!FLAGS_duplicated_satellites_test) + { + ASSERT_EQ(ReadRinexObs(&true_obs_vec, gnss_synchro_master), true) + << "Failure reading RINEX file"; + } + } //read measured values - observables_dump_reader estimated_observables(2); //two channels + observables_dump_reader estimated_observables(tracking_ch_vec.size()); ASSERT_NO_THROW({ if (estimated_observables.open_obs_file(std::string("./observables.dat")) == false) { @@ -655,82 +1778,251 @@ TEST_F(HybridObservablesTest, ValidationOfResults) } }) << "Failure opening dump observables file"; - nepoch = static_cast(estimated_observables.num_epochs()); - std::cout << "Measured observation epochs = " << nepoch << std::endl; + unsigned int nepoch = static_cast(estimated_observables.num_epochs()); + std::cout << "Measured observations epochs = " << nepoch << std::endl; // Matrices for storing columnwise measured RX_time, TOW, Doppler, Carrier phase and Pseudorange - arma::mat measured_ch0 = arma::zeros(nepoch, 5); - arma::mat measured_ch1 = arma::zeros(nepoch, 5); + std::vector measured_obs_vec; + std::vector epoch_counters_vec; + for (unsigned int n = 0; n < tracking_ch_vec.size(); n++) + { + measured_obs_vec.push_back(arma::zeros(nepoch, 5)); + epoch_counters_vec.push_back(0); + } estimated_observables.restart(); - epoch_counter = 0; - long int epoch_counter2 = 0; while (estimated_observables.read_binary_obs()) { - if (static_cast(estimated_observables.valid[0])) + for (unsigned int n = 0; n < measured_obs_vec.size(); n++) { - measured_ch0(epoch_counter, 0) = estimated_observables.RX_time[0]; - measured_ch0(epoch_counter, 1) = estimated_observables.TOW_at_current_symbol_s[0]; - measured_ch0(epoch_counter, 2) = estimated_observables.Carrier_Doppler_hz[0]; - measured_ch0(epoch_counter, 3) = estimated_observables.Acc_carrier_phase_hz[0]; - measured_ch0(epoch_counter, 4) = estimated_observables.Pseudorange_m[0]; - epoch_counter++; - } - if (static_cast(estimated_observables.valid[1])) - { - measured_ch1(epoch_counter2, 0) = estimated_observables.RX_time[1]; - measured_ch1(epoch_counter2, 1) = estimated_observables.TOW_at_current_symbol_s[1]; - measured_ch1(epoch_counter2, 2) = estimated_observables.Carrier_Doppler_hz[1]; - measured_ch1(epoch_counter2, 3) = estimated_observables.Acc_carrier_phase_hz[1]; - measured_ch1(epoch_counter2, 4) = estimated_observables.Pseudorange_m[1]; - epoch_counter2++; + if (static_cast(estimated_observables.valid[n])) + { + measured_obs_vec.at(n)(epoch_counters_vec.at(n), 0) = estimated_observables.RX_time[n]; + measured_obs_vec.at(n)(epoch_counters_vec.at(n), 1) = estimated_observables.TOW_at_current_symbol_s[n]; + measured_obs_vec.at(n)(epoch_counters_vec.at(n), 2) = estimated_observables.Carrier_Doppler_hz[n]; + measured_obs_vec.at(n)(epoch_counters_vec.at(n), 3) = estimated_observables.Acc_carrier_phase_hz[n]; + measured_obs_vec.at(n)(epoch_counters_vec.at(n), 4) = estimated_observables.Pseudorange_m[n]; + epoch_counters_vec.at(n)++; + } } } //Cut measurement tail zeros - arma::uvec index = arma::find(measured_ch0.col(0) > 0.0, 1, "last"); - if ((index.size() > 0) and index(0) < (nepoch - 1)) + arma::uvec index; + for (unsigned int n = 0; n < measured_obs_vec.size(); n++) { - measured_ch0.shed_rows(index(0) + 1, nepoch - 1); - } - index = arma::find(measured_ch1.col(0) > 0.0, 1, "last"); - if ((index.size() > 0) and index(0) < (nepoch - 1)) - { - measured_ch1.shed_rows(index(0) + 1, nepoch - 1); + index = arma::find(measured_obs_vec.at(n).col(0) > 0.0, 1, "last"); + if ((index.size() > 0) and index(0) < (nepoch - 1)) + { + measured_obs_vec.at(n).shed_rows(index(0) + 1, nepoch - 1); + } } //Cut measurement initial transitory of the measurements - index = arma::find(measured_ch0.col(0) >= true_ch0(0, 0), 1, "first"); - if ((index.size() > 0) and (index(0) > 0)) + double initial_transitory_s = FLAGS_skip_obs_transitory_s; + for (unsigned int n = 0; n < measured_obs_vec.size(); n++) { - measured_ch0.shed_rows(0, index(0)); - } - index = arma::find(measured_ch1.col(0) >= true_ch1(0, 0), 1, "first"); - if ((index.size() > 0) and (index(0) > 0)) - { - measured_ch1.shed_rows(0, index(0)); + index = arma::find(measured_obs_vec.at(n).col(0) >= (measured_obs_vec.at(n)(0, 0) + initial_transitory_s), 1, "first"); + if ((index.size() > 0) and (index(0) > 0)) + { + measured_obs_vec.at(n).shed_rows(0, index(0)); + } + + if (!FLAGS_duplicated_satellites_test) + { + index = arma::find(measured_obs_vec.at(n).col(0) >= true_obs_vec.at(n)(0, 0), 1, "first"); + if ((index.size() > 0) and (index(0) > 0)) + { + measured_obs_vec.at(n).shed_rows(0, index(0)); + } + } } - //Correct the clock error using true values (it is not possible for a receiver to correct - //the receiver clock offset error at the observables level because it is required the - //decoding of the ephemeris data and solve the PVT equations) - //Find the reference satellite (the nearest) and compute the receiver time offset at observable level - arma::vec receiver_time_offset_s; - if (measured_ch0(0, 4) < measured_ch1(0, 4)) + if (FLAGS_duplicated_satellites_test) { - receiver_time_offset_s = true_ch0.col(1) / GPS_C_m_s - GPS_STARTOFFSET_ms / 1000.0; + //special test mode for duplicated satellites + std::vector prn_pairs; + std::stringstream ss(FLAGS_duplicated_satellites_prns); + unsigned int i; + while (ss >> i) + { + prn_pairs.push_back(i); + if (ss.peek() == ',') + ss.ignore(); + } + + if (prn_pairs.size() % 2 != 0) + { + std::cout << "Test settings error: duplicated_satellites_prns are even\n"; + } + else + { + for (unsigned int n = 0; n < prn_pairs.size(); n = n + 2) + { + int sat1_ch_id = -1; + int sat2_ch_id = -1; + for (unsigned int ch = 0; ch < measured_obs_vec.size(); ch++) + { + if (epoch_counters_vec.at(ch) > 10) //discard non-valid channels + { + if (gnss_synchro_vec.at(ch).PRN == prn_pairs.at(n)) + { + sat1_ch_id = ch; + } + if (gnss_synchro_vec.at(ch).PRN == prn_pairs.at(n + 1)) + { + sat2_ch_id = ch; + } + } + } + if (sat1_ch_id != -1 and sat2_ch_id != -1) + { + //compute single differences for the duplicated satellite + + check_results_duplicated_satellite( + measured_obs_vec.at(sat1_ch_id), + measured_obs_vec.at(sat2_ch_id), + sat1_ch_id, + "Duplicated sat [CH " + std::to_string(sat1_ch_id) + "," + std::to_string(sat2_ch_id) + "] PRNs " + std::to_string(gnss_synchro_vec.at(sat1_ch_id).PRN) + "," + std::to_string(gnss_synchro_vec.at(sat2_ch_id).PRN) + " "); + } + else + { + std::cout << "Satellites PRNs " << prn_pairs.at(n) << "and " << prn_pairs.at(n) << " not found\n"; + } + } + } } else { - receiver_time_offset_s = true_ch1.col(1) / GPS_C_m_s - GPS_STARTOFFSET_ms / 1000.0; + //normal mode + + //Correct the clock error using true values (it is not possible for a receiver to correct + //the receiver clock offset error at the observables level because it is required the + //decoding of the ephemeris data and solve the PVT equations) + + //Find the reference satellite (the nearest) and compute the receiver time offset at observable level + double min_pr = std::numeric_limits::max(); + unsigned int min_pr_ch_id = 0; + for (unsigned int n = 0; n < measured_obs_vec.size(); n++) + { + if (epoch_counters_vec.at(n) > 10) //discard non-valid channels + { + { + if (measured_obs_vec.at(n)(0, 4) < min_pr) + { + min_pr = measured_obs_vec.at(n)(0, 4); + min_pr_ch_id = n; + } + } + } + else + { + std::cout << "PRN " << gnss_synchro_vec.at(n).PRN << " has NO observations!\n"; + } + } + + arma::vec receiver_time_offset_ref_channel_s; + receiver_time_offset_ref_channel_s = (true_obs_vec.at(min_pr_ch_id).col(1)(0) - measured_obs_vec.at(min_pr_ch_id).col(4)(0)) / GPS_C_m_s; + std::cout << "Ref. channel initial Receiver time offset " << receiver_time_offset_ref_channel_s(0) * 1e3 << " [ms]" << std::endl; + + for (unsigned int n = 0; n < measured_obs_vec.size(); n++) + { + //debug save to .mat + std::vector tmp_vector_x(true_obs_vec.at(n).col(0).colptr(0), + true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows); + std::vector tmp_vector_y(true_obs_vec.at(n).col(1).colptr(0), + true_obs_vec.at(n).col(1).colptr(0) + true_obs_vec.at(n).col(1).n_rows); + save_mat_xy(tmp_vector_x, tmp_vector_y, std::string("true_pr_ch_" + std::to_string(n))); + + std::vector tmp_vector_x2(measured_obs_vec.at(n).col(0).colptr(0), + measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows); + std::vector tmp_vector_y2(measured_obs_vec.at(n).col(4).colptr(0), + measured_obs_vec.at(n).col(4).colptr(0) + measured_obs_vec.at(n).col(4).n_rows); + save_mat_xy(tmp_vector_x2, tmp_vector_y2, std::string("measured_pr_ch_" + std::to_string(n))); + + std::vector tmp_vector_x3(true_obs_vec.at(n).col(0).colptr(0), + true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows); + std::vector tmp_vector_y3(true_obs_vec.at(n).col(2).colptr(0), + true_obs_vec.at(n).col(2).colptr(0) + true_obs_vec.at(n).col(2).n_rows); + save_mat_xy(tmp_vector_x3, tmp_vector_y3, std::string("true_doppler_ch_" + std::to_string(n))); + + std::vector tmp_vector_x4(measured_obs_vec.at(n).col(0).colptr(0), + measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows); + std::vector tmp_vector_y4(measured_obs_vec.at(n).col(2).colptr(0), + measured_obs_vec.at(n).col(2).colptr(0) + measured_obs_vec.at(n).col(2).n_rows); + save_mat_xy(tmp_vector_x4, tmp_vector_y4, std::string("measured_doppler_ch_" + std::to_string(n))); + + std::vector tmp_vector_x5(true_obs_vec.at(n).col(0).colptr(0), + true_obs_vec.at(n).col(0).colptr(0) + true_obs_vec.at(n).col(0).n_rows); + std::vector tmp_vector_y5(true_obs_vec.at(n).col(3).colptr(0), + true_obs_vec.at(n).col(3).colptr(0) + true_obs_vec.at(n).col(3).n_rows); + save_mat_xy(tmp_vector_x5, tmp_vector_y5, std::string("true_cp_ch_" + std::to_string(n))); + + std::vector tmp_vector_x6(measured_obs_vec.at(n).col(0).colptr(0), + measured_obs_vec.at(n).col(0).colptr(0) + measured_obs_vec.at(n).col(0).n_rows); + std::vector tmp_vector_y6(measured_obs_vec.at(n).col(3).colptr(0), + measured_obs_vec.at(n).col(3).colptr(0) + measured_obs_vec.at(n).col(3).n_rows); + save_mat_xy(tmp_vector_x6, tmp_vector_y6, std::string("measured_cp_ch_" + std::to_string(n))); + + + if (epoch_counters_vec.at(n) > 10) //discard non-valid channels + { + arma::vec true_TOW_ref_ch_s = true_obs_vec.at(min_pr_ch_id).col(0) - receiver_time_offset_ref_channel_s(0); + arma::vec true_TOW_ch_s = true_obs_vec.at(n).col(0) - receiver_time_offset_ref_channel_s(0); + //Compare measured observables + if (min_pr_ch_id != n) + { + check_results_code_pseudorange(true_obs_vec.at(n), + true_obs_vec.at(min_pr_ch_id), + true_TOW_ch_s, + true_TOW_ref_ch_s, + measured_obs_vec.at(n), + measured_obs_vec.at(min_pr_ch_id), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + + //Do not compare E5a with E5 RINEX due to the Doppler frequency discrepancy caused by the different center frequencies + //E5a_fc=1176.45e6, E5b_fc=1207.14e6, E5_fc=1191.795e6; + if (strcmp("5X\0", gnss_synchro_vec.at(n).Signal) != 0 or FLAGS_compare_with_5X) + { + check_results_carrier_phase_double_diff(true_obs_vec.at(n), + true_obs_vec.at(min_pr_ch_id), + true_TOW_ch_s, + true_TOW_ref_ch_s, + measured_obs_vec.at(n), + measured_obs_vec.at(min_pr_ch_id), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + + check_results_carrier_doppler_double_diff(true_obs_vec.at(n), + true_obs_vec.at(min_pr_ch_id), + true_TOW_ch_s, + true_TOW_ref_ch_s, + measured_obs_vec.at(n), + measured_obs_vec.at(min_pr_ch_id), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + } + } + else + { + std::cout << "[CH " << std::to_string(n) << "] PRN " << std::to_string(gnss_synchro_vec.at(n).PRN) << " is the reference satellite" << std::endl; + } + if (FLAGS_compute_single_diffs) + { + check_results_carrier_phase(true_obs_vec.at(n), + true_TOW_ch_s, + measured_obs_vec.at(n), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + check_results_carrier_doppler(true_obs_vec.at(n), + true_TOW_ch_s, + measured_obs_vec.at(n), + "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); + } + } + else + { + std::cout << "PRN " << gnss_synchro_vec.at(n).PRN << " has NO observations!\n"; + } + } } - arma::vec corrected_reference_TOW_s = true_ch0.col(0) - receiver_time_offset_s; - std::cout << "Receiver time offset: " << receiver_time_offset_s(0) * 1e3 << " [ms]" << std::endl; - - //Compare measured observables - check_results_code_psudorange(true_ch0, true_ch1, corrected_reference_TOW_s, measured_ch0, measured_ch1); - check_results_carrier_phase(true_ch0, true_ch1, corrected_reference_TOW_s, measured_ch0, measured_ch1); - std::cout << "Test completed in " << elapsed_seconds.count() << " [s]" << std::endl; } diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc index a08b401c2..ccf97ecaa 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc @@ -157,19 +157,27 @@ void NmeaPrinterTest::conf() TEST_F(NmeaPrinterTest, PrintLine) { std::string filename("nmea_test.nmea"); - std::shared_ptr pvt_solution = std::make_shared(12, "filename", false, rtk); + std::shared_ptr pvt_solution = std::make_shared(12, "filename", false, false, rtk); boost::posix_time::ptime pt(boost::gregorian::date(1994, boost::date_time::Nov, 19), - boost::posix_time::hours(22) + boost::posix_time::minutes(54) + boost::posix_time::seconds(46)); // example from http://aprs.gids.nl/nmea/#rmc - pvt_solution->set_position_UTC_time(pt); + boost::posix_time::hours(22) + boost::posix_time::minutes(54) + boost::posix_time::seconds(46)); + std::time_t tim = (pt - boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1))).total_seconds(); + gtime_t gtime; + gtime.time = tim; + gtime.sec = 0.0; - arma::vec pos = {49.27416667, -123.18533333, 0}; - pvt_solution->set_rx_pos(pos); - - pvt_solution->set_valid_position(true); + pvt_solution->pvt_sol.rr[0] = -2282104.0; //49.27416667; + pvt_solution->pvt_sol.rr[1] = -3489369.0; //-123.18533333; + pvt_solution->pvt_sol.rr[2] = 4810507.0; // 0 + pvt_solution->pvt_sol.rr[3] = 0.0; + pvt_solution->pvt_sol.rr[4] = 0.0; + pvt_solution->pvt_sol.rr[5] = 0.0; + pvt_solution->pvt_sol.stat = 1; // SOLQ_FIX + pvt_solution->pvt_sol.time = gtime; + bool flag_nmea_output_file = true; ASSERT_NO_THROW({ - std::shared_ptr nmea_printer = std::make_shared(filename, false, ""); + std::shared_ptr nmea_printer = std::make_shared(filename, flag_nmea_output_file, false, ""); nmea_printer->Print_Nmea_Line(pvt_solution, false); }) << "Failure printing NMEA messages."; @@ -183,45 +191,7 @@ TEST_F(NmeaPrinterTest, PrintLine) std::size_t found = line.find(GPRMC); if (found != std::string::npos) { - EXPECT_EQ(line, "$GPRMC,225446.000,A,4916.4500,N,12311.1199,W,0.00,0.00,191194,,*1c\r"); - } - } - test_file.close(); - } - EXPECT_EQ(0, remove(filename.c_str())) << "Failure deleting a temporary file."; -} - - -TEST_F(NmeaPrinterTest, PrintLineLessthan10min) -{ - std::string filename("nmea_test.nmea"); - std::shared_ptr pvt_solution = std::make_shared(12, "filename", false, rtk); - - boost::posix_time::ptime pt(boost::gregorian::date(1994, boost::date_time::Nov, 19), - boost::posix_time::hours(22) + boost::posix_time::minutes(54) + boost::posix_time::seconds(46)); // example from http://aprs.gids.nl/nmea/#rmc - pvt_solution->set_position_UTC_time(pt); - - arma::vec pos = {49.07416667, -123.02527778, 0}; - pvt_solution->set_rx_pos(pos); - - pvt_solution->set_valid_position(true); - - ASSERT_NO_THROW({ - std::shared_ptr nmea_printer = std::make_shared(filename, false, ""); - nmea_printer->Print_Nmea_Line(pvt_solution, false); - }) << "Failure printing NMEA messages."; - - std::ifstream test_file(filename); - std::string line; - std::string GPRMC("$GPRMC"); - if (test_file.is_open()) - { - while (getline(test_file, line)) - { - std::size_t found = line.find(GPRMC); - if (found != std::string::npos) - { - EXPECT_EQ(line, "$GPRMC,225446.000,A,4904.4500,N,12301.5166,W,0.00,0.00,191194,,*1a\r"); + EXPECT_EQ(line, "$GPRMC,225436.00,A,4916.4497617,N,12311.1202744,W,0.00,0.00,191194,0.0,E,D*21\r"); } } test_file.close(); diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc index 24544f380..4f648e0b7 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc @@ -39,9 +39,10 @@ TEST(RtcmPrinterTest, Instantiate) bool flag_rtcm_tty_port = false; std::string rtcm_dump_devname = "/dev/pts/4"; bool flag_rtcm_server = false; + bool rtcm_file_output_enabled = false; unsigned short rtcm_tcp_port = 2101; unsigned short rtcm_station_id = 1234; - std::unique_ptr RTCM_printer(new Rtcm_Printer(filename, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname)); + std::unique_ptr RTCM_printer(new Rtcm_Printer(filename, rtcm_file_output_enabled, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname)); } @@ -49,12 +50,13 @@ TEST(RtcmPrinterTest, Run) { std::string filename = "test.rtcm"; bool flag_rtcm_tty_port = false; + bool rtcm_file_output_enabled = false; std::string rtcm_dump_devname = "/dev/pts/4"; bool flag_rtcm_server = false; unsigned short rtcm_tcp_port = 2101; unsigned short rtcm_station_id = 1234; - std::unique_ptr RTCM_printer(new Rtcm_Printer(filename, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname)); + std::unique_ptr RTCM_printer(new Rtcm_Printer(filename, rtcm_file_output_enabled, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_dump_devname)); std::string reference_msg = "D300133ED7D30202980EDEEF34B4BD62AC0941986F33360B98"; @@ -63,7 +65,7 @@ TEST(RtcmPrinterTest, Run) unsigned char c[1]; for (unsigned int i = 0; i < reference_msg.length(); i = i + 2) { - unsigned long int n, n2; + uint64_t n, n2; std::istringstream(reference_msg.substr(i, 1)) >> std::hex >> n; std::istringstream(reference_msg.substr(i + 1, 1)) >> std::hex >> n2; c[0] = static_cast(n * 16) + static_cast(n2); diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc index 6ec85e562..4d8e54af6 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc @@ -103,8 +103,8 @@ TEST(RtcmTest, HexToInt) auto rtcm = std::make_shared(); std::string test1 = "2A"; - long int test1_int = rtcm->hex_to_int(test1); - long int expected1 = 42; + int64_t test1_int = rtcm->hex_to_int(test1); + int64_t expected1 = 42; EXPECT_EQ(expected1, test1_int); } @@ -112,7 +112,7 @@ TEST(RtcmTest, HexToInt) TEST(RtcmTest, HexToUint) { auto rtcm = std::make_shared(); - long unsigned int expected1 = 42; + uint64_t expected1 = 42; EXPECT_EQ(expected1, rtcm->hex_to_uint(rtcm->bin_to_hex("00101010"))); } @@ -122,8 +122,8 @@ TEST(RtcmTest, BinToDouble) auto rtcm = std::make_shared(); std::bitset<4> test1(5); - long int test1_int = static_cast(rtcm->bin_to_double(test1.to_string())); - long int expected1 = 5; + int64_t test1_int = static_cast(rtcm->bin_to_double(test1.to_string())); + int64_t expected1 = 5; EXPECT_EQ(expected1, test1_int); std::bitset<4> test2(-5); @@ -137,9 +137,9 @@ TEST(RtcmTest, BinToDouble) TEST(RtcmTest, BinToUint) { auto rtcm = std::make_shared(); - long unsigned int expected1 = 42; + uint32_t expected1 = 42; EXPECT_EQ(expected1, rtcm->bin_to_uint("00101010")); - long unsigned int expected2 = 214; + uint32_t expected2 = 214; EXPECT_EQ(expected2, rtcm->bin_to_uint("11010110")); } @@ -147,9 +147,9 @@ TEST(RtcmTest, BinToUint) TEST(RtcmTest, BinToInt) { auto rtcm = std::make_shared(); - long int expected1 = 42; + int32_t expected1 = 42; EXPECT_EQ(expected1, rtcm->bin_to_int("00101010")); - long int expected2 = -42; + int32_t expected2 = -42; EXPECT_EQ(expected2, rtcm->bin_to_int("11010110")); } @@ -620,7 +620,7 @@ TEST(RtcmTest, InstantiateServer) std::string test6 = "0011"; std::string test6_hex = rtcm->bin_to_hex(test6); EXPECT_EQ(0, test6_hex.compare("3")); - long unsigned int expected1 = 42; + uint64_t expected1 = 42; EXPECT_EQ(expected1, rtcm->bin_to_uint("00101010")); rtcm->run_server(); std::string test4_bin = rtcm->hex_to_bin(test3); diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc new file mode 100644 index 000000000..fe0c81ab6 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc @@ -0,0 +1,462 @@ +/*! + * \file rtklib_solver_test.cc + * \brief Implements Unit Test for the rtklib PVT solver class. + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include "rtklib_solver.h" +#include "in_memory_configuration.h" +#include "gnss_sdr_supl_client.h" +#include "geofunctions.h" +#include + + +rtk_t configure_rtklib_options() +{ + std::shared_ptr configuration; + configuration = std::make_shared(); + std::string role = "rtklib_solver"; + // custom options + configuration->set_property("rtklib_solver.positioning_mode", "Single"); + configuration->set_property("rtklib_solver.elevation_mask", "0"); + configuration->set_property("rtklib_solver.iono_model", "OFF"); + configuration->set_property("rtklib_solver.trop_model", "OFF"); + //RTKLIB PVT solver options + + // Settings 1 + int positioning_mode = -1; + std::string default_pos_mode("Single"); + std::string positioning_mode_str = configuration->property(role + ".positioning_mode", default_pos_mode); /* (PMODE_XXX) see src/algorithms/libs/rtklib/rtklib.h */ + if (positioning_mode_str.compare("Single") == 0) positioning_mode = PMODE_SINGLE; + if (positioning_mode_str.compare("Static") == 0) positioning_mode = PMODE_STATIC; + if (positioning_mode_str.compare("Kinematic") == 0) positioning_mode = PMODE_KINEMA; + if (positioning_mode_str.compare("PPP_Static") == 0) positioning_mode = PMODE_PPP_STATIC; + if (positioning_mode_str.compare("PPP_Kinematic") == 0) positioning_mode = PMODE_PPP_KINEMA; + + if (positioning_mode == -1) + { + //warn user and set the default + std::cout << "WARNING: Bad specification of positioning mode." << std::endl; + std::cout << "positioning_mode possible values: Single / Static / Kinematic / PPP_Static / PPP_Kinematic" << std::endl; + std::cout << "positioning_mode specified value: " << positioning_mode_str << std::endl; + std::cout << "Setting positioning_mode to Single" << std::endl; + positioning_mode = PMODE_SINGLE; + } + + int num_bands = 1; + + // if ((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) num_bands = 1; + // if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gps_2S_count > 0) || (glo_2G_count > 0))) num_bands = 2; + // if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 2; + // if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gps_2S_count > 0) || (glo_2G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 3; + + int number_of_frequencies = configuration->property(role + ".num_bands", num_bands); /* (1:L1, 2:L1+L2, 3:L1+L2+L5) */ + if ((number_of_frequencies < 1) || (number_of_frequencies > 3)) + { + //warn user and set the default + number_of_frequencies = num_bands; + } + + double elevation_mask = configuration->property(role + ".elevation_mask", 15.0); + if ((elevation_mask < 0.0) || (elevation_mask > 90.0)) + { + //warn user and set the default + LOG(WARNING) << "Erroneous Elevation Mask. Setting to default value of 15.0 degrees"; + elevation_mask = 15.0; + } + + int dynamics_model = configuration->property(role + ".dynamics_model", 0); /* dynamics model (0:none, 1:velocity, 2:accel) */ + if ((dynamics_model < 0) || (dynamics_model > 2)) + { + //warn user and set the default + LOG(WARNING) << "Erroneous Dynamics Model configuration. Setting to default value of (0:none)"; + dynamics_model = 0; + } + + std::string default_iono_model("OFF"); + std::string iono_model_str = configuration->property(role + ".iono_model", default_iono_model); /* (IONOOPT_XXX) see src/algorithms/libs/rtklib/rtklib.h */ + int iono_model = -1; + if (iono_model_str.compare("OFF") == 0) iono_model = IONOOPT_OFF; + if (iono_model_str.compare("Broadcast") == 0) iono_model = IONOOPT_BRDC; + if (iono_model_str.compare("SBAS") == 0) iono_model = IONOOPT_SBAS; + if (iono_model_str.compare("Iono-Free-LC") == 0) iono_model = IONOOPT_IFLC; + if (iono_model_str.compare("Estimate_STEC") == 0) iono_model = IONOOPT_EST; + if (iono_model_str.compare("IONEX") == 0) iono_model = IONOOPT_TEC; + if (iono_model == -1) + { + //warn user and set the default + std::cout << "WARNING: Bad specification of ionospheric model." << std::endl; + std::cout << "iono_model possible values: OFF / Broadcast / SBAS / Iono-Free-LC / Estimate_STEC / IONEX" << std::endl; + std::cout << "iono_model specified value: " << iono_model_str << std::endl; + std::cout << "Setting iono_model to OFF" << std::endl; + iono_model = IONOOPT_OFF; /* 0: ionosphere option: correction off */ + } + + std::string default_trop_model("OFF"); + int trop_model = -1; + std::string trop_model_str = configuration->property(role + ".trop_model", default_trop_model); /* (TROPOPT_XXX) see src/algorithms/libs/rtklib/rtklib.h */ + if (trop_model_str.compare("OFF") == 0) trop_model = TROPOPT_OFF; + if (trop_model_str.compare("Saastamoinen") == 0) trop_model = TROPOPT_SAAS; + if (trop_model_str.compare("SBAS") == 0) trop_model = TROPOPT_SBAS; + if (trop_model_str.compare("Estimate_ZTD") == 0) trop_model = TROPOPT_EST; + if (trop_model_str.compare("Estimate_ZTD_Grad") == 0) trop_model = TROPOPT_ESTG; + if (trop_model == -1) + { + //warn user and set the default + std::cout << "WARNING: Bad specification of tropospheric model." << std::endl; + std::cout << "trop_model possible values: OFF / Saastamoinen / SBAS / Estimate_ZTD / Estimate_ZTD_Grad" << std::endl; + std::cout << "trop_model specified value: " << trop_model_str << std::endl; + std::cout << "Setting trop_model to OFF" << std::endl; + trop_model = TROPOPT_OFF; + } + + /* RTKLIB positioning options */ + int sat_PCV = 0; /* Set whether the satellite antenna PCV (phase center variation) model is used or not. This feature requires a Satellite Antenna PCV File. */ + int rec_PCV = 0; /* Set whether the receiver antenna PCV (phase center variation) model is used or not. This feature requires a Receiver Antenna PCV File. */ + + /* Set whether the phase windup correction for PPP modes is applied or not. Only applicable to PPP‐* modes.*/ + int phwindup = configuration->property(role + ".phwindup", 0); + + /* Set whether the GPS Block IIA satellites in eclipse are excluded or not. + The eclipsing Block IIA satellites often degrade the PPP solutions due to unpredicted behavior of yaw‐attitude. Only applicable to PPP‐* modes.*/ + int reject_GPS_IIA = configuration->property(role + ".reject_GPS_IIA", 0); + + /* Set whether RAIM (receiver autonomous integrity monitoring) FDE (fault detection and exclusion) feature is enabled or not. + In case of RAIM FDE enabled, a satellite is excluded if SSE (sum of squared errors) of residuals is over a threshold. + The excluded satellite is selected to indicate the minimum SSE. */ + int raim_fde = configuration->property(role + ".raim_fde", 0); + + int earth_tide = configuration->property(role + ".earth_tide", 0); + + int nsys = SYS_GPS; + // if ((gps_1C_count > 0) || (gps_2S_count > 0) || (gps_L5_count > 0)) nsys += SYS_GPS; + // if ((gal_1B_count > 0) || (gal_E5a_count > 0) || (gal_E5b_count > 0)) nsys += SYS_GAL; + // if ((glo_1G_count > 0) || (glo_2G_count > 0)) nsys += SYS_GLO; + int navigation_system = configuration->property(role + ".navigation_system", nsys); /* (SYS_XXX) see src/algorithms/libs/rtklib/rtklib.h */ + if ((navigation_system < 1) || (navigation_system > 255)) /* GPS: 1 SBAS: 2 GPS+SBAS: 3 Galileo: 8 Galileo+GPS: 9 GPS+SBAS+Galileo: 11 All: 255 */ + { + //warn user and set the default + LOG(WARNING) << "Erroneous Navigation System. Setting to default value of (0:none)"; + navigation_system = nsys; + } + + // Settings 2 + std::string default_gps_ar("Continuous"); + std::string integer_ambiguity_resolution_gps_str = configuration->property(role + ".AR_GPS", default_gps_ar); /* Integer Ambiguity Resolution mode for GPS (0:off,1:continuous,2:instantaneous,3:fix and hold,4:ppp-ar) */ + int integer_ambiguity_resolution_gps = -1; + if (integer_ambiguity_resolution_gps_str.compare("OFF") == 0) integer_ambiguity_resolution_gps = ARMODE_OFF; + if (integer_ambiguity_resolution_gps_str.compare("Continuous") == 0) integer_ambiguity_resolution_gps = ARMODE_CONT; + if (integer_ambiguity_resolution_gps_str.compare("Instantaneous") == 0) integer_ambiguity_resolution_gps = ARMODE_INST; + if (integer_ambiguity_resolution_gps_str.compare("Fix-and-Hold") == 0) integer_ambiguity_resolution_gps = ARMODE_FIXHOLD; + if (integer_ambiguity_resolution_gps_str.compare("PPP-AR") == 0) integer_ambiguity_resolution_gps = ARMODE_PPPAR; + if (integer_ambiguity_resolution_gps == -1) + { + //warn user and set the default + std::cout << "WARNING: Bad specification of GPS ambiguity resolution method." << std::endl; + std::cout << "AR_GPS possible values: OFF / Continuous / Instantaneous / Fix-and-Hold / PPP-AR" << std::endl; + std::cout << "AR_GPS specified value: " << integer_ambiguity_resolution_gps_str << std::endl; + std::cout << "Setting AR_GPS to OFF" << std::endl; + integer_ambiguity_resolution_gps = ARMODE_OFF; + } + + int integer_ambiguity_resolution_glo = configuration->property(role + ".AR_GLO", 1); /* Integer Ambiguity Resolution mode for GLONASS (0:off,1:on,2:auto cal,3:ext cal) */ + if ((integer_ambiguity_resolution_glo < 0) || (integer_ambiguity_resolution_glo > 3)) + { + //warn user and set the default + LOG(WARNING) << "Erroneous Integer Ambiguity Resolution for GLONASS . Setting to default value of (1:on)"; + integer_ambiguity_resolution_glo = 1; + } + + int integer_ambiguity_resolution_bds = configuration->property(role + ".AR_DBS", 1); /* Integer Ambiguity Resolution mode for BEIDOU (0:off,1:on) */ + if ((integer_ambiguity_resolution_bds < 0) || (integer_ambiguity_resolution_bds > 1)) + { + //warn user and set the default + LOG(WARNING) << "Erroneous Integer Ambiguity Resolution for BEIDOU . Setting to default value of (1:on)"; + integer_ambiguity_resolution_bds = 1; + } + + double min_ratio_to_fix_ambiguity = configuration->property(role + ".min_ratio_to_fix_ambiguity", 3.0); /* Set the integer ambiguity validation threshold for ratio‐test, + which uses the ratio of squared residuals of the best integer vector to the second‐best vector. */ + + int min_lock_to_fix_ambiguity = configuration->property(role + ".min_lock_to_fix_ambiguity", 0); /* Set the minimum lock count to fix integer ambiguity. + If the lock count is less than the value, the ambiguity is excluded from the fixed integer vector. */ + + double min_elevation_to_fix_ambiguity = configuration->property(role + ".min_elevation_to_fix_ambiguity", 0.0); /* Set the minimum elevation (deg) to fix integer ambiguity. + If the elevation of the satellite is less than the value, the ambiguity is excluded from the fixed integer vector. */ + + int outage_reset_ambiguity = configuration->property(role + ".outage_reset_ambiguity", 5); /* Set the outage count to reset ambiguity. If the data outage count is over the value, the estimated ambiguity is reset to the initial value. */ + + double slip_threshold = configuration->property(role + ".slip_threshold", 0.05); /* set the cycle‐slip threshold (m) of geometry‐free LC carrier‐phase difference between epochs */ + + double threshold_reject_gdop = configuration->property(role + ".threshold_reject_gdop", 30.0); /* reject threshold of GDOP. If the GDOP is over the value, the observable is excluded for the estimation process as an outlier. */ + + double threshold_reject_innovation = configuration->property(role + ".threshold_reject_innovation", 30.0); /* reject threshold of innovation (m). If the innovation is over the value, the observable is excluded for the estimation process as an outlier. */ + + int number_filter_iter = configuration->property(role + ".number_filter_iter", 1); /* Set the number of iteration in the measurement update of the estimation filter. + If the baseline length is very short like 1 m, the iteration may be effective to handle + the nonlinearity of measurement equation. */ + + /// Statistics + double bias_0 = configuration->property(role + ".bias_0", 30.0); + + double iono_0 = configuration->property(role + ".iono_0", 0.03); + + double trop_0 = configuration->property(role + ".trop_0", 0.3); + + double sigma_bias = configuration->property(role + ".sigma_bias", 1e-4); /* Set the process noise standard deviation of carrier‐phase + bias (ambiguity) (cycle/sqrt(s)) */ + + double sigma_iono = configuration->property(role + ".sigma_iono", 1e-3); /* Set the process noise standard deviation of vertical ionospheric delay per 10 km baseline (m/sqrt(s)). */ + + double sigma_trop = configuration->property(role + ".sigma_trop", 1e-4); /* Set the process noise standard deviation of zenith tropospheric delay (m/sqrt(s)). */ + + double sigma_acch = configuration->property(role + ".sigma_acch", 1e-1); /* Set the process noise standard deviation of the receiver acceleration as + the horizontal component. (m/s2/sqrt(s)). If Receiver Dynamics is set to OFF, they are not used. */ + + double sigma_accv = configuration->property(role + ".sigma_accv", 1e-2); /* Set the process noise standard deviation of the receiver acceleration as + the vertical component. (m/s2/sqrt(s)). If Receiver Dynamics is set to OFF, they are not used. */ + + double sigma_pos = configuration->property(role + ".sigma_pos", 0.0); + + double code_phase_error_ratio_l1 = configuration->property(role + ".code_phase_error_ratio_l1", 100.0); + double code_phase_error_ratio_l2 = configuration->property(role + ".code_phase_error_ratio_l2", 100.0); + double code_phase_error_ratio_l5 = configuration->property(role + ".code_phase_error_ratio_l5", 100.0); + double carrier_phase_error_factor_a = configuration->property(role + ".carrier_phase_error_factor_a", 0.003); + double carrier_phase_error_factor_b = configuration->property(role + ".carrier_phase_error_factor_b", 0.003); + + snrmask_t snrmask = {{}, {{}, {}}}; + + prcopt_t rtklib_configuration_options = { + positioning_mode, /* positioning mode (PMODE_XXX) see src/algorithms/libs/rtklib/rtklib.h */ + 0, /* solution type (0:forward,1:backward,2:combined) */ + number_of_frequencies, /* number of frequencies (1:L1, 2:L1+L2, 3:L1+L2+L5)*/ + navigation_system, /* navigation system */ + elevation_mask * D2R, /* elevation mask angle (degrees) */ + snrmask, /* snrmask_t snrmask SNR mask */ + 0, /* satellite ephemeris/clock (EPHOPT_XXX) */ + integer_ambiguity_resolution_gps, /* AR mode (0:off,1:continuous,2:instantaneous,3:fix and hold,4:ppp-ar) */ + integer_ambiguity_resolution_glo, /* GLONASS AR mode (0:off,1:on,2:auto cal,3:ext cal) */ + integer_ambiguity_resolution_bds, /* BeiDou AR mode (0:off,1:on) */ + outage_reset_ambiguity, /* obs outage count to reset bias */ + min_lock_to_fix_ambiguity, /* min lock count to fix ambiguity */ + 10, /* min fix count to hold ambiguity */ + 1, /* max iteration to resolve ambiguity */ + iono_model, /* ionosphere option (IONOOPT_XXX) */ + trop_model, /* troposphere option (TROPOPT_XXX) */ + dynamics_model, /* dynamics model (0:none, 1:velocity, 2:accel) */ + earth_tide, /* earth tide correction (0:off,1:solid,2:solid+otl+pole) */ + number_filter_iter, /* number of filter iteration */ + 0, /* code smoothing window size (0:none) */ + 0, /* interpolate reference obs (for post mission) */ + 0, /* sbssat_t sbssat SBAS correction options */ + 0, /* sbsion_t sbsion[MAXBAND+1] SBAS satellite selection (0:all) */ + 0, /* rover position for fixed mode */ + 0, /* base position for relative mode */ + /* 0:pos in prcopt, 1:average of single pos, */ + /* 2:read from file, 3:rinex header, 4:rtcm pos */ + {code_phase_error_ratio_l1, code_phase_error_ratio_l2, code_phase_error_ratio_l5}, /* eratio[NFREQ] code/phase error ratio */ + {100.0, carrier_phase_error_factor_a, carrier_phase_error_factor_b, 0.0, 1.0}, /* err[5]: measurement error factor [0]:reserved, [1-3]:error factor a/b/c of phase (m) , [4]:doppler frequency (hz) */ + {bias_0, iono_0, trop_0}, /* std[3]: initial-state std [0]bias,[1]iono [2]trop*/ + {sigma_bias, sigma_iono, sigma_trop, sigma_acch, sigma_accv, sigma_pos}, /* prn[6] process-noise std */ + 5e-12, /* sclkstab: satellite clock stability (sec/sec) */ + {min_ratio_to_fix_ambiguity, 0.9999, 0.25, 0.1, 0.05, 0.0, 0.0, 0.0}, /* thresar[8]: AR validation threshold */ + min_elevation_to_fix_ambiguity, /* elevation mask of AR for rising satellite (deg) */ + 0.0, /* elevation mask to hold ambiguity (deg) */ + slip_threshold, /* slip threshold of geometry-free phase (m) */ + 30.0, /* max difference of time (sec) */ + threshold_reject_innovation, /* reject threshold of innovation (m) */ + threshold_reject_gdop, /* reject threshold of gdop */ + {}, /* double baseline[2] baseline length constraint {const,sigma} (m) */ + {}, /* double ru[3] rover position for fixed mode {x,y,z} (ecef) (m) */ + {}, /* double rb[3] base position for relative mode {x,y,z} (ecef) (m) */ + {"", ""}, /* char anttype[2][MAXANT] antenna types {rover,base} */ + {{}, {}}, /* double antdel[2][3] antenna delta {{rov_e,rov_n,rov_u},{ref_e,ref_n,ref_u}} */ + {}, /* pcv_t pcvr[2] receiver antenna parameters {rov,base} */ + {}, /* unsigned char exsats[MAXSAT] excluded satellites (1:excluded, 2:included) */ + 0, /* max averaging epoches */ + 0, /* initialize by restart */ + 1, /* output single by dgps/float/fix/ppp outage */ + {"", ""}, /* char rnxopt[2][256] rinex options {rover,base} */ + {sat_PCV, rec_PCV, phwindup, reject_GPS_IIA, raim_fde}, /* posopt[6] positioning options [0]: satellite and receiver antenna PCV model; [1]: interpolate antenna parameters; [2]: apply phase wind-up correction for PPP modes; [3]: exclude measurements of GPS Block IIA satellites satellite [4]: RAIM FDE (fault detection and exclusion) [5]: handle day-boundary clock jump */ + 0, /* solution sync mode (0:off,1:on) */ + {{}, {}}, /* odisp[2][6*11] ocean tide loading parameters {rov,base} */ + {{}, {{}, {}}, {{}, {}}, {}, {}}, /* exterr_t exterr extended receiver error model */ + 0, /* disable L2-AR */ + {} /* char pppopt[256] ppp option "-GAP_RESION=" default gap to reset iono parameters (ep) */ + }; + + rtk_t rtk; + rtkinit(&rtk, &rtklib_configuration_options); + return rtk; +} + + +//todo: add test cases for Galileo E1, E5 and GPS L5 +TEST(RTKLibSolverTest, test1) +{ + //test case #1: GPS L1 CA simulated with gnss-sim + std::string path = std::string(TEST_PATH); + int nchannels = 8; + std::string dump_filename = ".rtklib_solver_dump.dat"; + bool flag_dump_to_file = false; + bool save_to_mat = false; + rtk_t rtk = configure_rtklib_options(); + + std::unique_ptr d_ls_pvt(new rtklib_solver(nchannels, dump_filename, flag_dump_to_file, save_to_mat, rtk)); + d_ls_pvt->set_averaging_depth(1); + + // load ephemeris + std::string eph_xml_filename = path + "data/rtklib_test/eph_GPS_L1CA_test1.xml"; + gnss_sdr_supl_client supl_client_ephemeris_; + + std::cout << "SUPL: Try read GPS ephemeris from XML file " << eph_xml_filename << std::endl; + if (supl_client_ephemeris_.load_ephemeris_xml(eph_xml_filename) == true) + { + std::map::const_iterator gps_eph_iter; + for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.cbegin(); + gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); + gps_eph_iter++) + { + std::cout << "SUPL: Read XML Ephemeris for GPS SV " << gps_eph_iter->first << std::endl; + std::shared_ptr tmp_obj = std::make_shared(gps_eph_iter->second); + // update/insert new ephemeris record to the global ephemeris map + d_ls_pvt->gps_ephemeris_map[gps_eph_iter->first] = *tmp_obj; + } + } + else + { + std::cout << "ERROR: SUPL client error reading XML" << std::endl; + } + + // insert observables epoch + std::map gnss_synchro_map; + // Gnss_Synchro tmp_obs; + // tmp_obs.System = 'G'; + // std::string signal = "1C"; + // const char* str = signal.c_str(); // get a C style null terminated string + // std::memcpy(static_cast(tmp_obs.Signal), str, 3); // copy string into synchro char array: 2 char + null + // + // gnss_synchro_map[0] = tmp_obs; + // gnss_synchro_map[0].PRN = 1; + + //load from xml (boost serialize) + std::string file_name = path + "data/rtklib_test/obs_test1.xml"; + + std::ifstream ifs; + try + { + ifs.open(file_name.c_str(), std::ifstream::binary | std::ifstream::in); + boost::archive::xml_iarchive xml(ifs); + gnss_synchro_map.clear(); + xml >> boost::serialization::make_nvp("GNSS-SDR_gnss_synchro_map", gnss_synchro_map); + std::cout << "Loaded gnss_synchro map data with " << gnss_synchro_map.size() << " pseudoranges" << std::endl; + } + catch (std::exception& e) + { + std::cout << e.what() << "File: " << file_name; + } + ifs.close(); + + // solve + bool pvt_valid = false; + if (d_ls_pvt->get_PVT(gnss_synchro_map, false)) + { + // DEBUG MESSAGE: Display position in console output + if (d_ls_pvt->is_valid_position()) + { + std::streamsize ss = std::cout.precision(); // save current precision + std::cout.setf(std::ios::fixed, std::ios::floatfield); + + auto facet = new boost::posix_time::time_facet("%Y-%b-%d %H:%M:%S.%f %z"); + std::cout.imbue(std::locale(std::cout.getloc(), facet)); + + std::cout << "Position at " << d_ls_pvt->get_position_UTC_time() + << " UTC using " << d_ls_pvt->get_num_valid_observations() + << std::fixed << std::setprecision(9) + << " observations is Lat = " << d_ls_pvt->get_latitude() << " [deg], Long = " << d_ls_pvt->get_longitude() + << std::fixed << std::setprecision(3) + << " [deg], Height = " << d_ls_pvt->get_height() << " [m]" << std::endl; + std::cout << std::setprecision(ss); + std::cout << "RX clock offset: " << d_ls_pvt->get_time_offset_s() << "[s]" << std::endl; + + // boost::posix_time::ptime p_time; + // gtime_t rtklib_utc_time = gpst2time(adjgpsweek(d_ls_pvt->gps_ephemeris_map.cbegin()->second.i_GPS_week), d_rx_time); + // p_time = boost::posix_time::from_time_t(rtklib_utc_time.time); + // p_time += boost::posix_time::microseconds(round(rtklib_utc_time.sec * 1e6)); + // std::cout << TEXT_MAGENTA << "Observable RX time (GPST) " << boost::posix_time::to_simple_string(p_time) << TEXT_RESET << std::endl; + + std::cout << "RTKLIB Position at RX TOW = " << gnss_synchro_map.begin()->second.RX_time + << " in ECEF (X,Y,Z,t[meters]) = " << std::fixed << std::setprecision(16) + << d_ls_pvt->pvt_sol.rr[0] << "," + << d_ls_pvt->pvt_sol.rr[1] << "," + << d_ls_pvt->pvt_sol.rr[2] << std::endl; + /* std::cout << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_ls_pvt->get_position_UTC_time()) + << " UTC using "<< d_ls_pvt->get_num_valid_observations() <<" observations is HDOP = " << d_ls_pvt->get_hdop() << " VDOP = " + << d_ls_pvt->get_vdop() + << " GDOP = " << d_ls_pvt->get_gdop() << std::endl; */ + + //todo: check here the positioning error against the reference position generated with gnss-sim + //reference position on in WGS84: Lat (deg), Long (deg) , H (m): 30.286502,120.032669,100 + arma::vec LLH = {30.286502, 120.032669, 100}; //ref position for this scenario + + double error_LLH_m = great_circle_distance(LLH(0), LLH(1), d_ls_pvt->get_latitude(), d_ls_pvt->get_longitude()); + std::cout << "Lat, Long, H error: " << d_ls_pvt->get_latitude() - LLH(0) + << "," << d_ls_pvt->get_longitude() - LLH(1) + << "," << d_ls_pvt->get_height() - LLH(2) << " [deg,deg,meters]" << std::endl; + + std::cout << "Haversine Great Circle error LLH distance: " << error_LLH_m << " [meters]" << std::endl; + + arma::vec v_eb_n = {0.0, 0.0, 0.0}; + arma::vec true_r_eb_e; + arma::vec true_v_eb_e; + pv_Geo_to_ECEF(degtorad(LLH(0)), degtorad(LLH(1)), LLH(2), v_eb_n, true_r_eb_e, true_v_eb_e); + + arma::vec measured_r_eb_e = {d_ls_pvt->pvt_sol.rr[0], d_ls_pvt->pvt_sol.rr[1], d_ls_pvt->pvt_sol.rr[2]}; + + arma::vec error_r_eb_e = measured_r_eb_e - true_r_eb_e; + + std::cout << "ECEF position error vector: " << error_r_eb_e << " [meters]" << std::endl; + + double error_3d_m = arma::norm(error_r_eb_e, 2); + + std::cout << "3D positioning error: " << error_3d_m << " [meters]" << std::endl; + + //check results against the test tolerance + ASSERT_LT(error_3d_m, 0.2); + pvt_valid = true; + } + } + + EXPECT_EQ(true, pvt_valid); +} diff --git a/src/tests/unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_test.cc b/src/tests/unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_test.cc index 8dc1ef42c..55c49c568 100644 --- a/src/tests/unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_test.cc @@ -34,7 +34,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include "gnss_sdr_valve.h" diff --git a/src/tests/unit-tests/signal-processing-blocks/resampler/mmse_resampler_test.cc b/src/tests/unit-tests/signal-processing-blocks/resampler/mmse_resampler_test.cc index 1292f93dc..c00561eb3 100644 --- a/src/tests/unit-tests/signal-processing-blocks/resampler/mmse_resampler_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/resampler/mmse_resampler_test.cc @@ -32,7 +32,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include "gnss_sdr_valve.h" diff --git a/src/tests/unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc b/src/tests/unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc index 26a57621e..41c10d607 100644 --- a/src/tests/unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc @@ -33,7 +33,11 @@ #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include "gnss_sdr_valve.h" diff --git a/src/tests/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc b/src/tests/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc index 9229f16be..68891bff0 100644 --- a/src/tests/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc @@ -33,9 +33,14 @@ #include #include +#ifdef GR_GREATER_38 +#include +#include +#else #include #include #include +#endif #include #include "unpack_2bit_samples.h" diff --git a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc new file mode 100644 index 000000000..1db19d4a7 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc @@ -0,0 +1,288 @@ +/*! + * \file galileo_fnav_inav_decoder_test.cc + * \brief This class implements the unit test for the Galileo FNAV and INAV frames + * according to the Galileo ICD + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2012-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "galileo_navigation_message.h" +#include "galileo_fnav_message.h" +#include "convolutional.h" +#include +#include +#include +#include +#include +#include +#include + + +class Galileo_FNAV_INAV_test : public ::testing::Test +{ +public: + Galileo_Navigation_Message INAV_decoder; + Galileo_Fnav_Message FNAV_decoder; + // vars for Viterbi decoder + int32_t *out0, *out1, *state0, *state1; + int32_t g_encoder[2]; + const int32_t nn = 2; // Coding rate 1/n + const int32_t KK = 7; // Constraint Length + int32_t mm = KK - 1; + int32_t flag_even_word_arrived; + void viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits, int32_t _datalength) + { + Viterbi(page_part_bits, out0, state0, out1, state1, + page_part_symbols, KK, nn, _datalength); + } + + + void deinterleaver(int32_t rows, int32_t cols, double *in, double *out) + { + for (int32_t r = 0; r < rows; r++) + { + for (int32_t c = 0; c < cols; c++) + { + out[c * rows + r] = in[r * cols + c]; + } + } + } + + + bool decode_INAV_word(double *page_part_symbols, int32_t frame_length) + { + // 1. De-interleave + double *page_part_symbols_deint = static_cast(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment())); + deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS, GALILEO_INAV_INTERLEAVER_COLS, page_part_symbols, page_part_symbols_deint); + + // 2. Viterbi decoder + // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) + // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180º + for (int32_t i = 0; i < frame_length; i++) + { + if ((i + 1) % 2 == 0) + { + page_part_symbols_deint[i] = -page_part_symbols_deint[i]; + } + } + + int32_t *page_part_bits = static_cast(volk_gnsssdr_malloc((frame_length / 2) * sizeof(int32_t), volk_gnsssdr_get_alignment())); + + const int32_t CodeLength = 240; + int32_t DataLength = (CodeLength / nn) - mm; + viterbi_decoder(page_part_symbols_deint, page_part_bits, DataLength); + volk_gnsssdr_free(page_part_symbols_deint); + + // 3. Call the Galileo page decoder + std::string page_String; + for (int32_t i = 0; i < (frame_length / 2); i++) + { + if (page_part_bits[i] > 0) + { + page_String.push_back('1'); + } + else + { + page_String.push_back('0'); + } + } + + bool crc_ok = false; + if (page_part_bits[0] == 1) + { + // DECODE COMPLETE WORD (even + odd) and TEST CRC + INAV_decoder.split_page(page_String, flag_even_word_arrived); + if (INAV_decoder.flag_CRC_test == true) + { + std::cout << "Galileo E1 INAV PAGE CRC correct \n"; + //std::cout << "Galileo E1 CRC correct on channel " << d_channel << " from satellite " << d_satellite << std::endl; + crc_ok = true; + } + flag_even_word_arrived = 0; + } + else + { + // STORE HALF WORD (even page) + INAV_decoder.split_page(page_String.c_str(), flag_even_word_arrived); + flag_even_word_arrived = 1; + } + volk_gnsssdr_free(page_part_bits); + return crc_ok; + } + + bool decode_FNAV_word(double *page_symbols, int32_t frame_length) + { + // 1. De-interleave + double *page_symbols_deint = static_cast(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment())); + deinterleaver(GALILEO_FNAV_INTERLEAVER_ROWS, GALILEO_FNAV_INTERLEAVER_COLS, page_symbols, page_symbols_deint); + + // 2. Viterbi decoder + // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) + // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180 + for (int32_t i = 0; i < frame_length; i++) + { + if ((i + 1) % 2 == 0) + { + page_symbols_deint[i] = -page_symbols_deint[i]; + } + } + int32_t *page_bits = static_cast(volk_gnsssdr_malloc((frame_length / 2) * sizeof(int32_t), volk_gnsssdr_get_alignment())); + + const int32_t CodeLength = 488; + int32_t DataLength = (CodeLength / nn) - mm; + viterbi_decoder(page_symbols_deint, page_bits, DataLength); + + volk_gnsssdr_free(page_symbols_deint); + + // 3. Call the Galileo page decoder + std::string page_String; + for (int32_t i = 0; i < frame_length; i++) + { + if (page_bits[i] > 0) + { + page_String.push_back('1'); + } + else + { + page_String.push_back('0'); + } + } + volk_gnsssdr_free(page_bits); + + // DECODE COMPLETE WORD (even + odd) and TEST CRC + FNAV_decoder.split_page(page_String); + if (FNAV_decoder.flag_CRC_test == true) + { + std::cout << "Galileo E5a FNAV PAGE CRC correct \n"; + return true; + } + else + { + return false; + } + } + + Galileo_FNAV_INAV_test() + { + // vars for Viterbi decoder + int32_t max_states = 1 << mm; // 2^mm + g_encoder[0] = 121; // Polynomial G1 + g_encoder[1] = 91; // Polynomial G2 + out0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + out1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + state0 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + state1 = static_cast(volk_gnsssdr_malloc(max_states * sizeof(int32_t), volk_gnsssdr_get_alignment())); + // create appropriate transition matrices + nsc_transit(out0, state0, 0, g_encoder, KK, nn); + nsc_transit(out1, state1, 1, g_encoder, KK, nn); + flag_even_word_arrived = 0; + } + + ~Galileo_FNAV_INAV_test() + { + volk_gnsssdr_free(out0); + volk_gnsssdr_free(out1); + volk_gnsssdr_free(state0); + volk_gnsssdr_free(state1); + } +}; + +TEST_F(Galileo_FNAV_INAV_test, ValidationOfResults) +{ + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds(0); + start = std::chrono::system_clock::now(); + int repetitions = 10; + // FNAV FULLY ENCODED FRAME + double FNAV_frame[488] = {-1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, + -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, + -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, + -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, + -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, + -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, + -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, + 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, + -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, + 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, + -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, + 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, + 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1}; + + ASSERT_NO_THROW({ + for (int n = 0; n < repetitions; n++) + { + EXPECT_EQ(decode_FNAV_word(&FNAV_frame[0], 488), true); + } + }) << "Exception during FNAV frame decoding"; + + + // INAV FULLY ENCODED FRAME + double INAV_frame_even[240] = {-1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, + -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, + 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, + -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1}; + + double INAV_frame_odd[240] = {1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, + 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, + -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, + 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, + -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, + 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, + -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, + -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1}; + + ASSERT_NO_THROW({ + for (int n = 0; n < repetitions; n++) + { + decode_INAV_word(&INAV_frame_even[0], 240); + EXPECT_EQ(decode_INAV_word(&INAV_frame_odd[0], 240), true); + } + }) << "Exception during INAV frame decoding"; + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + std::cout << "Galileo FNAV/INAV Test completed in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; +} diff --git a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc index fb502d71b..22a1118d9 100644 --- a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc @@ -38,7 +38,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -87,7 +91,7 @@ void GpsL1CADllPllTelemetryDecoderTest_msg_rx::msg_handler_events(pmt::pmt_t msg { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast& e) @@ -140,7 +144,7 @@ void GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx::msg_handler_events(pmt::pmt_t { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast& e) @@ -418,7 +422,7 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) //check results //load the true values - long int nepoch = true_obs_data.num_epochs(); + int64_t nepoch = true_obs_data.num_epochs(); std::cout << "True observation epochs=" << nepoch << std::endl; arma::vec true_timestamp_s = arma::zeros(nepoch, 1); @@ -427,7 +431,7 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) arma::vec true_prn_delay_chips = arma::zeros(nepoch, 1); arma::vec true_tow_s = arma::zeros(nepoch, 1); - long int epoch_counter = 0; + int64_t epoch_counter = 0; while (true_obs_data.read_binary_obs()) { true_timestamp_s(epoch_counter) = true_obs_data.signal_timestamp_s; diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/bayesian_estimation_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/bayesian_estimation_test.cc new file mode 100644 index 000000000..f32e82f16 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/bayesian_estimation_test.cc @@ -0,0 +1,69 @@ +/*! + * \file bayesian_estimation_positivity_test.cc + * \brief This file implements timing tests for the Bayesian covariance estimator + * \author Gerald LaMountain, 20168. gerald(at)ece.neu.edu + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include "bayesian_estimation.h" + +#define BAYESIAN_TEST_N_TRIALS 100 +#define BAYESIAN_TEST_ITER 10000 + +TEST(BayesianEstimationPositivityTest, BayesianPositivityTest) +{ + Bayesian_estimator bayes; + arma::vec bayes_mu = arma::zeros(1, 1); + int bayes_nu = 0; + int bayes_kappa = 0; + arma::mat bayes_Psi = arma::ones(1, 1); + arma::vec input = arma::zeros(1, 1); + + //--- Perform initializations ------------------------------ + + std::random_device r; + std::default_random_engine e1(r()); + std::normal_distribution normal_dist(0, 5); + + for (int k = 0; k < BAYESIAN_TEST_N_TRIALS; k++) + { + bayes.init(bayes_mu, bayes_kappa, bayes_nu, bayes_Psi); + + for (int n = 0; n < BAYESIAN_TEST_ITER; n++) + { + input(0) = static_cast(normal_dist(e1)); + bayes.update_sequential(input); + + arma::mat output = bayes.get_Psi_est(); + double output0 = output(0, 0); + ASSERT_EQ(output0 > 0.0, true); + } + } +} diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc index 1be7bbe49..3b0c24883 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc @@ -49,6 +49,7 @@ void run_correlator_cpu_real_codes(cpu_multicorrelator_real_codes* correlator, float d_rem_carrier_phase_rad, float d_carrier_phase_step_rad, float d_code_phase_step_chips, + float d_code_phase_rate_step_chips, float d_rem_code_phase_chips, int correlation_size) { @@ -58,6 +59,7 @@ void run_correlator_cpu_real_codes(cpu_multicorrelator_real_codes* correlator, d_carrier_phase_step_rad, d_code_phase_step_chips, d_rem_code_phase_chips, + d_code_phase_rate_step_chips, correlation_size); } } @@ -125,6 +127,7 @@ TEST(CpuMulticorrelatorRealCodesTest, MeasureExecutionTime) float d_rem_carrier_phase_rad = 0.0; float d_carrier_phase_step_rad = 0.1; float d_code_phase_step_chips = 0.3; + float d_code_phase_rate_step_chips = 0.00001; float d_rem_code_phase_chips = 0.4; EXPECT_NO_THROW( @@ -141,6 +144,7 @@ TEST(CpuMulticorrelatorRealCodesTest, MeasureExecutionTime) d_rem_carrier_phase_rad, d_carrier_phase_step_rad, d_code_phase_step_chips, + d_code_phase_rate_step_chips, d_rem_code_phase_chips, correlation_sizes[correlation_sizes_idx])); } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc index 55b2e80f8..fb61cd4bd 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc @@ -35,7 +35,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc index 2aad4e5bd..9c6d274f7 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc @@ -35,7 +35,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc index a8210f19a..352c837e1 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc @@ -35,7 +35,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -77,7 +81,7 @@ void GlonassL1CaDllPllCAidTrackingTest_msg_rx::msg_handler_events(pmt::pmt_t msg { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast& e) diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc index bd1ec45f0..6503e30db 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc @@ -35,7 +35,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -77,7 +81,7 @@ void GlonassL1CaDllPllTrackingTest_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast& e) diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index 523be87a3..3484fc791 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -34,11 +34,16 @@ #include #include #include +#include #include #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -85,7 +90,7 @@ void GpsL1CADllPllTrackingTest_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; //3 -> loss of lock //std::cout << "Received trk message: " << rx_message << std::endl; } @@ -136,20 +141,24 @@ public: arma::vec& meas_time_s, arma::vec& meas_value, double& mean_error, - double& std_dev_error); + double& std_dev_error, + double& rmse); std::vector check_results_acc_carrier_phase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, arma::vec& meas_value, double& mean_error, - double& std_dev_error); + double& std_dev_error, + double& rmse); std::vector check_results_codephase(arma::vec& true_time_s, arma::vec& true_value, arma::vec& meas_time_s, arma::vec& meas_value, double& mean_error, - double& std_dev_error); + double& std_dev_error, + double& rmse); + bool save_mat_xy(std::vector& x, std::vector& y, std::string filename); GpsL1CADllPllTrackingTest() { factory = std::make_shared(); @@ -267,7 +276,8 @@ std::vector GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& arma::vec& meas_time_s, arma::vec& meas_value, double& mean_error, - double& std_dev_error) + double& std_dev_error, + double& rmse) { // 1. True value interpolation to match the measurement times arma::vec true_value_interp; @@ -289,7 +299,7 @@ std::vector GpsL1CADllPllTrackingTest::check_results_doppler(arma::vec& std::vector err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows); arma::vec err2 = arma::square(err); - double rmse = sqrt(arma::mean(err2)); + rmse = sqrt(arma::mean(err2)); // 3. Mean err and variance double error_mean = arma::mean(err); @@ -317,7 +327,8 @@ std::vector GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(a arma::vec& meas_time_s, arma::vec& meas_value, double& mean_error, - double& std_dev_error) + double& std_dev_error, + double& rmse) { // 1. True value interpolation to match the measurement times arma::vec true_value_interp; @@ -332,12 +343,13 @@ std::vector GpsL1CADllPllTrackingTest::check_results_acc_carrier_phase(a // 2. RMSE arma::vec err; - err = meas_value - true_value_interp; + //it is required to remove the initial offset in the accumulated carrier phase error + err = (meas_value - meas_value(0)) - (true_value_interp - true_value_interp(0)); arma::vec err2 = arma::square(err); //conversion between arma::vec and std:vector std::vector err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows); - double rmse = sqrt(arma::mean(err2)); + rmse = sqrt(arma::mean(err2)); // 3. Mean err and variance double error_mean = arma::mean(err); @@ -364,7 +376,8 @@ std::vector GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec arma::vec& meas_time_s, arma::vec& meas_value, double& mean_error, - double& std_dev_error) + double& std_dev_error, + double& rmse) { // 1. True value interpolation to match the measurement times arma::vec true_value_interp; @@ -385,7 +398,7 @@ std::vector GpsL1CADllPllTrackingTest::check_results_codephase(arma::vec std::vector err_std_vector(err.colptr(0), err.colptr(0) + err.n_rows); arma::vec err2 = arma::square(err); - double rmse = sqrt(arma::mean(err2)); + rmse = sqrt(arma::mean(err2)); // 3. Mean err and variance double error_mean = arma::mean(err); @@ -420,12 +433,15 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) //data containers for config param sweep std::vector> mean_doppler_error_sweep; //swep config param and cn0 sweep std::vector> std_dev_doppler_error_sweep; //swep config param and cn0 sweep + std::vector> rmse_doppler_sweep; //swep config param and cn0 sweep std::vector> mean_code_phase_error_sweep; //swep config param and cn0 sweep std::vector> std_dev_code_phase_error_sweep; //swep config param and cn0 sweep + std::vector> rmse_code_phase_sweep; //swep config param and cn0 sweep std::vector> mean_carrier_phase_error_sweep; //swep config param and cn0 sweep std::vector> std_dev_carrier_phase_error_sweep; //swep config param and cn0 sweep + std::vector> rmse_carrier_phase_sweep; //swep config param and cn0 sweep std::vector> trk_valid_timestamp_s_sweep; std::vector> generator_CN0_values_sweep_copy; @@ -528,14 +544,18 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std::vector> doppler_error_sweep; std::vector> code_phase_error_sweep; + std::vector> code_phase_error_meters_sweep; std::vector> acc_carrier_phase_error_sweep; std::vector mean_doppler_error; std::vector std_dev_doppler_error; + std::vector rmse_doppler; std::vector mean_code_phase_error; std::vector std_dev_code_phase_error; + std::vector rmse_code_phase; std::vector mean_carrier_phase_error; std::vector std_dev_carrier_phase_error; + std::vector rmse_carrier_phase; std::vector valid_CN0_values; configure_receiver(PLL_wide_bw_values.at(config_idx), @@ -631,7 +651,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) ASSERT_EQ(trk_dump.open_obs_file(std::string("./tracking_ch_0.dat")), true) << "Failure opening tracking dump file"; - long int n_measured_epochs = trk_dump.num_epochs(); + int64_t n_measured_epochs = trk_dump.num_epochs(); //std::cout << "Measured observation epochs=" << n_measured_epochs << std::endl; arma::vec trk_timestamp_s = arma::zeros(n_measured_epochs, 1); @@ -639,7 +659,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) arma::vec trk_Doppler_Hz = arma::zeros(n_measured_epochs, 1); arma::vec trk_prn_delay_chips = arma::zeros(n_measured_epochs, 1); - long int epoch_counter = 0; + int64_t epoch_counter = 0; std::vector timestamp_s; std::vector prompt; @@ -682,12 +702,13 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { std::vector doppler_error_hz; std::vector code_phase_error_chips; + std::vector code_phase_error_meters; std::vector acc_carrier_phase_hz; try { // load the true values - long int n_true_epochs = true_obs_data.num_epochs(); + int64_t n_true_epochs = true_obs_data.num_epochs(); //std::cout << "True observation epochs=" << n_true_epochs << std::endl; arma::vec true_timestamp_s = arma::zeros(n_true_epochs, 1); @@ -696,7 +717,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) arma::vec true_prn_delay_chips = arma::zeros(n_true_epochs, 1); arma::vec true_tow_s = arma::zeros(n_true_epochs, 1); - long int epoch_counter = 0; + int64_t epoch_counter = 0; while (true_obs_data.read_binary_obs()) { true_timestamp_s(epoch_counter) = true_obs_data.signal_timestamp_s; @@ -707,7 +728,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) epoch_counter++; } // Align initial measurements and cut the tracking pull-in transitory - double pull_in_offset_s = 1.0; + double pull_in_offset_s = FLAGS_skip_trk_transitory_s; arma::uvec initial_meas_point = arma::find(trk_timestamp_s >= (true_timestamp_s(0) + pull_in_offset_s), 1, "first"); if (initial_meas_point.size() > 0 and tracking_last_msg != 3) @@ -720,20 +741,28 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) double mean_error; double std_dev_error; + double rmse; valid_CN0_values.push_back(generator_CN0_values.at(current_cn0_idx)); //save the current cn0 value (valid tracking) - doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz, mean_error, std_dev_error); + doppler_error_hz = check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz, mean_error, std_dev_error, rmse); mean_doppler_error.push_back(mean_error); std_dev_doppler_error.push_back(std_dev_error); + rmse_doppler.push_back(rmse); - code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error); + code_phase_error_chips = check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips, mean_error, std_dev_error, rmse); + for (unsigned int ii = 0; ii < code_phase_error_chips.size(); ii++) + { + code_phase_error_meters.push_back(GPS_L1_CA_CHIP_PERIOD * code_phase_error_chips.at(ii) * GPS_C_m_s); + } mean_code_phase_error.push_back(mean_error); std_dev_code_phase_error.push_back(std_dev_error); + rmse_code_phase.push_back(rmse); - acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles, mean_error, std_dev_error); + acc_carrier_phase_hz = check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles, mean_error, std_dev_error, rmse); mean_carrier_phase_error.push_back(mean_error); std_dev_carrier_phase_error.push_back(std_dev_error); + rmse_carrier_phase.push_back(rmse); //save tracking measurement timestamps to std::vector std::vector vector_trk_timestamp_s(trk_timestamp_s.colptr(0), trk_timestamp_s.colptr(0) + trk_timestamp_s.n_rows); @@ -741,6 +770,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) doppler_error_sweep.push_back(doppler_error_hz); code_phase_error_sweep.push_back(code_phase_error_chips); + code_phase_error_meters_sweep.push_back(code_phase_error_meters); acc_carrier_phase_error_sweep.push_back(acc_carrier_phase_hz); } else @@ -760,10 +790,16 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { mean_doppler_error_sweep.push_back(mean_doppler_error); std_dev_doppler_error_sweep.push_back(std_dev_doppler_error); + rmse_doppler_sweep.push_back(rmse_doppler); + mean_code_phase_error_sweep.push_back(mean_code_phase_error); std_dev_code_phase_error_sweep.push_back(std_dev_code_phase_error); + rmse_code_phase_sweep.push_back(rmse_code_phase); + mean_carrier_phase_error_sweep.push_back(mean_carrier_phase_error); std_dev_carrier_phase_error_sweep.push_back(std_dev_carrier_phase_error); + rmse_carrier_phase_sweep.push_back(rmse_carrier_phase); + //make a copy of the CN0 vector for each configuration parameter in order to filter the loss of lock events generator_CN0_values_sweep_copy.push_back(valid_CN0_values); } @@ -795,7 +831,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { Gnuplot g1("linespoints"); - if (FLAGS_show_plots) g1.showonscreen(); // window output + if (FLAGS_show_plots) + { + g1.showonscreen(); // window output + } + else + { + g1.disablescreen(); + } g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g1.set_grid(); g1.set_xlabel("Time [s]"); @@ -809,7 +852,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); } Gnuplot g2("points"); - if (FLAGS_show_plots) g2.showonscreen(); // window output + if (FLAGS_show_plots) + { + g2.showonscreen(); // window output + } + else + { + g2.disablescreen(); + } g2.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), ceil(static_cast(generator_CN0_values.size()) / 2)); for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) @@ -840,7 +890,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g3.set_legend(); g3.savetops("CN0_output"); g3.savetopdf("CN0_output", 18); - if (FLAGS_show_plots) g3.showonscreen(); // window output + if (FLAGS_show_plots) + { + g3.showonscreen(); // window output + } + else + { + g3.disablescreen(); + } } //PLOT ERROR FIGURES (only if it is used the signal generator) @@ -849,7 +906,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) if (FLAGS_plot_detail_level >= 1) { Gnuplot g5("points"); - if (FLAGS_show_plots) g5.showonscreen(); // window output + if (FLAGS_show_plots) + { + g5.showonscreen(); // window output + } + else + { + g5.disablescreen(); + } g5.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g5.set_grid(); g5.set_xlabel("Time [s]"); @@ -866,15 +930,61 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) catch (const GnuplotException& ge) { } + save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), + code_phase_error_sweep.at(current_cn0_idx), + "Code_error_chips" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + + std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx))); } g5.set_legend(); g5.set_legend(); - g5.savetops("Code_error_output"); - g5.savetopdf("Code_error_output", 18); + g5.savetops("Code_error_chips"); + g5.savetopdf("Code_error_chips", 18); + + Gnuplot g5b("points"); + if (FLAGS_show_plots) + { + g5b.showonscreen(); // window output + } + else + { + g5b.disablescreen(); + } + g5b.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g5b.set_grid(); + g5b.set_xlabel("Time [s]"); + g5b.set_ylabel("Code delay error [meters]"); + + + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++) + { + try + { + g5b.plot_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), code_phase_error_meters_sweep.at(current_cn0_idx), + std::to_string(static_cast(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz]", decimate); + } + catch (const GnuplotException& ge) + { + } + save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), + code_phase_error_sweep.at(current_cn0_idx), + "Code_error_meters" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + + std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx))); + } + g5b.set_legend(); + g5b.set_legend(); + g5b.savetops("Code_error_meters"); + g5b.savetopdf("Code_error_meters", 18); Gnuplot g6("points"); - if (FLAGS_show_plots) g6.showonscreen(); // window output + if (FLAGS_show_plots) + { + g6.showonscreen(); // window output + } + else + { + g6.disablescreen(); + } g6.set_title("Accumulated carrier phase error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g6.set_grid(); g6.set_xlabel("Time [s]"); @@ -891,20 +1001,31 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) catch (const GnuplotException& ge) { } + save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), + acc_carrier_phase_error_sweep.at(current_cn0_idx), + "Carrier_phase_error" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + + std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx))); } g6.set_legend(); g6.set_legend(); - g6.savetops("Carrier_phase_error_output"); - g6.savetopdf("Carrier_phase_error_output", 18); + g6.savetops("Acc_carrier_phase_error_cycles"); + g6.savetopdf("Acc_carrier_phase_error_cycles", 18); Gnuplot g4("points"); - if (FLAGS_show_plots) g4.showonscreen(); // window output + if (FLAGS_show_plots) + { + g4.showonscreen(); // window output + } + else + { + g4.disablescreen(); + } g4.set_multiplot(ceil(static_cast(generator_CN0_values.size()) / 2.0), ceil(static_cast(generator_CN0_values.size()) / 2)); for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++) { g4.reset_plot(); - g4.set_title(std::to_string(static_cast(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz], PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g4.set_title("Dopper error" + std::to_string(static_cast(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz], PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g4.set_grid(); //g4.cmd("set key box opaque"); g4.set_xlabel("Time [s]"); @@ -917,10 +1038,15 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) catch (const GnuplotException& ge) { } + + save_mat_xy(trk_valid_timestamp_s_sweep.at(current_cn0_idx), + doppler_error_sweep.at(current_cn0_idx), + "Doppler_error" + std::to_string(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)) + + std::to_string(PLL_wide_bw_values.at(config_idx)) + "_" + std::to_string(DLL_wide_bw_values.at(config_idx))); } g4.unset_multiplot(); - g4.savetops("Doppler_error_output"); - g4.savetopdf("Doppler_error_output", 18); + g4.savetops("Doppler_error_hz"); + g4.savetopdf("Doppler_error_hz", 18); } } } @@ -942,7 +1068,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) //plot metrics Gnuplot g7("linespoints"); - if (FLAGS_show_plots) g7.showonscreen(); // window output + if (FLAGS_show_plots) + { + g7.showonscreen(); // window output + } + else + { + g7.disablescreen(); + } g7.set_title("Doppler error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g7.set_grid(); g7.set_xlabel("CN0 [dB-Hz]"); @@ -957,10 +1090,17 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std_dev_doppler_error_sweep.at(config_sweep_idx), "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); + + //matlab save + save_mat_xy(generator_CN0_values_sweep_copy.at(config_sweep_idx), + rmse_doppler_sweep.at(config_sweep_idx), + "RMSE_Doppler_CN0_Sweep_PLL_DLL" + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"_" + std::to_string(DLL_wide_bw_values.at(config_sweep_idx))); } g7.savetops("Doppler_error_metrics"); g7.savetopdf("Doppler_error_metrics", 18); + Gnuplot g8("linespoints"); g8.set_title("Accumulated carrier phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); g8.set_grid(); @@ -976,6 +1116,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std_dev_carrier_phase_error_sweep.at(config_sweep_idx), "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); + //matlab save + save_mat_xy(generator_CN0_values_sweep_copy.at(config_sweep_idx), + rmse_carrier_phase_sweep.at(config_sweep_idx), + "RMSE_Carrier_Phase_CN0_Sweep_PLL_DLL" + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"_" + std::to_string(DLL_wide_bw_values.at(config_sweep_idx))); } g8.savetops("Carrier_error_metrics"); g8.savetopdf("Carrier_error_metrics", 18); @@ -995,6 +1140,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) std_dev_code_phase_error_sweep.at(config_sweep_idx), "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + +"," + std::to_string(DLL_wide_bw_values.at(config_sweep_idx)) + " Hz"); + //matlab save + save_mat_xy(generator_CN0_values_sweep_copy.at(config_sweep_idx), + rmse_code_phase_sweep.at(config_sweep_idx), + "RMSE_Code_Phase_CN0_Sweep_PLL_DLL" + std::to_string(PLL_wide_bw_values.at(config_sweep_idx)) + + +"_" + std::to_string(DLL_wide_bw_values.at(config_sweep_idx))); } g9.savetops("Code_error_metrics"); g9.savetopdf("Code_error_metrics", 18); @@ -1006,3 +1156,33 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) } } } + +bool GpsL1CADllPllTrackingTest::save_mat_xy(std::vector& x, std::vector& y, std::string filename) +{ + try + { + // WRITE MAT FILE + mat_t* matfp; + matvar_t* matvar; + filename.erase(filename.length() - 4, 4); + filename.append(".mat"); + matfp = Mat_CreateVer(filename.c_str(), NULL, MAT_FT_MAT73); + if (reinterpret_cast(matfp) != NULL) + { + size_t dims[2] = {1, x.size()}; + matvar = Mat_VarCreate("x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &x[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + + matvar = Mat_VarCreate("y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, &y[0], 0); + Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE + Mat_VarFree(matvar); + } + Mat_Close(matfp); + return true; + } + catch (const std::exception& ex) + { + return false; + } +} diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc index 328068dd1..977f87f7a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc @@ -41,7 +41,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -177,7 +181,7 @@ void GpsL1CADllPllTrackingTestFpga_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast &e) @@ -545,7 +549,7 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) //check results //load the true values - long int nepoch = true_obs_data.num_epochs(); + int64_t nepoch = true_obs_data.num_epochs(); std::cout << "True observation epochs=" << nepoch << std::endl; arma::vec true_timestamp_s = arma::zeros(nepoch, 1); @@ -554,7 +558,7 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) arma::vec true_prn_delay_chips = arma::zeros(nepoch, 1); arma::vec true_tow_s = arma::zeros(nepoch, 1); - long int epoch_counter = 0; + int64_t epoch_counter = 0; while (true_obs_data.read_binary_obs()) { true_timestamp_s(epoch_counter) = true_obs_data.signal_timestamp_s; diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_kf_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_kf_tracking_test.cc new file mode 100644 index 000000000..775c3540b --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_kf_tracking_test.cc @@ -0,0 +1,586 @@ +/*! + * \file gps_l1_ca_kf_tracking_test.cc + * \brief This class implements a tracking test for GPS_L1_CA_KF_Tracking + * implementation based on some input parameters. + * \author Carles Fernandez, 2018 + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2012-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef GR_GREATER_38 +#include +#else +#include +#endif +#include +#include +#include +#include +#include "GPS_L1_CA.h" +#include "gnss_block_factory.h" +#include "tracking_interface.h" +#include "in_memory_configuration.h" +#include "tracking_true_obs_reader.h" +#include "tracking_dump_reader.h" +#include "signal_generator_flags.h" +#include "gnuplot_i.h" +#include "test_flags.h" +#include "gnss_sdr_flags.h" + +DEFINE_bool(plot_gps_l1_kf_tracking_test, false, "Plots results of GpsL1CAKfTrackingTest with gnuplot"); + + +// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +class GpsL1CAKfTrackingTest_msg_rx; + +typedef boost::shared_ptr GpsL1CAKfTrackingTest_msg_rx_sptr; + +GpsL1CAKfTrackingTest_msg_rx_sptr GpsL1CAKfTrackingTest_msg_rx_make(); + +class GpsL1CAKfTrackingTest_msg_rx : public gr::block +{ +private: + friend GpsL1CAKfTrackingTest_msg_rx_sptr GpsL1CAKfTrackingTest_msg_rx_make(); + void msg_handler_events(pmt::pmt_t msg); + GpsL1CAKfTrackingTest_msg_rx(); + +public: + int rx_message; + ~GpsL1CAKfTrackingTest_msg_rx(); //!< Default destructor +}; + + +GpsL1CAKfTrackingTest_msg_rx_sptr GpsL1CAKfTrackingTest_msg_rx_make() +{ + return GpsL1CAKfTrackingTest_msg_rx_sptr(new GpsL1CAKfTrackingTest_msg_rx()); +} + + +void GpsL1CAKfTrackingTest_msg_rx::msg_handler_events(pmt::pmt_t msg) +{ + try + { + long int message = pmt::to_long(msg); + rx_message = message; + } + catch (boost::bad_any_cast& e) + { + LOG(WARNING) << "msg_handler_telemetry Bad any cast!"; + rx_message = 0; + } +} + + +GpsL1CAKfTrackingTest_msg_rx::GpsL1CAKfTrackingTest_msg_rx() : gr::block("GpsL1CAKfTrackingTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) +{ + this->message_port_register_in(pmt::mp("events")); + this->set_msg_handler(pmt::mp("events"), boost::bind(&GpsL1CAKfTrackingTest_msg_rx::msg_handler_events, this, _1)); + rx_message = 0; +} + + +GpsL1CAKfTrackingTest_msg_rx::~GpsL1CAKfTrackingTest_msg_rx() +{ +} + + +// ########################################################### + +class GpsL1CAKfTrackingTest : public ::testing::Test +{ +public: + std::string generator_binary; + std::string p1; + std::string p2; + std::string p3; + std::string p4; + std::string p5; + + std::string implementation = "GPS_L1_CA_KF_Tracking"; + + const int baseband_sampling_freq = FLAGS_fs_gen_sps; + + std::string filename_rinex_obs = FLAGS_filename_rinex_obs; + std::string filename_raw_data = FLAGS_filename_raw_data; + + int configure_generator(); + int generate_signal(); + void check_results_doppler(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value); + void check_results_acc_carrier_phase(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value); + void check_results_codephase(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value); + + GpsL1CAKfTrackingTest() + { + factory = std::make_shared(); + config = std::make_shared(); + item_size = sizeof(gr_complex); + gnss_synchro = Gnss_Synchro(); + } + + ~GpsL1CAKfTrackingTest() + { + } + + void configure_receiver(); + + gr::top_block_sptr top_block; + std::shared_ptr factory; + std::shared_ptr config; + Gnss_Synchro gnss_synchro; + size_t item_size; +}; + + +int GpsL1CAKfTrackingTest::configure_generator() +{ + // Configure signal generator + generator_binary = FLAGS_generator_binary; + + p1 = std::string("-rinex_nav_file=") + FLAGS_rinex_nav_file; + if (FLAGS_dynamic_position.empty()) + { + p2 = std::string("-static_position=") + FLAGS_static_position + std::string(",") + std::to_string(FLAGS_duration * 10); + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(FLAGS_dynamic_position); + } + p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] + return 0; +} + + +int GpsL1CAKfTrackingTest::generate_signal() +{ + int child_status; + + char* const parmList[] = {&generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], NULL}; + + int pid; + if ((pid = fork()) == -1) + perror("fork err"); + else if (pid == 0) + { + execv(&generator_binary[0], parmList); + std::cout << "Return not expected. Must be an execv err." << std::endl; + std::terminate(); + } + + waitpid(pid, &child_status, 0); + + std::cout << "Signal and Observables RINEX and RAW files created." << std::endl; + return 0; +} + + +void GpsL1CAKfTrackingTest::configure_receiver() +{ + gnss_synchro.Channel_ID = 0; + gnss_synchro.System = 'G'; + std::string signal = "1C"; + signal.copy(gnss_synchro.Signal, 2, 0); + gnss_synchro.PRN = FLAGS_test_satellite_PRN; + + config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); + // Set Tracking + config->set_property("Tracking_1C.implementation", implementation); + config->set_property("Tracking_1C.item_type", "gr_complex"); + if (FLAGS_dll_bw_hz != 0.0) + { + config->set_property("Tracking_1C.dll_bw_hz", std::to_string(FLAGS_dll_bw_hz)); + } + else + { + config->set_property("Tracking_1C.dll_bw_hz", "2.0"); + } + config->set_property("Tracking_1C.early_late_space_chips", "0.5"); + config->set_property("Tracking_1C.extend_correlation_ms", "1"); + config->set_property("Tracking_1C.dump", "true"); + config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); +} + + +void GpsL1CAKfTrackingTest::check_results_doppler(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value) +{ + // 1. True value interpolation to match the measurement times + arma::vec true_value_interp; + arma::uvec true_time_s_valid = find(true_time_s > 0); + true_time_s = true_time_s(true_time_s_valid); + true_value = true_value(true_time_s_valid); + arma::uvec meas_time_s_valid = find(meas_time_s > 0); + meas_time_s = meas_time_s(meas_time_s_valid); + meas_value = meas_value(meas_time_s_valid); + arma::interp1(true_time_s, true_value, meas_time_s, true_value_interp); + + // 2. RMSE + arma::vec err; + + err = meas_value - true_value_interp; + arma::vec err2 = arma::square(err); + double rmse = sqrt(arma::mean(err2)); + + // 3. Mean err and variance + double error_mean = arma::mean(err); + double error_var = arma::var(err); + + // 4. Peaks + double max_error = arma::max(err); + double min_error = arma::min(err); + + // 5. report + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(10) << "TRK Doppler RMSE=" << rmse + << ", mean=" << error_mean + << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; + std::cout.precision(ss); +} + + +void GpsL1CAKfTrackingTest::check_results_acc_carrier_phase(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value) +{ + // 1. True value interpolation to match the measurement times + arma::vec true_value_interp; + arma::uvec true_time_s_valid = find(true_time_s > 0); + true_time_s = true_time_s(true_time_s_valid); + true_value = true_value(true_time_s_valid); + arma::uvec meas_time_s_valid = find(meas_time_s > 0); + meas_time_s = meas_time_s(meas_time_s_valid); + meas_value = meas_value(meas_time_s_valid); + + arma::interp1(true_time_s, true_value, meas_time_s, true_value_interp); + + // 2. RMSE + arma::vec err; + err = meas_value - true_value_interp; + arma::vec err2 = arma::square(err); + double rmse = sqrt(arma::mean(err2)); + + // 3. Mean err and variance + double error_mean = arma::mean(err); + double error_var = arma::var(err); + + // 4. Peaks + double max_error = arma::max(err); + double min_error = arma::min(err); + + // 5. report + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(10) << "TRK acc carrier phase RMSE=" << rmse + << ", mean=" << error_mean + << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Hz]" << std::endl; + std::cout.precision(ss); +} + + +void GpsL1CAKfTrackingTest::check_results_codephase(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value) +{ + // 1. True value interpolation to match the measurement times + arma::vec true_value_interp; + arma::uvec true_time_s_valid = find(true_time_s > 0); + true_time_s = true_time_s(true_time_s_valid); + true_value = true_value(true_time_s_valid); + arma::uvec meas_time_s_valid = find(meas_time_s > 0); + meas_time_s = meas_time_s(meas_time_s_valid); + meas_value = meas_value(meas_time_s_valid); + + arma::interp1(true_time_s, true_value, meas_time_s, true_value_interp); + + // 2. RMSE + arma::vec err; + + err = meas_value - true_value_interp; + arma::vec err2 = arma::square(err); + double rmse = sqrt(arma::mean(err2)); + + // 3. Mean err and variance + double error_mean = arma::mean(err); + double error_var = arma::var(err); + + // 4. Peaks + double max_error = arma::max(err); + double min_error = arma::min(err); + + // 5. report + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(10) << "TRK code phase RMSE=" << rmse + << ", mean=" << error_mean + << ", stdev=" << sqrt(error_var) << " (max,min)=" << max_error << "," << min_error << " [Chips]" << std::endl; + std::cout.precision(ss); +} + + +TEST_F(GpsL1CAKfTrackingTest, ValidationOfResults) +{ + // Configure the signal generator + configure_generator(); + + // Generate signal raw signal samples and observations RINEX file + if (FLAGS_disable_generator == false) + { + generate_signal(); + } + + std::chrono::time_point start, end; + + configure_receiver(); + + // open true observables log file written by the simulator + tracking_true_obs_reader true_obs_data; + int test_satellite_PRN = FLAGS_test_satellite_PRN; + std::cout << "Testing satellite PRN=" << test_satellite_PRN << std::endl; + std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); + true_obs_file.append(std::to_string(test_satellite_PRN)); + true_obs_file.append(".dat"); + ASSERT_EQ(true_obs_data.open_obs_file(true_obs_file), true) << "Failure opening true observables file"; + + top_block = gr::make_top_block("Tracking test"); + + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); + std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); //std::make_shared(config.get(), "Tracking_1C", 1, 1); + + boost::shared_ptr msg_rx = GpsL1CAKfTrackingTest_msg_rx_make(); + + // load acquisition data based on the first epoch of the true observations + ASSERT_EQ(true_obs_data.read_binary_obs(), true) + << "Failure reading true tracking dump file." << std::endl + << "Maybe sat PRN #" + std::to_string(FLAGS_test_satellite_PRN) + + " is not available?"; + + // restart the epoch counter + true_obs_data.restart(); + + std::cout << "Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << std::endl; + gnss_synchro.Acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * baseband_sampling_freq * GPS_L1_CA_CODE_PERIOD; + gnss_synchro.Acq_doppler_hz = true_obs_data.doppler_l1_hz; + gnss_synchro.Acq_samplestamp_samples = 0; + + ASSERT_NO_THROW({ + tracking->set_channel(gnss_synchro.Channel_ID); + }) << "Failure setting channel."; + + ASSERT_NO_THROW({ + tracking->set_gnss_synchro(&gnss_synchro); + }) << "Failure setting gnss_synchro."; + + ASSERT_NO_THROW({ + tracking->connect(top_block); + }) << "Failure connecting tracking to the top_block."; + + ASSERT_NO_THROW({ + std::string file = "./" + filename_raw_data; + const char* file_name = file.c_str(); + gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); + gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); + gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); + top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); + top_block->connect(gr_interleaved_char_to_complex, 0, tracking->get_left_block(), 0); + top_block->connect(tracking->get_right_block(), 0, sink, 0); + top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + }) << "Failure connecting the blocks of tracking test."; + + tracking->start_tracking(); + + EXPECT_NO_THROW({ + start = std::chrono::system_clock::now(); + top_block->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + }) << "Failure running the top_block."; + + // check results + // load the true values + long int nepoch = true_obs_data.num_epochs(); + std::cout << "True observation epochs=" << nepoch << std::endl; + + arma::vec true_timestamp_s = arma::zeros(nepoch, 1); + arma::vec true_acc_carrier_phase_cycles = arma::zeros(nepoch, 1); + arma::vec true_Doppler_Hz = arma::zeros(nepoch, 1); + arma::vec true_prn_delay_chips = arma::zeros(nepoch, 1); + arma::vec true_tow_s = arma::zeros(nepoch, 1); + + long int epoch_counter = 0; + while (true_obs_data.read_binary_obs()) + { + true_timestamp_s(epoch_counter) = true_obs_data.signal_timestamp_s; + true_acc_carrier_phase_cycles(epoch_counter) = true_obs_data.acc_carrier_phase_cycles; + true_Doppler_Hz(epoch_counter) = true_obs_data.doppler_l1_hz; + true_prn_delay_chips(epoch_counter) = true_obs_data.prn_delay_chips; + true_tow_s(epoch_counter) = true_obs_data.tow; + epoch_counter++; + } + + //load the measured values + tracking_dump_reader trk_dump; + + ASSERT_EQ(trk_dump.open_obs_file(std::string("./tracking_ch_0.dat")), true) + << "Failure opening tracking dump file"; + + nepoch = trk_dump.num_epochs(); + std::cout << "Measured observation epochs=" << nepoch << std::endl; + //trk_dump.restart(); + + arma::vec trk_timestamp_s = arma::zeros(nepoch, 1); + arma::vec trk_acc_carrier_phase_cycles = arma::zeros(nepoch, 1); + arma::vec trk_Doppler_Hz = arma::zeros(nepoch, 1); + arma::vec trk_prn_delay_chips = arma::zeros(nepoch, 1); + + std::vector prompt; + std::vector early; + std::vector late; + std::vector promptI; + std::vector promptQ; + + epoch_counter = 0; + while (trk_dump.read_binary_obs()) + { + trk_timestamp_s(epoch_counter) = static_cast(trk_dump.PRN_start_sample_count) / static_cast(baseband_sampling_freq); + trk_acc_carrier_phase_cycles(epoch_counter) = trk_dump.acc_carrier_phase_rad / GPS_TWO_PI; + trk_Doppler_Hz(epoch_counter) = trk_dump.carrier_doppler_hz; + double delay_chips = GPS_L1_CA_CODE_LENGTH_CHIPS - GPS_L1_CA_CODE_LENGTH_CHIPS * (fmod((static_cast(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast(baseband_sampling_freq), 1.0e-3) / 1.0e-3); + + trk_prn_delay_chips(epoch_counter) = delay_chips; + epoch_counter++; + prompt.push_back(trk_dump.abs_P); + early.push_back(trk_dump.abs_E); + late.push_back(trk_dump.abs_L); + promptI.push_back(trk_dump.prompt_I); + promptQ.push_back(trk_dump.prompt_Q); + } + + // Align initial measurements and cut the tracking pull-in transitory + double pull_in_offset_s = 1.0; + arma::uvec initial_meas_point = arma::find(trk_timestamp_s >= (true_timestamp_s(0) + pull_in_offset_s), 1, "first"); + + trk_timestamp_s = trk_timestamp_s.subvec(initial_meas_point(0), trk_timestamp_s.size() - 1); + trk_acc_carrier_phase_cycles = trk_acc_carrier_phase_cycles.subvec(initial_meas_point(0), trk_acc_carrier_phase_cycles.size() - 1); + trk_Doppler_Hz = trk_Doppler_Hz.subvec(initial_meas_point(0), trk_Doppler_Hz.size() - 1); + trk_prn_delay_chips = trk_prn_delay_chips.subvec(initial_meas_point(0), trk_prn_delay_chips.size() - 1); + + check_results_doppler(true_timestamp_s, true_Doppler_Hz, trk_timestamp_s, trk_Doppler_Hz); + check_results_codephase(true_timestamp_s, true_prn_delay_chips, trk_timestamp_s, trk_prn_delay_chips); + check_results_acc_carrier_phase(true_timestamp_s, true_acc_carrier_phase_cycles, trk_timestamp_s, trk_acc_carrier_phase_cycles); + + std::chrono::duration elapsed_seconds = end - start; + std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds." << std::endl; + + if (FLAGS_plot_gps_l1_kf_tracking_test == true) + { + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if (gnuplot_executable.empty()) + { + std::cout << "WARNING: Although the flag plot_gps_l1_tracking_test has been set to TRUE," << std::endl; + std::cout << "gnuplot has not been found in your system." << std::endl; + std::cout << "Test results will not be plotted." << std::endl; + } + else + { + try + { + boost::filesystem::path p(gnuplot_executable); + boost::filesystem::path dir = p.parent_path(); + std::string gnuplot_path = dir.native(); + Gnuplot::set_GNUPlotPath(gnuplot_path); + + std::vector timevec; + double t = 0.0; + for (auto it = prompt.begin(); it != prompt.end(); it++) + { + timevec.push_back(t); + t = t + GPS_L1_CA_CODE_PERIOD; + } + Gnuplot g1("linespoints"); + g1.set_title("GPS L1 C/A signal tracking correlators' output (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g1.set_grid(); + g1.set_xlabel("Time [s]"); + g1.set_ylabel("Correlators' output"); + g1.cmd("set key box opaque"); + unsigned int decimate = static_cast(FLAGS_plot_decimate); + g1.plot_xy(timevec, prompt, "Prompt", decimate); + g1.plot_xy(timevec, early, "Early", decimate); + g1.plot_xy(timevec, late, "Late", decimate); + g1.savetops("Correlators_outputs"); + g1.savetopdf("Correlators_outputs", 18); + if (FLAGS_show_plots) + { + g1.showonscreen(); // window output + } + else + { + g1.disablescreen(); + } + + Gnuplot g2("points"); + g2.set_title("Constellation diagram (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g2.set_grid(); + g2.set_xlabel("Inphase"); + g2.set_ylabel("Quadrature"); + g2.cmd("set size ratio -1"); + g2.plot_xy(promptI, promptQ); + g2.savetops("Constellation"); + g2.savetopdf("Constellation", 18); + if (FLAGS_show_plots) + { + g2.showonscreen(); // window output + } + else + { + g2.disablescreen(); + } + } + catch (const GnuplotException& ge) + { + std::cout << ge.what() << std::endl; + } + } + } +} diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc index bfd715260..3c40eb54c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc @@ -35,7 +35,11 @@ #include #include #include +#ifdef GR_GREATER_38 +#include +#else #include +#endif #include #include #include @@ -79,7 +83,7 @@ void GpsL2MDllPllTrackingTest_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; } catch (boost::bad_any_cast& e) diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc new file mode 100644 index 000000000..6b33a2c33 --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc @@ -0,0 +1,1021 @@ +/*! + * \file tracking_test.cc + * \brief This class implements a tracking Pull-In test for GPS_L1_CA_DLL_PLL_Tracking + * implementation based on some input parameters. + * \author Javier Arribas, 2018. jarribas(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2012-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "GPS_L1_CA.h" +#include "gnss_block_factory.h" +#include "control_message_factory.h" +#include "tracking_interface.h" +#include "gnss_sdr_valve.h" +#include "gps_l2_m_pcps_acquisition.h" +#include "gps_l1_ca_pcps_acquisition.h" +#include "gps_l1_ca_pcps_acquisition_fine_doppler.h" +#include "galileo_e1_pcps_ambiguous_acquisition.h" +#include "galileo_e5a_noncoherent_iq_acquisition_caf.h" +#include "galileo_e5a_pcps_acquisition.h" +#include "gps_l5i_pcps_acquisition.h" +#include "in_memory_configuration.h" +#include "tracking_true_obs_reader.h" +#include "tracking_dump_reader.h" +#include "signal_generator_flags.h" +#include "gnuplot_i.h" +#include "test_flags.h" +#include "tracking_tests_flags.h" +#include "acquisition_msg_rx.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER ######### +class TrackingPullInTest_msg_rx; + +typedef boost::shared_ptr TrackingPullInTest_msg_rx_sptr; + +TrackingPullInTest_msg_rx_sptr TrackingPullInTest_msg_rx_make(); + +class TrackingPullInTest_msg_rx : public gr::block +{ +private: + friend TrackingPullInTest_msg_rx_sptr TrackingPullInTest_msg_rx_make(); + void msg_handler_events(pmt::pmt_t msg); + TrackingPullInTest_msg_rx(); + +public: + int rx_message; + ~TrackingPullInTest_msg_rx(); //!< Default destructor +}; + + +TrackingPullInTest_msg_rx_sptr TrackingPullInTest_msg_rx_make() +{ + return TrackingPullInTest_msg_rx_sptr(new TrackingPullInTest_msg_rx()); +} + + +void TrackingPullInTest_msg_rx::msg_handler_events(pmt::pmt_t msg) +{ + try + { + int64_t message = pmt::to_long(msg); + rx_message = message; //3 -> loss of lock + //std::cout << "Received trk message: " << rx_message << std::endl; + } + catch (boost::bad_any_cast& e) + { + LOG(WARNING) << "msg_handler_tracking Bad cast!"; + rx_message = 0; + } +} + + +TrackingPullInTest_msg_rx::TrackingPullInTest_msg_rx() : gr::block("TrackingPullInTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) +{ + this->message_port_register_in(pmt::mp("events")); + this->set_msg_handler(pmt::mp("events"), boost::bind(&TrackingPullInTest_msg_rx::msg_handler_events, this, _1)); + rx_message = 0; +} + + +TrackingPullInTest_msg_rx::~TrackingPullInTest_msg_rx() +{ +} + + +// ########################################################### + +class TrackingPullInTest : public ::testing::Test +{ +public: + std::string generator_binary; + std::string p1; + std::string p2; + std::string p3; + std::string p4; + std::string p5; + std::string p6; + std::string implementation = FLAGS_trk_test_implementation; + + const int baseband_sampling_freq = FLAGS_fs_gen_sps; + + std::string filename_rinex_obs = FLAGS_filename_rinex_obs; + std::string filename_raw_data = FLAGS_signal_file; + + std::map doppler_measurements_map; + std::map code_delay_measurements_map; + std::map acq_samplestamp_map; + + int configure_generator(double CN0_dBHz, int file_idx); + int generate_signal(); + std::vector check_results_doppler(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); + std::vector check_results_acc_carrier_phase(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); + std::vector check_results_codephase(arma::vec& true_time_s, + arma::vec& true_value, + arma::vec& meas_time_s, + arma::vec& meas_value, + double& mean_error, + double& std_dev_error); + + TrackingPullInTest() + { + factory = std::make_shared(); + config = std::make_shared(); + item_size = sizeof(gr_complex); + gnss_synchro = Gnss_Synchro(); + } + + ~TrackingPullInTest() + { + } + + void configure_receiver(double PLL_wide_bw_hz, + double DLL_wide_bw_hz, + double PLL_narrow_bw_hz, + double DLL_narrow_bw_hz, + int extend_correlation_symbols); + + bool acquire_signal(int SV_ID); + gr::top_block_sptr top_block; + std::shared_ptr factory; + std::shared_ptr config; + Gnss_Synchro gnss_synchro; + size_t item_size; + + gr::msg_queue::sptr queue; +}; + + +int TrackingPullInTest::configure_generator(double CN0_dBHz, int file_idx) +{ + // Configure signal generator + generator_binary = FLAGS_generator_binary; + + p1 = std::string("-rinex_nav_file=") + FLAGS_rinex_nav_file; + if (FLAGS_dynamic_position.empty()) + { + p2 = std::string("-static_position=") + FLAGS_static_position + std::string(",") + std::to_string(FLAGS_duration * 10); + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(FLAGS_dynamic_position); + } + p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + FLAGS_signal_file + std::to_string(file_idx); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); //Baseband sampling frequency [MSps] + p6 = std::string("-CN0_dBHz=") + std::to_string(CN0_dBHz); // Signal generator CN0 + return 0; +} + + +int TrackingPullInTest::generate_signal() +{ + int child_status; + + char* const parmList[] = {&generator_binary[0], &generator_binary[0], &p1[0], &p2[0], &p3[0], &p4[0], &p5[0], &p6[0], NULL}; + + int pid; + if ((pid = fork()) == -1) + perror("fork err"); + else if (pid == 0) + { + execv(&generator_binary[0], parmList); + std::cout << "Return not expected. Must be an execv err." << std::endl; + std::terminate(); + } + + waitpid(pid, &child_status, 0); + + std::cout << "Signal and Observables RINEX and RAW files created." << std::endl; + return 0; +} + + +void TrackingPullInTest::configure_receiver( + double PLL_wide_bw_hz, + double DLL_wide_bw_hz, + double PLL_narrow_bw_hz, + double DLL_narrow_bw_hz, + int extend_correlation_symbols) +{ + config = std::make_shared(); + config->set_property("Tracking.dump", "true"); + config->set_property("Tracking.dump_filename", "./tracking_ch_"); + config->set_property("Tracking.implementation", implementation); + config->set_property("Tracking.item_type", "gr_complex"); + config->set_property("Tracking.pll_bw_hz", std::to_string(PLL_wide_bw_hz)); + config->set_property("Tracking.dll_bw_hz", std::to_string(DLL_wide_bw_hz)); + config->set_property("Tracking.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); + config->set_property("Tracking.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); + config->set_property("Tracking.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); + gnss_synchro.PRN = FLAGS_test_satellite_PRN; + gnss_synchro.Channel_ID = 0; + config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); + + std::string System_and_Signal; + if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0) + { + gnss_synchro.System = 'G'; + std::string signal = "1C"; + System_and_Signal = "GPS L1 CA"; + signal.copy(gnss_synchro.Signal, 2, 0); + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.early_late_space_narrow_chips", "0.5"); + } + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0) + { + gnss_synchro.System = 'E'; + std::string signal = "1B"; + System_and_Signal = "Galileo E1B"; + signal.copy(gnss_synchro.Signal, 2, 0); + config->set_property("Tracking.early_late_space_chips", "0.15"); + config->set_property("Tracking.very_early_late_space_chips", "0.6"); + config->set_property("Tracking.early_late_space_narrow_chips", "0.15"); + config->set_property("Tracking.very_early_late_space_narrow_chips", "0.6"); + config->set_property("Tracking.track_pilot", "true"); + } + else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0) + { + gnss_synchro.System = 'G'; + std::string signal = "2S"; + System_and_Signal = "GPS L2CM"; + signal.copy(gnss_synchro.Signal, 2, 0); + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.track_pilot", "false"); + } + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0 or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + { + gnss_synchro.System = 'E'; + std::string signal = "5X"; + System_and_Signal = "Galileo E5a"; + signal.copy(gnss_synchro.Signal, 2, 0); + if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + { + config->supersede_property("Tracking.implementation", std::string("Galileo_E5a_DLL_PLL_Tracking")); + } + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.track_pilot", "false"); + config->set_property("Tracking.order", "2"); + } + else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0) + { + gnss_synchro.System = 'G'; + std::string signal = "L5"; + System_and_Signal = "GPS L5I"; + signal.copy(gnss_synchro.Signal, 2, 0); + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.track_pilot", "false"); + config->set_property("Tracking.order", "2"); + } + else + { + std::cout << "The test can not run with the selected tracking implementation\n "; + throw(std::exception()); + } + + std::cout << "*****************************************\n"; + std::cout << "*** Tracking configuration parameters ***\n"; + std::cout << "*****************************************\n"; + std::cout << "Signal: " << System_and_Signal << "\n"; + std::cout << "implementation: " << config->property("Tracking.implementation", std::string("undefined")) << " \n"; + std::cout << "pll_bw_hz: " << config->property("Tracking.pll_bw_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_hz: " << config->property("Tracking.dll_bw_hz", 0.0) << " Hz\n"; + std::cout << "pll_bw_narrow_hz: " << config->property("Tracking.pll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_narrow_hz: " << config->property("Tracking.dll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "extend_correlation_symbols: " << config->property("Tracking.extend_correlation_symbols", 0) << " Symbols\n"; + std::cout << "*****************************************\n"; + std::cout << "*****************************************\n"; +} + + +bool TrackingPullInTest::acquire_signal(int SV_ID) +{ + // 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m) + gr::top_block_sptr top_block; + top_block = gr::make_top_block("Acquisition test"); + + // Satellite signal definition + Gnss_Synchro tmp_gnss_synchro; + tmp_gnss_synchro.Channel_ID = 0; + config = std::make_shared(); + config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); + config->set_property("Acquisition.blocking_on_standby", "true"); + config->set_property("Acquisition.blocking", "true"); + config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition.dump_filename", "./data/acquisition.dat"); + config->set_property("Acquisition.use_CFAR_algorithm", "false"); + + std::shared_ptr acquisition; + + std::string System_and_Signal; + //create the correspondign acquisition block according to the desired tracking signal + if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'G'; + std::string signal = "1C"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "GPS L1 CA"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + //acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0) + { + tmp_gnss_synchro.System = 'E'; + std::string signal = "1B"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "Galileo E1B"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'G'; + std::string signal = "2S"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "GPS L2CM"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + { + tmp_gnss_synchro.System = 'E'; + std::string signal = "5X"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "Galileo E5a"; + config->set_property("Acquisition_5X.coherent_integration_time_ms", "1"); + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + config->set_property("Acquisition.CAF_window_hz", "0"); // **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz + config->set_property("Acquisition.Zero_padding", "0"); //**Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF. + config->set_property("Acquisition.bit_transition_flag", "false"); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'E'; + std::string signal = "5X"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "Galileo E5a"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'G'; + std::string signal = "L5"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "GPS L5I"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else + { + std::cout << "The test can not run with the selected tracking implementation\n "; + throw(std::exception()); + } + + acquisition->set_gnss_synchro(&tmp_gnss_synchro); + acquisition->set_channel(0); + acquisition->set_doppler_max(config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz)); + acquisition->set_doppler_step(config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz)); + acquisition->set_threshold(config->property("Acquisition.threshold", FLAGS_external_signal_acquisition_threshold)); + acquisition->init(); + acquisition->set_local_code(); + acquisition->set_state(1); // Ensure that acquisition starts at the first sample + acquisition->connect(top_block); + + gr::blocks::file_source::sptr file_source; + std::string file = FLAGS_signal_file; + const char* file_name = file.c_str(); + file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); + file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample + gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); + //gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration); + + top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); + top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0); + //top_block->connect(head_samples, 0, acquisition->get_left_block(), 0); + + boost::shared_ptr msg_rx; + try + { + msg_rx = Acquisition_msg_rx_make(); + } + catch (const std::exception& e) + { + std::cout << "Failure connecting the message port system: " << e.what() << std::endl; + exit(0); + } + + msg_rx->top_block = top_block; + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + + // 5. Run the flowgraph + // Get visible GPS satellites (positive acquisitions with Doppler measurements) + // record startup time + std::chrono::time_point start, end; + std::chrono::duration elapsed_seconds; + start = std::chrono::system_clock::now(); + + bool start_msg = true; + + doppler_measurements_map.clear(); + code_delay_measurements_map.clear(); + acq_samplestamp_map.clear(); + + unsigned int MAX_PRN_IDX = 0; + + switch (tmp_gnss_synchro.System) + { + case 'G': + MAX_PRN_IDX = 33; + break; + case 'E': + MAX_PRN_IDX = 37; + break; + default: + MAX_PRN_IDX = 33; + } + + for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++) + { + tmp_gnss_synchro.PRN = PRN; + acquisition->set_gnss_synchro(&tmp_gnss_synchro); + acquisition->init(); + acquisition->set_local_code(); + acquisition->reset(); + acquisition->set_state(1); + msg_rx->rx_message = 0; + top_block->run(); + if (start_msg == true) + { + std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl; + std::cout << "Searching for " << System_and_Signal << " Satellites..." << std::endl; + std::cout << "["; + start_msg = false; + } + while (msg_rx->rx_message == 0) + { + usleep(100000); + } + if (msg_rx->rx_message == 1) + { + std::cout << " " << PRN << " "; + doppler_measurements_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_doppler_hz)); + code_delay_measurements_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_delay_samples)); + acq_samplestamp_map.insert(std::pair(PRN, tmp_gnss_synchro.Acq_samplestamp_samples)); + } + else + { + std::cout << " . "; + } + top_block->stop(); + file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample + std::cout.flush(); + } + std::cout << "]" << std::endl; + std::cout << "-------------------------------------------\n"; + + for (auto& x : doppler_measurements_map) + { + std::cout << "DETECTED SATELLITE " << System_and_Signal << " PRN: " << x.first << " with Doppler: " << x.second << " [Hz], code phase: " << code_delay_measurements_map.at(x.first) << " [samples] at signal SampleStamp " << acq_samplestamp_map.at(x.first) << "\n"; + } + + // report the elapsed time + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + std::cout << "Total signal acquisition run time " + << elapsed_seconds.count() + << " [seconds]" << std::endl; + return true; +} + +TEST_F(TrackingPullInTest, ValidationOfResults) +{ + //************************************************* + //***** STEP 1: Prepare the parameters sweep ****** + //************************************************* + std::vector + acq_doppler_error_hz_values; + std::vector> acq_delay_error_chips_values; //vector of vector + + for (double doppler_hz = FLAGS_acq_Doppler_error_hz_start; doppler_hz >= FLAGS_acq_Doppler_error_hz_stop; doppler_hz = doppler_hz + FLAGS_acq_Doppler_error_hz_step) + { + acq_doppler_error_hz_values.push_back(doppler_hz); + std::vector tmp_vector; + //Code Delay Sweep + for (double code_delay_chips = FLAGS_acq_Delay_error_chips_start; code_delay_chips >= FLAGS_acq_Delay_error_chips_stop; code_delay_chips = code_delay_chips + FLAGS_acq_Delay_error_chips_step) + { + tmp_vector.push_back(code_delay_chips); + } + acq_delay_error_chips_values.push_back(tmp_vector); + } + + + //*********************************************************** + //***** STEP 2: Generate the input signal (if required) ***** + //*********************************************************** + std::vector generator_CN0_values; + if (FLAGS_enable_external_signal_file) + { + generator_CN0_values.push_back(999); // an external input signal capture is selected, no CN0 information available + } + else + { + if (FLAGS_CN0_dBHz_start == FLAGS_CN0_dBHz_stop) + { + generator_CN0_values.push_back(FLAGS_CN0_dBHz_start); + } + else + { + for (double cn0 = FLAGS_CN0_dBHz_start; cn0 > FLAGS_CN0_dBHz_stop; cn0 = cn0 - FLAGS_CN0_dB_step) + { + generator_CN0_values.push_back(cn0); + } + } + } + + // use generator or use an external capture file + if (FLAGS_enable_external_signal_file) + { + //create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters + ASSERT_EQ(acquire_signal(FLAGS_test_satellite_PRN), true); + bool found_satellite = doppler_measurements_map.find(FLAGS_test_satellite_PRN) != doppler_measurements_map.end(); + EXPECT_TRUE(found_satellite) << "Error: satellite SV: " << FLAGS_test_satellite_PRN << " is not acquired"; + if (!found_satellite) return; + } + else + { + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + // Configure the signal generator + configure_generator(generator_CN0_values.at(current_cn0_idx), current_cn0_idx); + // Generate signal raw signal samples and observations RINEX file + if (FLAGS_disable_generator == false) + { + generate_signal(); + } + } + } + + + configure_receiver(FLAGS_PLL_bw_hz_start, + FLAGS_DLL_bw_hz_start, + FLAGS_PLL_narrow_bw_hz, + FLAGS_DLL_narrow_bw_hz, + FLAGS_extend_correlation_symbols); + + //****************************************************************************************** + //***** Obtain the initial signal sinchronization parameters (emulating an acquisition) **** + //****************************************************************************************** + int test_satellite_PRN = 0; + double true_acq_doppler_hz = 0.0; + double true_acq_delay_samples = 0.0; + uint64_t acq_samplestamp_samples = 0; + + tracking_true_obs_reader true_obs_data; + if (!FLAGS_enable_external_signal_file) + { + test_satellite_PRN = FLAGS_test_satellite_PRN; + std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); + true_obs_file.append(std::to_string(test_satellite_PRN)); + true_obs_file.append(".dat"); + true_obs_data.close_obs_file(); + ASSERT_EQ(true_obs_data.open_obs_file(true_obs_file), true) << "Failure opening true observables file"; + // load acquisition data based on the first epoch of the true observations + ASSERT_EQ(true_obs_data.read_binary_obs(), true) + << "Failure reading true tracking dump file." << std::endl + << "Maybe sat PRN #" + std::to_string(FLAGS_test_satellite_PRN) + + " is not available?"; + std::cout << "Testing satellite PRN=" << test_satellite_PRN << std::endl; + std::cout << "True Initial Doppler " << true_obs_data.doppler_l1_hz << " [Hz], true Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << "[Chips]" << std::endl; + true_acq_doppler_hz = true_obs_data.doppler_l1_hz; + true_acq_delay_samples = (GPS_L1_CA_CODE_LENGTH_CHIPS - true_obs_data.prn_delay_chips / GPS_L1_CA_CODE_LENGTH_CHIPS) * static_cast(baseband_sampling_freq) * GPS_L1_CA_CODE_PERIOD; + acq_samplestamp_samples = 0; + } + else + { + true_acq_doppler_hz = doppler_measurements_map.find(FLAGS_test_satellite_PRN)->second; + true_acq_delay_samples = code_delay_measurements_map.find(FLAGS_test_satellite_PRN)->second; + acq_samplestamp_samples = 0; + std::cout << "Estimated Initial Doppler " << true_acq_doppler_hz + << " [Hz], estimated Initial code delay " << true_acq_delay_samples << " [Samples]" + << " Acquisition SampleStamp is " << acq_samplestamp_map.find(FLAGS_test_satellite_PRN)->second << std::endl; + } + + // create the msg queue for valve + + queue = gr::msg_queue::make(0); + boost::shared_ptr reseteable_valve; + long long int acq_to_trk_delay_samples = ceil(static_cast(FLAGS_fs_gen_sps) * FLAGS_acq_to_trk_delay_s); + boost::shared_ptr resetable_valve_(new gnss_sdr_valve(sizeof(gr_complex), acq_to_trk_delay_samples, queue, false)); + + std::shared_ptr control_message_factory_; + std::shared_ptr>> control_messages_; + + + //CN0 LOOP + std::vector> pull_in_results_v_v; + + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + std::vector pull_in_results_v; + for (unsigned int current_acq_doppler_error_idx = 0; current_acq_doppler_error_idx < acq_doppler_error_hz_values.size(); current_acq_doppler_error_idx++) + { + for (unsigned int current_acq_code_error_idx = 0; current_acq_code_error_idx < acq_delay_error_chips_values.at(current_acq_doppler_error_idx).size(); current_acq_code_error_idx++) + { + gnss_synchro.Acq_samplestamp_samples = acq_samplestamp_samples; + //simulate a Doppler error in acquisition + gnss_synchro.Acq_doppler_hz = true_acq_doppler_hz + acq_doppler_error_hz_values.at(current_acq_doppler_error_idx); + //simulate Code Delay error in acquisition + gnss_synchro.Acq_delay_samples = true_acq_delay_samples + (acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx) / GPS_L1_CA_CODE_RATE_HZ) * static_cast(baseband_sampling_freq); + + //create flowgraph + top_block = gr::make_top_block("Tracking test"); + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking", config->property("Tracking.implementation", std::string("undefined")), 1, 1); + std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); + boost::shared_ptr msg_rx = TrackingPullInTest_msg_rx_make(); + + + ASSERT_NO_THROW({ + tracking->set_channel(gnss_synchro.Channel_ID); + }) << "Failure setting channel."; + + ASSERT_NO_THROW({ + tracking->set_gnss_synchro(&gnss_synchro); + }) << "Failure setting gnss_synchro."; + + ASSERT_NO_THROW({ + tracking->connect(top_block); + }) << "Failure connecting tracking to the top_block."; + + std::string file; + ASSERT_NO_THROW({ + if (!FLAGS_enable_external_signal_file) + { + file = "./" + filename_raw_data + std::to_string(current_cn0_idx); + } + else + { + file = FLAGS_signal_file; + } + const char* file_name = file.c_str(); + gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); + gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); + gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); + gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration); + top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); + top_block->connect(gr_interleaved_char_to_complex, 0, head_samples, 0); + if (acq_to_trk_delay_samples > 0) + { + top_block->connect(head_samples, 0, resetable_valve_, 0); + top_block->connect(resetable_valve_, 0, tracking->get_left_block(), 0); + } + else + { + top_block->connect(head_samples, 0, tracking->get_left_block(), 0); + } + top_block->connect(tracking->get_right_block(), 0, sink, 0); + top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample + }) << "Failure connecting the blocks of tracking test."; + + + //******************************************************************** + //***** STEP 5: Perform the signal tracking and read the results ***** + //******************************************************************** + std::cout << "--- START TRACKING WITH PULL-IN ERROR: " << acq_doppler_error_hz_values.at(current_acq_doppler_error_idx) << " [Hz] and " << acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx) << " [Chips] ---" << std::endl; + std::chrono::time_point start, end; + if (acq_to_trk_delay_samples > 0) + { + EXPECT_NO_THROW({ + start = std::chrono::system_clock::now(); + std::cout << "--- SIMULATING A PULL-IN DELAY OF " << FLAGS_acq_to_trk_delay_s << " SECONDS ---\n"; + top_block->start(); + std::cout << " Waiting for valve...\n"; + //wait the valve message indicating the circulation of the amount of samples of the delay + gr::message::sptr queue_message = queue->delete_head(); + if (queue_message != 0) + { + control_messages_ = control_message_factory_->GetControlMessages(queue_message); + } + else + { + control_messages_->clear(); + } + std::cout << " Starting tracking...\n"; + tracking->start_tracking(); + resetable_valve_->open_valve(); + std::cout << " Waiting flowgraph..\n"; + top_block->wait(); + end = std::chrono::system_clock::now(); + }) << "Failure running the top_block."; + } + else + { + tracking->start_tracking(); + std::chrono::time_point start, end; + EXPECT_NO_THROW({ + start = std::chrono::system_clock::now(); + top_block->run(); // Start threads and wait + end = std::chrono::system_clock::now(); + }) << "Failure running the top_block."; + } + + std::chrono::duration elapsed_seconds = end - start; + std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds" << std::endl; + + pull_in_results_v.push_back(msg_rx->rx_message != 3); //save last asynchronous tracking message in order to detect a loss of lock + + //******************************** + //***** STEP 7: Plot results ***** + //******************************** + if (FLAGS_plot_detail_level >= 2 and FLAGS_show_plots) + { + //load the measured values + tracking_dump_reader trk_dump; + ASSERT_EQ(trk_dump.open_obs_file(std::string("./tracking_ch_0.dat")), true) + << "Failure opening tracking dump file"; + + int64_t n_measured_epochs = trk_dump.num_epochs(); + //todo: use vectors instead + arma::vec trk_timestamp_s = arma::zeros(n_measured_epochs, 1); + arma::vec trk_acc_carrier_phase_cycles = arma::zeros(n_measured_epochs, 1); + arma::vec trk_Doppler_Hz = arma::zeros(n_measured_epochs, 1); + arma::vec trk_prn_delay_chips = arma::zeros(n_measured_epochs, 1); + std::vector timestamp_s; + std::vector prompt; + std::vector early; + std::vector late; + std::vector v_early; + std::vector v_late; + std::vector promptI; + std::vector promptQ; + std::vector CN0_dBHz; + std::vector Doppler; + int64_t epoch_counter = 0; + while (trk_dump.read_binary_obs()) + { + trk_timestamp_s(epoch_counter) = static_cast(trk_dump.PRN_start_sample_count) / static_cast(baseband_sampling_freq); + trk_acc_carrier_phase_cycles(epoch_counter) = trk_dump.acc_carrier_phase_rad / GPS_TWO_PI; + trk_Doppler_Hz(epoch_counter) = trk_dump.carrier_doppler_hz; + double delay_chips = GPS_L1_CA_CODE_LENGTH_CHIPS - GPS_L1_CA_CODE_LENGTH_CHIPS * (fmod((static_cast(trk_dump.PRN_start_sample_count) + trk_dump.aux1) / static_cast(baseband_sampling_freq), 1.0e-3) / 1.0e-3); + + trk_prn_delay_chips(epoch_counter) = delay_chips; + + timestamp_s.push_back(trk_timestamp_s(epoch_counter)); + prompt.push_back(trk_dump.abs_P); + early.push_back(trk_dump.abs_E); + late.push_back(trk_dump.abs_L); + v_early.push_back(trk_dump.abs_VE); + v_late.push_back(trk_dump.abs_VL); + promptI.push_back(trk_dump.prompt_I); + promptQ.push_back(trk_dump.prompt_Q); + CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz); + Doppler.push_back(trk_dump.carrier_doppler_hz); + epoch_counter++; + } + + + const std::string gnuplot_executable(FLAGS_gnuplot_executable); + if (gnuplot_executable.empty()) + { + std::cout << "WARNING: Although the flag show_plots has been set to TRUE," << std::endl; + std::cout << "gnuplot has not been found in your system." << std::endl; + std::cout << "Test results will not be plotted." << std::endl; + } + else + { + try + { + boost::filesystem::path p(gnuplot_executable); + boost::filesystem::path dir = p.parent_path(); + std::string gnuplot_path = dir.native(); + Gnuplot::set_GNUPlotPath(gnuplot_path); + unsigned int decimate = static_cast(FLAGS_plot_decimate); + + if (FLAGS_plot_detail_level >= 2 and FLAGS_show_plots) + { + Gnuplot g1("linespoints"); + g1.showonscreen(); // window output + if (!FLAGS_enable_external_signal_file) + { + g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + else + { + g1.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + + g1.set_grid(); + g1.set_xlabel("Time [s]"); + g1.set_ylabel("Correlators' output"); + //g1.cmd("set key box opaque"); + g1.plot_xy(trk_timestamp_s, prompt, "Prompt", decimate); + g1.plot_xy(trk_timestamp_s, early, "Early", decimate); + g1.plot_xy(trk_timestamp_s, late, "Late", decimate); + if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0) + { + g1.plot_xy(trk_timestamp_s, v_early, "Very Early", decimate); + g1.plot_xy(trk_timestamp_s, v_late, "Very Late", decimate); + } + g1.set_legend(); + g1.savetops("Correlators_outputs"); + + Gnuplot g2("points"); + g2.showonscreen(); // window output + if (!FLAGS_enable_external_signal_file) + { + g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + else + { + g2.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + + g2.set_grid(); + g2.set_xlabel("Inphase"); + g2.set_ylabel("Quadrature"); + //g2.cmd("set size ratio -1"); + g2.plot_xy(promptI, promptQ); + g2.savetops("Constellation"); + + Gnuplot g3("linespoints"); + if (!FLAGS_enable_external_signal_file) + { + g3.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + else + { + g3.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + g3.set_grid(); + g3.set_xlabel("Time [s]"); + g3.set_ylabel("Reported CN0 [dB-Hz]"); + g3.cmd("set key box opaque"); + + g3.plot_xy(trk_timestamp_s, CN0_dBHz, + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + + g3.set_legend(); + g3.savetops("CN0_output"); + + g3.showonscreen(); // window output + + Gnuplot g4("linespoints"); + if (!FLAGS_enable_external_signal_file) + { + g4.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + else + { + g4.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + g4.set_grid(); + g4.set_xlabel("Time [s]"); + g4.set_ylabel("Estimated Doppler [Hz]"); + g4.cmd("set key box opaque"); + + g4.plot_xy(trk_timestamp_s, Doppler, + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + + g4.set_legend(); + g4.savetops("Doppler"); + + g4.showonscreen(); // window output + } + } + catch (const GnuplotException& ge) + { + std::cout << ge.what() << std::endl; + } + } + } //end plot + + } //end acquisition Delay errors loop + } //end acquisition Doppler errors loop + pull_in_results_v_v.push_back(pull_in_results_v); + + + } //end CN0 LOOP + //build the mesh grid + std::vector doppler_error_mesh; + std::vector code_delay_error_mesh; + for (unsigned int current_acq_doppler_error_idx = 0; current_acq_doppler_error_idx < acq_doppler_error_hz_values.size(); current_acq_doppler_error_idx++) + { + for (unsigned int current_acq_code_error_idx = 0; current_acq_code_error_idx < acq_delay_error_chips_values.at(current_acq_doppler_error_idx).size(); current_acq_code_error_idx++) + { + doppler_error_mesh.push_back(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)); + code_delay_error_mesh.push_back(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)); + } + } + + for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) + { + std::vector pull_in_result_mesh; + pull_in_result_mesh = pull_in_results_v_v.at(current_cn0_idx); + //plot grid + Gnuplot g4("points palette pointsize 2 pointtype 7"); + if (FLAGS_show_plots) + { + g4.showonscreen(); // window output + } + else + { + g4.disablescreen(); + } + g4.cmd("set palette defined ( 0 \"black\", 1 \"green\" )"); + g4.cmd("set key off"); + g4.cmd("set view map"); + std::string title; + if (!FLAGS_enable_external_signal_file) + { + title = std::string("Tracking Pull-in result grid at CN0:" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + " [dB-Hz], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz]."); + } + else + { + title = std::string("Tracking Pull-in result grid, PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + + g4.set_title(title); + g4.set_grid(); + g4.set_xlabel("Acquisition Doppler error [Hz]"); + g4.set_ylabel("Acquisition Code Delay error [Chips]"); + g4.cmd("set cbrange[0:1]"); + g4.plot_xyz(doppler_error_mesh, + code_delay_error_mesh, + pull_in_result_mesh); + g4.set_legend(); + if (!FLAGS_enable_external_signal_file) + { + g4.savetops("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx))))); + g4.savetopdf("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))), 12); + } + else + { + g4.savetops("trk_pull_in_grid_external_file"); + g4.savetopdf("trk_pull_in_grid_external_file", 12); + } + } +} diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc similarity index 65% rename from src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc rename to src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc index e449fa2e0..1c35cc64e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_pull-in_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc @@ -1,5 +1,5 @@ /*! - * \file gps_l1_ca_dll_pll_tracking_test.cc + * \file tracking_test.cc * \brief This class implements a tracking Pull-In test for GPS_L1_CA_DLL_PLL_Tracking * implementation based on some input parameters. * \author Javier Arribas, 2018. jarribas(at)cttc.es @@ -40,11 +40,17 @@ #include #include #include +#include #include #include "GPS_L1_CA.h" #include "gnss_block_factory.h" #include "tracking_interface.h" +#include "gps_l2_m_pcps_acquisition.h" +#include "gps_l1_ca_pcps_acquisition.h" #include "gps_l1_ca_pcps_acquisition_fine_doppler.h" +#include "galileo_e5a_noncoherent_iq_acquisition_caf.h" +#include "galileo_e5a_pcps_acquisition.h" +#include "gps_l5i_pcps_acquisition.h" #include "in_memory_configuration.h" #include "tracking_true_obs_reader.h" #include "tracking_dump_reader.h" @@ -71,6 +77,7 @@ private: public: int rx_message; + gr::top_block_sptr top_block; ~Acquisition_msg_rx(); //!< Default destructor }; @@ -85,8 +92,9 @@ void Acquisition_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; + top_block->stop(); //stop the flowgraph } catch (boost::bad_any_cast& e) { @@ -106,36 +114,36 @@ Acquisition_msg_rx::Acquisition_msg_rx() : gr::block("Acquisition_msg_rx", gr::i Acquisition_msg_rx::~Acquisition_msg_rx() {} // ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER ######### -class GpsL1CADllPllTrackingPullInTest_msg_rx; +class TrackingPullInTestFpga_msg_rx; -typedef boost::shared_ptr GpsL1CADllPllTrackingPullInTest_msg_rx_sptr; +typedef boost::shared_ptr TrackingPullInTestFpga_msg_rx_sptr; -GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make(); +TrackingPullInTestFpga_msg_rx_sptr TrackingPullInTestFpga_msg_rx_make(); -class GpsL1CADllPllTrackingPullInTest_msg_rx : public gr::block +class TrackingPullInTestFpga_msg_rx : public gr::block { private: - friend GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make(); + friend TrackingPullInTestFpga_msg_rx_sptr TrackingPullInTestFpga_msg_rx_make(); void msg_handler_events(pmt::pmt_t msg); - GpsL1CADllPllTrackingPullInTest_msg_rx(); + TrackingPullInTestFpga_msg_rx(); public: int rx_message; - ~GpsL1CADllPllTrackingPullInTest_msg_rx(); //!< Default destructor + ~TrackingPullInTestFpga_msg_rx(); //!< Default destructor }; -GpsL1CADllPllTrackingPullInTest_msg_rx_sptr GpsL1CADllPllTrackingPullInTest_msg_rx_make() +TrackingPullInTestFpga_msg_rx_sptr TrackingPullInTestFpga_msg_rx_make() { - return GpsL1CADllPllTrackingPullInTest_msg_rx_sptr(new GpsL1CADllPllTrackingPullInTest_msg_rx()); + return TrackingPullInTestFpga_msg_rx_sptr(new TrackingPullInTestFpga_msg_rx()); } -void GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events(pmt::pmt_t msg) +void TrackingPullInTestFpga_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; //3 -> loss of lock //std::cout << "Received trk message: " << rx_message << std::endl; } @@ -147,22 +155,22 @@ void GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events(pmt::pmt_t msg) } -GpsL1CADllPllTrackingPullInTest_msg_rx::GpsL1CADllPllTrackingPullInTest_msg_rx() : gr::block("GpsL1CADllPllTrackingPullInTest_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) +TrackingPullInTestFpga_msg_rx::TrackingPullInTestFpga_msg_rx() : gr::block("TrackingPullInTestFpga_msg_rx", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)) { this->message_port_register_in(pmt::mp("events")); - this->set_msg_handler(pmt::mp("events"), boost::bind(&GpsL1CADllPllTrackingPullInTest_msg_rx::msg_handler_events, this, _1)); + this->set_msg_handler(pmt::mp("events"), boost::bind(&TrackingPullInTestFpga_msg_rx::msg_handler_events, this, _1)); rx_message = 0; } -GpsL1CADllPllTrackingPullInTest_msg_rx::~GpsL1CADllPllTrackingPullInTest_msg_rx() +TrackingPullInTestFpga_msg_rx::~TrackingPullInTestFpga_msg_rx() { } // ########################################################### -class GpsL1CADllPllTrackingPullInTest : public ::testing::Test +class TrackingPullInTestFpga : public ::testing::Test { public: std::string generator_binary; @@ -172,7 +180,7 @@ public: std::string p4; std::string p5; std::string p6; - std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking"; //"GPS_L1_CA_DLL_PLL_C_Aid_Tracking"; + std::string implementation = FLAGS_trk_test_implementation; const int baseband_sampling_freq = FLAGS_fs_gen_sps; @@ -181,7 +189,7 @@ public: std::map doppler_measurements_map; std::map code_delay_measurements_map; - std::map acq_samplestamp_map; + std::map acq_samplestamp_map; int configure_generator(double CN0_dBHz, int file_idx); int generate_signal(); @@ -204,7 +212,7 @@ public: double& mean_error, double& std_dev_error); - GpsL1CADllPllTrackingPullInTest() + TrackingPullInTestFpga() { factory = std::make_shared(); config = std::make_shared(); @@ -212,7 +220,7 @@ public: gnss_synchro = Gnss_Synchro(); } - ~GpsL1CADllPllTrackingPullInTest() + ~TrackingPullInTestFpga() { } @@ -222,7 +230,7 @@ public: double DLL_narrow_bw_hz, int extend_correlation_symbols); - bool acquire_GPS_L1CA_signal(int SV_ID); + bool acquire_signal(int SV_ID); gr::top_block_sptr top_block; std::shared_ptr factory; std::shared_ptr config; @@ -231,7 +239,7 @@ public: }; -int GpsL1CADllPllTrackingPullInTest::configure_generator(double CN0_dBHz, int file_idx) +int TrackingPullInTestFpga::configure_generator(double CN0_dBHz, int file_idx) { // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -253,7 +261,7 @@ int GpsL1CADllPllTrackingPullInTest::configure_generator(double CN0_dBHz, int fi } -int GpsL1CADllPllTrackingPullInTest::generate_signal() +int TrackingPullInTestFpga::generate_signal() { int child_status; @@ -276,48 +284,104 @@ int GpsL1CADllPllTrackingPullInTest::generate_signal() } -void GpsL1CADllPllTrackingPullInTest::configure_receiver( +void TrackingPullInTestFpga::configure_receiver( double PLL_wide_bw_hz, double DLL_wide_bw_hz, double PLL_narrow_bw_hz, double DLL_narrow_bw_hz, int extend_correlation_symbols) { - gnss_synchro.Channel_ID = 0; - gnss_synchro.System = 'G'; - std::string signal = "1C"; - signal.copy(gnss_synchro.Signal, 2, 0); - gnss_synchro.PRN = FLAGS_test_satellite_PRN; - config = std::make_shared(); + config->set_property("Tracking.dump", "true"); + config->set_property("Tracking.dump_filename", "./tracking_ch_"); + config->set_property("Tracking.implementation", implementation); + config->set_property("Tracking.item_type", "gr_complex"); + config->set_property("Tracking.pll_bw_hz", std::to_string(PLL_wide_bw_hz)); + config->set_property("Tracking.dll_bw_hz", std::to_string(DLL_wide_bw_hz)); + config->set_property("Tracking.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); + config->set_property("Tracking.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); + config->set_property("Tracking.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); + gnss_synchro.PRN = FLAGS_test_satellite_PRN; + gnss_synchro.Channel_ID = 0; config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); - // Set Tracking - config->set_property("Tracking_1C.implementation", implementation); - config->set_property("Tracking_1C.item_type", "gr_complex"); - config->set_property("Tracking_1C.pll_bw_hz", std::to_string(PLL_wide_bw_hz)); - config->set_property("Tracking_1C.dll_bw_hz", std::to_string(DLL_wide_bw_hz)); - config->set_property("Tracking_1C.early_late_space_chips", "0.5"); - config->set_property("Tracking_1C.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); - config->set_property("Tracking_1C.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); - config->set_property("Tracking_1C.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); - config->set_property("Tracking_1C.early_late_space_narrow_chips", "0.5"); - config->set_property("Tracking_1C.dump", "true"); - config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); + + std::string System_and_Signal; + if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0) + { + gnss_synchro.System = 'G'; + std::string signal = "1C"; + System_and_Signal = "GPS L1 CA"; + signal.copy(gnss_synchro.Signal, 2, 0); + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.early_late_space_narrow_chips", "0.5"); + } + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0) + { + gnss_synchro.System = 'E'; + std::string signal = "1B"; + System_and_Signal = "Galileo E1B"; + signal.copy(gnss_synchro.Signal, 2, 0); + config->set_property("Tracking.early_late_space_chips", "0.15"); + config->set_property("Tracking.very_early_late_space_chips", "0.6"); + config->set_property("Tracking.early_late_space_narrow_chips", "0.15"); + config->set_property("Tracking.very_early_late_space_narrow_chips", "0.6"); + config->set_property("Tracking.track_pilot", "true"); + } + else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0) + { + gnss_synchro.System = 'G'; + std::string signal = "2S"; + System_and_Signal = "GPS L2CM"; + signal.copy(gnss_synchro.Signal, 2, 0); + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.track_pilot", "false"); + } + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0 or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + { + gnss_synchro.System = 'E'; + std::string signal = "5X"; + System_and_Signal = "Galileo E5a"; + signal.copy(gnss_synchro.Signal, 2, 0); + if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + { + config->supersede_property("Tracking.implementation", std::string("Galileo_E5a_DLL_PLL_Tracking")); + } + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.track_pilot", "false"); + config->set_property("Tracking.order", "2"); + } + else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0) + { + gnss_synchro.System = 'G'; + std::string signal = "L5"; + System_and_Signal = "GPS L5I"; + signal.copy(gnss_synchro.Signal, 2, 0); + config->set_property("Tracking.early_late_space_chips", "0.5"); + config->set_property("Tracking.track_pilot", "false"); + config->set_property("Tracking.order", "2"); + } + else + { + std::cout << "The test can not run with the selected tracking implementation\n "; + throw(std::exception()); + } std::cout << "*****************************************\n"; std::cout << "*** Tracking configuration parameters ***\n"; std::cout << "*****************************************\n"; - std::cout << "pll_bw_hz: " << config->property("Tracking_1C.pll_bw_hz", 0.0) << " Hz\n"; - std::cout << "dll_bw_hz: " << config->property("Tracking_1C.dll_bw_hz", 0.0) << " Hz\n"; - std::cout << "pll_bw_narrow_hz: " << config->property("Tracking_1C.pll_bw_narrow_hz", 0.0) << " Hz\n"; - std::cout << "dll_bw_narrow_hz: " << config->property("Tracking_1C.dll_bw_narrow_hz", 0.0) << " Hz\n"; - std::cout << "extend_correlation_symbols: " << config->property("Tracking_1C.extend_correlation_symbols", 0) << " Symbols\n"; + std::cout << "Signal: " << System_and_Signal << "\n"; + std::cout << "implementation: " << config->property("Tracking.implementation", std::string("undefined")) << " \n"; + std::cout << "pll_bw_hz: " << config->property("Tracking.pll_bw_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_hz: " << config->property("Tracking.dll_bw_hz", 0.0) << " Hz\n"; + std::cout << "pll_bw_narrow_hz: " << config->property("Tracking.pll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "dll_bw_narrow_hz: " << config->property("Tracking.dll_bw_narrow_hz", 0.0) << " Hz\n"; + std::cout << "extend_correlation_symbols: " << config->property("Tracking.extend_correlation_symbols", 0) << " Symbols\n"; std::cout << "*****************************************\n"; std::cout << "*****************************************\n"; } -bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) +bool TrackingPullInTestFpga::acquire_signal(int SV_ID) { // 1. Setup GNU Radio flowgraph (file_source -> Acquisition_10m) gr::top_block_sptr top_block; @@ -326,25 +390,117 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) // Satellite signal definition Gnss_Synchro tmp_gnss_synchro; tmp_gnss_synchro.Channel_ID = 0; - tmp_gnss_synchro.System = 'G'; - std::string signal = "1C"; - signal.copy(tmp_gnss_synchro.Signal, 2, 0); - tmp_gnss_synchro.PRN = SV_ID; - config = std::make_shared(); config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); + config->set_property("Acquisition.blocking_on_standby", "true"); + config->set_property("Acquisition.blocking", "true"); + config->set_property("Acquisition.dump", "false"); + config->set_property("Acquisition.dump_filename", "./data/acquisition.dat"); + config->set_property("Acquisition.use_CFAR_algorithm", "false"); - config->set_property("Acquisition.max_dwells", "10"); - config->set_property("Acquisition.dump", "true"); - GNSSBlockFactory block_factory; - GpsL1CaPcpsAcquisitionFineDoppler* acquisition; - acquisition = new GpsL1CaPcpsAcquisitionFineDoppler(config.get(), "Acquisition", 1, 1); + std::shared_ptr acquisition; + + std::string System_and_Signal; + //create the correspondign acquisition block according to the desired tracking signal + if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'G'; + std::string signal = "1C"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "GPS L1 CA"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + //acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0) + { + tmp_gnss_synchro.System = 'E'; + std::string signal = "1B"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "Galileo E1B"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L2_M_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'G'; + std::string signal = "2S"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "GPS L2CM"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + { + tmp_gnss_synchro.System = 'E'; + std::string signal = "5X"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "Galileo E5a"; + config->set_property("Acquisition_5X.coherent_integration_time_ms", "1"); + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + config->set_property("Acquisition.CAF_window_hz", "0"); // **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz + config->set_property("Acquisition.Zero_padding", "0"); //**Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF. + config->set_property("Acquisition.bit_transition_flag", "false"); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + + else if (implementation.compare("Galileo_E5a_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'E'; + std::string signal = "5X"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "Galileo E5a"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else if (implementation.compare("GPS_L5_DLL_PLL_Tracking") == 0) + { + tmp_gnss_synchro.System = 'G'; + std::string signal = "L5"; + const char* str = signal.c_str(); // get a C style null terminated string + std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null + tmp_gnss_synchro.PRN = SV_ID; + System_and_Signal = "GPS L5I"; + config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); + acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); + } + else + { + std::cout << "The test can not run with the selected tracking implementation\n "; + throw(std::exception()); + } - acquisition->set_channel(1); acquisition->set_gnss_synchro(&tmp_gnss_synchro); + acquisition->set_channel(0); + acquisition->set_doppler_max(config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz)); + acquisition->set_doppler_step(config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz)); acquisition->set_threshold(config->property("Acquisition.threshold", FLAGS_external_signal_acquisition_threshold)); - acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000)); - acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500)); + acquisition->init(); + acquisition->set_local_code(); + acquisition->set_state(1); // Ensure that acquisition starts at the first sample + acquisition->connect(top_block); + + gr::blocks::file_source::sptr file_source; + std::string file = FLAGS_signal_file; + const char* file_name = file.c_str(); + file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); + file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample + gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); + //gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration); + + top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); + top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0); + //top_block->connect(head_samples, 0, acquisition->get_left_block(), 0); boost::shared_ptr msg_rx; try @@ -357,15 +513,8 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) exit(0); } - gr::blocks::file_source::sptr file_source; - std::string file = FLAGS_signal_file; - const char* file_name = file.c_str(); - file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); - gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); - gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); - top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); - top_block->connect(gr_interleaved_char_to_complex, 0, acquisition->get_left_block(), 0); - top_block->msg_connect(acquisition->get_left_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + msg_rx->top_block = top_block; + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); // 5. Run the flowgraph // Get visible GPS satellites (positive acquisitions with Doppler measurements) @@ -380,19 +529,34 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) code_delay_measurements_map.clear(); acq_samplestamp_map.clear(); - for (unsigned int PRN = 1; PRN < 33; PRN++) + unsigned int MAX_PRN_IDX = 0; + + switch (tmp_gnss_synchro.System) + { + case 'G': + MAX_PRN_IDX = 33; + break; + case 'E': + MAX_PRN_IDX = 37; + break; + default: + MAX_PRN_IDX = 33; + } + + for (unsigned int PRN = 1; PRN < MAX_PRN_IDX; PRN++) { tmp_gnss_synchro.PRN = PRN; acquisition->set_gnss_synchro(&tmp_gnss_synchro); acquisition->init(); acquisition->set_local_code(); acquisition->reset(); + acquisition->set_state(1); msg_rx->rx_message = 0; top_block->run(); if (start_msg == true) { std::cout << "Reading external signal file: " << FLAGS_signal_file << std::endl; - std::cout << "Searching for GPS Satellites in L1 band..." << std::endl; + std::cout << "Searching for " << System_and_Signal << " Satellites..." << std::endl; std::cout << "["; start_msg = false; } @@ -412,10 +576,16 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) std::cout << " . "; } top_block->stop(); - file_source->seek(0, 0); + file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample std::cout.flush(); } std::cout << "]" << std::endl; + std::cout << "-------------------------------------------\n"; + + for (auto& x : doppler_measurements_map) + { + std::cout << "DETECTED SATELLITE " << System_and_Signal << " PRN: " << x.first << " with Doppler: " << x.second << " [Hz], code phase: " << code_delay_measurements_map.at(x.first) << " [samples] at signal SampleStamp " << acq_samplestamp_map.at(x.first) << "\n"; + } // report the elapsed time end = std::chrono::system_clock::now(); @@ -426,7 +596,7 @@ bool GpsL1CADllPllTrackingPullInTest::acquire_GPS_L1CA_signal(int SV_ID) return true; } -TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) +TEST_F(TrackingPullInTestFpga, ValidationOfResults) { //************************************************* //***** STEP 1: Prepare the parameters sweep ****** @@ -475,7 +645,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) if (FLAGS_enable_external_signal_file) { //create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters - ASSERT_EQ(acquire_GPS_L1CA_signal(FLAGS_test_satellite_PRN), true); + ASSERT_EQ(acquire_signal(FLAGS_test_satellite_PRN), true); bool found_satellite = doppler_measurements_map.find(FLAGS_test_satellite_PRN) != doppler_measurements_map.end(); EXPECT_TRUE(found_satellite) << "Error: satellite SV: " << FLAGS_test_satellite_PRN << " is not acquired"; if (!found_satellite) return; @@ -507,7 +677,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) int test_satellite_PRN = 0; double true_acq_doppler_hz = 0.0; double true_acq_delay_samples = 0.0; - unsigned long int acq_samplestamp_samples = 0; + uint64_t acq_samplestamp_samples = 0; tracking_true_obs_reader true_obs_data; if (!FLAGS_enable_external_signal_file) @@ -556,9 +726,9 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) //create flowgraph top_block = gr::make_top_block("Tracking test"); - std::shared_ptr trk_ = factory->GetBlock(config, "Tracking_1C", implementation, 1, 1); + std::shared_ptr trk_ = factory->GetBlock(config, "Tracking", config->property("Tracking.implementation", std::string("undefined")), 1, 1); std::shared_ptr tracking = std::dynamic_pointer_cast(trk_); - boost::shared_ptr msg_rx = GpsL1CADllPllTrackingPullInTest_msg_rx_make(); + boost::shared_ptr msg_rx = TrackingPullInTestFpga_msg_rx_make(); ASSERT_NO_THROW({ @@ -587,19 +757,20 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); + gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration); top_block->connect(file_source, 0, gr_interleaved_char_to_complex, 0); - top_block->connect(gr_interleaved_char_to_complex, 0, tracking->get_left_block(), 0); + top_block->connect(gr_interleaved_char_to_complex, 0, head_samples, 0); + top_block->connect(head_samples, 0, tracking->get_left_block(), 0); top_block->connect(tracking->get_right_block(), 0, sink, 0); top_block->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - - file_source->seek(acq_samplestamp_samples, 0); + file_source->seek(2 * FLAGS_skip_samples, 0); //skip head. ibyte, two bytes per complex sample }) << "Failure connecting the blocks of tracking test."; //******************************************************************** //***** STEP 5: Perform the signal tracking and read the results ***** //******************************************************************** - std::cout << "------------ START TRACKING -------------" << std::endl; + std::cout << "--- START TRACKING WITH PULL-IN ERROR: " << acq_doppler_error_hz_values.at(current_acq_doppler_error_idx) << " [Hz] and " << acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx) << " [Chips] ---" << std::endl; tracking->start_tracking(); std::chrono::time_point start, end; EXPECT_NO_THROW({ @@ -624,7 +795,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) ASSERT_EQ(trk_dump.open_obs_file(std::string("./tracking_ch_0.dat")), true) << "Failure opening tracking dump file"; - long int n_measured_epochs = trk_dump.num_epochs(); + int64_t n_measured_epochs = trk_dump.num_epochs(); //todo: use vectors instead arma::vec trk_timestamp_s = arma::zeros(n_measured_epochs, 1); arma::vec trk_acc_carrier_phase_cycles = arma::zeros(n_measured_epochs, 1); @@ -634,10 +805,13 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) std::vector prompt; std::vector early; std::vector late; + std::vector v_early; + std::vector v_late; std::vector promptI; std::vector promptQ; std::vector CN0_dBHz; - long int epoch_counter = 0; + std::vector Doppler; + int64_t epoch_counter = 0; while (trk_dump.read_binary_obs()) { trk_timestamp_s(epoch_counter) = static_cast(trk_dump.PRN_start_sample_count) / static_cast(baseband_sampling_freq); @@ -651,10 +825,12 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) prompt.push_back(trk_dump.abs_P); early.push_back(trk_dump.abs_E); late.push_back(trk_dump.abs_L); + v_early.push_back(trk_dump.abs_VE); + v_late.push_back(trk_dump.abs_VL); promptI.push_back(trk_dump.prompt_I); promptQ.push_back(trk_dump.prompt_Q); CN0_dBHz.push_back(trk_dump.CN0_SNV_dB_Hz); - + Doppler.push_back(trk_dump.carrier_doppler_hz); epoch_counter++; } @@ -686,7 +862,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) } else { - g1.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g1.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } g1.set_grid(); @@ -696,19 +872,23 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) g1.plot_xy(trk_timestamp_s, prompt, "Prompt", decimate); g1.plot_xy(trk_timestamp_s, early, "Early", decimate); g1.plot_xy(trk_timestamp_s, late, "Late", decimate); + if (implementation.compare("Galileo_E1_DLL_PLL_VEML_Tracking") == 0) + { + g1.plot_xy(trk_timestamp_s, v_early, "Very Early", decimate); + g1.plot_xy(trk_timestamp_s, v_late, "Very Late", decimate); + } g1.set_legend(); - //g1.savetops("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx))); - //g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); + g1.savetops("Correlators_outputs"); Gnuplot g2("points"); g2.showonscreen(); // window output if (!FLAGS_enable_external_signal_file) { - g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } else { - g2.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g2.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } g2.set_grid(); @@ -716,8 +896,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) g2.set_ylabel("Quadrature"); //g2.cmd("set size ratio -1"); g2.plot_xy(promptI, promptQ); - //g2.savetops("Constellation"); - //g2.savetopdf("Constellation", 18); + g2.savetops("Constellation"); Gnuplot g3("linespoints"); if (!FLAGS_enable_external_signal_file) @@ -726,7 +905,7 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) } else { - g3.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + g3.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } g3.set_grid(); g3.set_xlabel("Time [s]"); @@ -737,9 +916,31 @@ TEST_F(GpsL1CADllPllTrackingPullInTest, ValidationOfResults) std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); g3.set_legend(); - //g3.savetops("CN0_output"); - //g3.savetopdf("CN0_output", 18); + g3.savetops("CN0_output"); + g3.showonscreen(); // window output + + Gnuplot g4("linespoints"); + if (!FLAGS_enable_external_signal_file) + { + g4.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + else + { + g4.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); + } + g4.set_grid(); + g4.set_xlabel("Time [s]"); + g4.set_ylabel("Estimated Doppler [Hz]"); + g4.cmd("set key box opaque"); + + g4.plot_xy(trk_timestamp_s, Doppler, + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + "[dB-Hz]", decimate); + + g4.set_legend(); + g4.savetops("Doppler"); + + g4.showonscreen(); // window output } } catch (const GnuplotException& ge) diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index 1396ed3e6..c68294b45 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -17,3 +17,7 @@ # add_subdirectory(front-end-cal) + +if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) + add_subdirectory(rinex2assist) +endif() diff --git a/src/utils/front-end-cal/CMakeLists.txt b/src/utils/front-end-cal/CMakeLists.txt index 81ecf1e54..16dfa40be 100644 --- a/src/utils/front-end-cal/CMakeLists.txt +++ b/src/utils/front-end-cal/CMakeLists.txt @@ -18,10 +18,11 @@ if(OPENSSL_FOUND) - add_definitions( -DUSE_OPENSSL_FALLBACK=1 ) -endif(OPENSSL_FOUND) + add_definitions(-DUSE_OPENSSL_FALLBACK=1) +endif() set(FRONT_END_CAL_SOURCES front_end_cal.cc) +set(FRONT_END_CAL_HEADERS front_end_cal.h) include_directories( ${CMAKE_SOURCE_DIR}/src/core/system_parameters @@ -30,7 +31,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/core/libs ${CMAKE_SOURCE_DIR}/src/core/libs/supl ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp - ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl + ${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/adapters ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/gnuradio_blocks ${CMAKE_SOURCE_DIR}/src/algorithms/acquisition/libs @@ -41,78 +42,75 @@ include_directories( ${GNURADIO_BLOCKS_INCLUDE_DIRS} ${ARMADILLO_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} + ${PUGIXML_INCLUDE_DIR} ${VOLK_GNSSSDR_INCLUDE_DIRS} ) -file(GLOB FRONT_END_CAL_HEADERS "*.h") -list(SORT FRONT_END_CAL_HEADERS) add_library(front_end_cal_lib ${FRONT_END_CAL_SOURCES} ${FRONT_END_CAL_HEADERS}) source_group(Headers FILES ${FRONT_END_CAL_HEADERS}) -target_link_libraries(front_end_cal_lib ${MAC_LIBRARIES} - ${Boost_LIBRARIES} - ${GNURADIO_RUNTIME_LIBRARIES} - ${GNURADIO_BLOCKS_LIBRARIES} - ${GNURADIO_FFT_LIBRARIES} - ${GNURADIO_FILTER_LIBRARIES} - ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${ARMADILLO_LIBRARIES} - ${VOLK_GNSSSDR_LIBRARIES} ${ORC_LIBRARIES} - ${GNSS_SDR_OPTIONAL_LIBS} - rx_core_lib - gnss_sdr_flags - gnss_rx - channel_fsm +target_link_libraries(front_end_cal_lib + ${MAC_LIBRARIES} + ${THREAD_LIBRARIES} + ${Boost_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${GNURADIO_FFT_LIBRARIES} + ${GNURADIO_FILTER_LIBRARIES} + ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${ARMADILLO_LIBRARIES} + ${VOLK_GNSSSDR_LIBRARIES} ${ORC_LIBRARIES} + ${GNSS_SDR_OPTIONAL_LIBS} + rx_core_lib + gnss_sdr_flags + gnss_rx + channel_fsm ) - + add_dependencies(front_end_cal_lib glog-${glog_RELEASE} armadillo-${armadillo_RELEASE}) -add_definitions( -DGNSS_SDR_VERSION="${VERSION}" ) -add_definitions( -DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}" ) +add_definitions(-DGNSS_SDR_VERSION="${VERSION}") +add_definitions(-DGNSSSDR_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}") add_executable(front-end-cal ${CMAKE_CURRENT_SOURCE_DIR}/main.cc) add_custom_command(TARGET front-end-cal POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ - ${CMAKE_SOURCE_DIR}/install/$) + COMMAND ${CMAKE_COMMAND} -E copy $ + ${CMAKE_SOURCE_DIR}/install/$) - -target_link_libraries(front-end-cal ${MAC_LIBRARIES} - ${Boost_LIBRARIES} - ${GNURADIO_RUNTIME_LIBRARIES} - ${GNURADIO_BLOCKS_LIBRARIES} - ${GNURADIO_FFT_LIBRARIES} - ${GNURADIO_FILTER_LIBRARIES} - ${GFlags_LIBS} - ${GLOG_LIBRARIES} - ${ARMADILLO_LIBRARIES} - ${VOLK_GNSSSDR_LIBRARIES} ${ORC_LIBRARIES} - ${GNSS_SDR_OPTIONAL_LIBS} - rx_core_lib - gnss_rx - front_end_cal_lib +target_link_libraries(front-end-cal + ${MAC_LIBRARIES} + ${Boost_LIBRARIES} + ${GNURADIO_RUNTIME_LIBRARIES} + ${GNURADIO_BLOCKS_LIBRARIES} + ${GNURADIO_FFT_LIBRARIES} + ${GNURADIO_FILTER_LIBRARIES} + ${GFlags_LIBS} + ${GLOG_LIBRARIES} + ${ARMADILLO_LIBRARIES} + ${VOLK_GNSSSDR_LIBRARIES} ${ORC_LIBRARIES} + ${GNSS_SDR_OPTIONAL_LIBS} + rx_core_lib + gnss_rx + front_end_cal_lib ) - install(TARGETS front-end-cal - RUNTIME DESTINATION bin - COMPONENT "front-end-cal" + RUNTIME DESTINATION bin + COMPONENT "front-end-cal" ) find_program(GZIP gzip - /bin - /usr/bin - /usr/local/bin - /opt/local/bin - /sbin - ) + /bin + /usr/bin + /usr/local/bin + /opt/local/bin + /sbin +) if(NOT GZIP_NOTFOUND) execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/docs/manpage/front-end-cal-manpage - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/front-end-cal.1.gz") - + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_FILE "${CMAKE_BINARY_DIR}/front-end-cal.1.gz") install(FILES ${CMAKE_BINARY_DIR}/front-end-cal.1.gz DESTINATION share/man/man1) -endif(NOT GZIP_NOTFOUND) - - +endif() diff --git a/src/utils/front-end-cal/front_end_cal.cc b/src/utils/front-end-cal/front_end_cal.cc index 6b8b937ac..9fec07116 100644 --- a/src/utils/front-end-cal/front_end_cal.cc +++ b/src/utils/front-end-cal/front_end_cal.cc @@ -110,7 +110,7 @@ int FrontEndCal::Get_SUPL_Assist() supl_client_ephemeris_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_port", 7275); supl_client_acquisition_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_acquisition_port", 7275); supl_mcc = configuration_->property("GNSS-SDR.SUPL_MCC", 244); - supl_mns = configuration_->property("GNSS-SDR.SUPL_MNS", 5); + supl_mns = configuration_->property("GNSS-SDR.SUPL_MNC", 5); std::string default_lac = "0x59e2"; std::string default_ci = "0x31b0"; diff --git a/src/utils/front-end-cal/main.cc b/src/utils/front-end-cal/main.cc index 69b6c6e97..c3f129803 100644 --- a/src/utils/front-end-cal/main.cc +++ b/src/utils/front-end-cal/main.cc @@ -68,6 +68,7 @@ #include #include #include +#include #include // for ctime #include #include @@ -123,7 +124,7 @@ void FrontEndCal_msg_rx::msg_handler_events(pmt::pmt_t msg) { try { - long int message = pmt::to_long(msg); + int64_t message = pmt::to_long(msg); rx_message = message; channel_internal_queue.push(rx_message); } @@ -204,7 +205,7 @@ bool front_end_capture(std::shared_ptr configuration) sink = gr::blocks::file_sink::make(sizeof(gr_complex), "tmp_capture.dat"); //--- Find number of samples per spreading code --- - long fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", 2048000); + int64_t fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", 2048000); int samples_per_code = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); int nsamples = samples_per_code * 50; @@ -234,7 +235,7 @@ bool front_end_capture(std::shared_ptr configuration) } -static time_t utc_time(int week, long tow) +static time_t utc_time(int week, int64_t tow) { time_t t; @@ -350,7 +351,7 @@ int main(int argc, char** argv) signal.copy(gnss_synchro->Signal, 2, 0); gnss_synchro->PRN = 1; - long fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", 2048000); + int64_t fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", 2048000); configuration->set_property("Acquisition.max_dwells", "10"); GNSSBlockFactory block_factory; @@ -447,7 +448,7 @@ int main(int argc, char** argv) } catch (const boost::exception& e) { - LOG(INFO) << "Exception caught while pushing to he internal queue."; + LOG(INFO) << "Exception caught while pushing to the internal queue."; } try { @@ -480,12 +481,12 @@ int main(int argc, char** argv) Eph_map = global_gps_ephemeris_map.get_map_copy(); current_TOW = Eph_map.begin()->second.d_TOW; - time_t t = utc_time(Eph_map.begin()->second.i_GPS_week, (long int)current_TOW); + time_t t = utc_time(Eph_map.begin()->second.i_GPS_week, static_cast(current_TOW)); - fprintf(stdout, "Reference Time:\n"); - fprintf(stdout, " GPS Week: %d\n", Eph_map.begin()->second.i_GPS_week); - fprintf(stdout, " GPS TOW: %ld %lf\n", (long int)current_TOW, (long int)current_TOW * 0.08); - fprintf(stdout, " ~ UTC: %s", ctime(&t)); + std::cout << "Reference Time:" << std::endl; + std::cout << " GPS Week: " << Eph_map.begin()->second.i_GPS_week << std::endl; + std::cout << " GPS TOW: " << static_cast(current_TOW) << " " << static_cast(current_TOW) * 0.08 << std::endl; + std::cout << " ~ UTC: " << ctime(&t) << std::endl; std::cout << "Current TOW obtained from SUPL assistance = " << current_TOW << std::endl; } else diff --git a/src/utils/matlab/gps_l1_ca_kf_plot_sample.m b/src/utils/matlab/gps_l1_ca_kf_plot_sample.m new file mode 100644 index 000000000..f8fcb0ed7 --- /dev/null +++ b/src/utils/matlab/gps_l1_ca_kf_plot_sample.m @@ -0,0 +1,93 @@ +% Reads GNSS-SDR Tracking dump binary file using the provided +% function and plots some internal variables +% Javier Arribas, 2011. jarribas(at)cttc.es +% ------------------------------------------------------------------------- +% +% Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) +% +% GNSS-SDR is a software defined Global Navigation +% Satellite Systems receiver +% +% This file is part of GNSS-SDR. +% +% GNSS-SDR is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% at your option) any later version. +% +% GNSS-SDR is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with GNSS-SDR. If not, see . +% +% ------------------------------------------------------------------------- +% + +close all; +clear all; + +if ~exist('dll_pll_veml_read_tracking_dump.m', 'file') + addpath('./libs') +end + + +samplingFreq = 6625000; %[Hz] +channels = 8; +first_channel = 0; +code_period = 0.001; + +path = '/archive/'; %% CHANGE THIS PATH +figpath = [path]; + +for N=1:1:channels + tracking_log_path = [path 'epl_tracking_ch_' num2str(N+first_channel-1) '.dat']; %% CHANGE epl_tracking_ch_ BY YOUR dump_filename + GNSS_tracking(N) = gps_l1_ca_kf_read_tracking_dump(tracking_log_path); +end + +% GNSS-SDR format conversion to MATLAB GPS receiver + +for N=1:1:channels + trackResults(N).status = 'T'; %fake track + trackResults(N).codeFreq = GNSS_tracking(N).code_freq_hz.'; + trackResults(N).carrFreq = GNSS_tracking(N).carrier_doppler_hz.'; + trackResults(N).carrFreqRate = GNSS_tracking(N).carrier_dopplerrate_hz2.'; + trackResults(N).dllDiscr = GNSS_tracking(N).code_error.'; + trackResults(N).dllDiscrFilt = GNSS_tracking(N).code_nco.'; + trackResults(N).pllDiscr = GNSS_tracking(N).carr_error.'; + trackResults(N).pllDiscrFilt = GNSS_tracking(N).carr_nco.'; + + trackResults(N).I_P = GNSS_tracking(N).prompt_I.'; + trackResults(N).Q_P = GNSS_tracking(N).prompt_Q.'; + + trackResults(N).I_E = GNSS_tracking(N).E.'; + trackResults(N).I_L = GNSS_tracking(N).L.'; + trackResults(N).Q_E = zeros(1,length(GNSS_tracking(N).E)); + trackResults(N).Q_L = zeros(1,length(GNSS_tracking(N).E)); + trackResults(N).PRN = GNSS_tracking(N).PRN.'; + trackResults(N).CNo = GNSS_tracking(N).CN0_SNV_dB_Hz.'; + + + kalmanResults(N).PRN = GNSS_tracking(N).PRN.'; + kalmanResults(N).innovation = GNSS_tracking(N).carr_error.'; + kalmanResults(N).state1 = GNSS_tracking(N).carr_nco.'; + kalmanResults(N).state2 = GNSS_tracking(N).carrier_doppler_hz.'; + kalmanResults(N).state3 = GNSS_tracking(N).carrier_dopplerrate_hz2.'; + kalmanResults(N).r_noise_cov = GNSS_tracking(N).carr_noise_sigma2.'; + kalmanResults(N).CNo = GNSS_tracking(N).CN0_SNV_dB_Hz.'; + + % Use original MATLAB tracking plot function + settings.numberOfChannels = channels; + settings.msToProcess = length(GNSS_tracking(N).E); + settings.codePeriod = code_period; + settings.timeStartInSeconds = 20; + + %plotTracking(N, trackResults, settings) + plotKalman(N, kalmanResults, settings) + + saveas(gcf, [figpath 'epl_tracking_ch_' num2str(N) '_PRN_' num2str(trackResults(N).PRN(end)) '.png'], 'png') +end + + diff --git a/src/utils/matlab/libs/dll_pll_veml_read_tracking_dump.m b/src/utils/matlab/libs/dll_pll_veml_read_tracking_dump.m index a53dedbf9..698a1b5df 100644 --- a/src/utils/matlab/libs/dll_pll_veml_read_tracking_dump.m +++ b/src/utils/matlab/libs/dll_pll_veml_read_tracking_dump.m @@ -33,7 +33,7 @@ function [GNSS_tracking] = dll_pll_veml_read_tracking_dump (filename, count) m = nargchk (1,2,nargin); -num_float_vars = 17; +num_float_vars = 19; num_unsigned_long_int_vars = 1; num_double_vars = 1; num_unsigned_int_vars = 1; @@ -114,17 +114,23 @@ else fseek(f,bytes_shift,'bof'); % move to next float v16 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); bytes_shift = bytes_shift + float_size_bytes; - fseek(f,bytes_shift,'bof'); % move to next interleaved float + fseek(f,bytes_shift,'bof'); % move to next float v17 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); bytes_shift = bytes_shift + float_size_bytes; fseek(f,bytes_shift,'bof'); % move to next float - v18 = fread (f, count, 'float', skip_bytes_each_read-float_size_bytes); + v18 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved float + v19 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v20 = fread (f, count, 'float', skip_bytes_each_read-float_size_bytes); bytes_shift = bytes_shift + float_size_bytes; fseek(f,bytes_shift,'bof'); % move to next double - v19 = fread (f, count, 'double', skip_bytes_each_read - double_size_bytes); + v21 = fread (f, count, 'double', skip_bytes_each_read - double_size_bytes); bytes_shift = bytes_shift + double_size_bytes; fseek(f,bytes_shift,'bof'); % move to next unsigned int - v20 = fread (f, count, 'uint', skip_bytes_each_read - unsigned_int_size_bytes); + v22 = fread (f, count, 'uint', skip_bytes_each_read - unsigned_int_size_bytes); fclose (f); GNSS_tracking.VE = v1; @@ -137,15 +143,17 @@ else GNSS_tracking.PRN_start_sample = v8; GNSS_tracking.acc_carrier_phase_rad = v9; GNSS_tracking.carrier_doppler_hz = v10; - GNSS_tracking.code_freq_hz = v11; - GNSS_tracking.carr_error = v12; - GNSS_tracking.carr_nco = v13; - GNSS_tracking.code_error = v14; - GNSS_tracking.code_nco = v15; - GNSS_tracking.CN0_SNV_dB_Hz = v16; - GNSS_tracking.carrier_lock_test = v17; - GNSS_tracking.var1 = v18; - GNSS_tracking.var2 = v19; - GNSS_tracking.PRN = v20; + GNSS_tracking.carrier_doppler_rate_hz_s = v11; + GNSS_tracking.code_freq_hz = v12; + GNSS_tracking.code_freq_rate_hz_s = v13; + GNSS_tracking.carr_error = v14; + GNSS_tracking.carr_nco = v15; + GNSS_tracking.code_error = v16; + GNSS_tracking.code_nco = v17; + GNSS_tracking.CN0_SNV_dB_Hz = v18; + GNSS_tracking.carrier_lock_test = v19; + GNSS_tracking.var1 = v20; + GNSS_tracking.var2 = v21; + GNSS_tracking.PRN = v22; end diff --git a/src/utils/matlab/libs/gps_l1_ca_kf_read_tracking_dump.m b/src/utils/matlab/libs/gps_l1_ca_kf_read_tracking_dump.m new file mode 100644 index 000000000..e1f1c8687 --- /dev/null +++ b/src/utils/matlab/libs/gps_l1_ca_kf_read_tracking_dump.m @@ -0,0 +1,158 @@ +% Usage: gps_l1_ca_kf_read_tracking_dump (filename, [count]) +% +% Opens GNSS-SDR tracking binary log file .dat and returns the contents + +% Read GNSS-SDR Tracking dump binary file into MATLAB. +% Javier Arribas, 2011. jarribas(at)cttc.es +% ------------------------------------------------------------------------- +% +% Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) +% +% GNSS-SDR is a software defined Global Navigation +% Satellite Systems receiver +% +% This file is part of GNSS-SDR. +% +% GNSS-SDR is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% at your option) any later version. +% +% GNSS-SDR is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with GNSS-SDR. If not, see . +% +% ------------------------------------------------------------------------- +% + +function [GNSS_tracking] = gps_l1_ca_kf_read_tracking_dump (filename, count) + +m = nargchk (1,2,nargin); + +num_float_vars = 19; +num_unsigned_long_int_vars = 1; +num_double_vars = 1; +num_unsigned_int_vars = 1; + +if(~isempty(strfind(computer('arch'), '64'))) + % 64-bit computer + double_size_bytes = 8; + unsigned_long_int_size_bytes = 8; + float_size_bytes = 4; + unsigned_int_size_bytes = 4; +else + double_size_bytes = 8; + unsigned_long_int_size_bytes = 4; + float_size_bytes = 4; + unsigned_int_size_bytes = 4; +end + +skip_bytes_each_read = float_size_bytes * num_float_vars + unsigned_long_int_size_bytes * num_unsigned_long_int_vars + ... + double_size_bytes * num_double_vars + num_unsigned_int_vars*unsigned_int_size_bytes; + +bytes_shift = 0; + +if (m) + usage (m); +end + +if (nargin < 2) + count = Inf; +end +%loops_counter = fread (f, count, 'uint32',4*12); +f = fopen (filename, 'rb'); +if (f < 0) +else + v1 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v2 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v3 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v4 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v5 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v6 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v7 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved float + v8 = fread (f, count, 'long', skip_bytes_each_read - unsigned_long_int_size_bytes); + bytes_shift = bytes_shift + unsigned_long_int_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v9 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v10 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v11 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v12 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v13 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v14 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v15 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v16 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v17 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v18 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next interleaved float + v19 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next float + v20 = fread (f, count, 'float', skip_bytes_each_read-float_size_bytes); + bytes_shift = bytes_shift + float_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next double + v21 = fread (f, count, 'double', skip_bytes_each_read - double_size_bytes); + bytes_shift = bytes_shift + double_size_bytes; + fseek(f,bytes_shift,'bof'); % move to next unsigned int + v22 = fread (f, count, 'uint', skip_bytes_each_read - unsigned_int_size_bytes); + fclose (f); + + GNSS_tracking.VE = v1; + GNSS_tracking.E = v2; + GNSS_tracking.P = v3; + GNSS_tracking.L = v4; + GNSS_tracking.VL = v5; + GNSS_tracking.prompt_I = v6; + GNSS_tracking.prompt_Q = v7; + GNSS_tracking.PRN_start_sample = v8; + GNSS_tracking.acc_carrier_phase_rad = v9; + GNSS_tracking.carrier_doppler_hz = v10; + GNSS_tracking.carrier_dopplerrate_hz2 = v11; + GNSS_tracking.code_freq_hz = v12; + GNSS_tracking.carr_error = v13; + GNSS_tracking.carr_noise_sigma2 = v14; + GNSS_tracking.carr_nco = v15; + GNSS_tracking.code_error = v16; + GNSS_tracking.code_nco = v17; + GNSS_tracking.CN0_SNV_dB_Hz = v18; + GNSS_tracking.carrier_lock_test = v19; + GNSS_tracking.var1 = v20; + GNSS_tracking.var2 = v21; + GNSS_tracking.PRN = v22; +end \ No newline at end of file diff --git a/src/utils/matlab/libs/plotKalman.m b/src/utils/matlab/libs/plotKalman.m new file mode 100644 index 000000000..e05fd0d52 --- /dev/null +++ b/src/utils/matlab/libs/plotKalman.m @@ -0,0 +1,135 @@ +function plotKalman(channelList, trackResults, settings) +% This function plots the tracking results for the given channel list. +% +% plotTracking(channelList, trackResults, settings) +% +% Inputs: +% channelList - list of channels to be plotted. +% trackResults - tracking results from the tracking function. +% settings - receiver settings. + +%-------------------------------------------------------------------------- +% SoftGNSS v3.0 +% +% Copyright (C) Darius Plausinaitis +% Written by Darius Plausinaitis +%-------------------------------------------------------------------------- +%This program is free software; you can redistribute it and/or +%modify it under the terms of the GNU General Public License +%as published by the Free Software Foundation; either version 2 +%of the License, or (at your option) any later version. +% +%This program is distributed in the hope that it will be useful, +%but WITHOUT ANY WARRANTY; without even the implied warranty of +%MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%GNU General Public License for more details. +% +%You should have received a copy of the GNU General Public License +%along with this program; if not, write to the Free Software +%Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +%USA. +%-------------------------------------------------------------------------- + +% Protection - if the list contains incorrect channel numbers +channelList = intersect(channelList, 1:settings.numberOfChannels); + +%=== For all listed channels ============================================== +for channelNr = channelList + + %% Select (or create) and clear the figure ================================ + % The number 200 is added just for more convenient handling of the open + % figure windows, when many figures are closed and reopened. + % Figures drawn or opened by the user, will not be "overwritten" by + % this function. + + figure(channelNr +200); + clf(channelNr +200); + set(channelNr +200, 'Name', ['Channel ', num2str(channelNr), ... + ' (PRN ', ... + num2str(trackResults(channelNr).PRN(end-1)), ... + ') results']); + + timeStart = settings.timeStartInSeconds; + + %% Draw axes ============================================================== + % Row 1 + handles(1, 1) = subplot(4, 2, 1); + handles(1, 2) = subplot(4, 2, 2); + % Row 2 + handles(2, 1) = subplot(4, 2, 3); + handles(2, 2) = subplot(4, 2, 4); + % Row 3 + handles(3, 1) = subplot(4, 2, [5 6]); + % Row 4 + handles(4, 1) = subplot(4, 2, [7 8]); + + %% Plot all figures ======================================================= + + timeAxisInSeconds = (1:settings.msToProcess)/1000; + + %----- CNo for signal---------------------------------- + plot (handles(1, 1), timeAxisInSeconds, ... + trackResults(channelNr).CNo(1:settings.msToProcess), 'b'); + + grid (handles(1, 1)); + axis (handles(1, 1), 'tight'); + xlabel(handles(1, 1), 'Time (s)'); + ylabel(handles(1, 1), 'CNo (dB-Hz)'); + title (handles(1, 1), 'Carrier to Noise Ratio'); + + %----- PLL discriminator filtered---------------------------------- + plot (handles(1, 2), timeAxisInSeconds, ... + trackResults(channelNr).state1(1:settings.msToProcess), 'b'); + + grid (handles(1, 2)); + axis (handles(1, 2), 'tight'); + xlim (handles(1, 2), [timeStart, timeAxisInSeconds(end)]); + xlabel(handles(1, 2), 'Time (s)'); + ylabel(handles(1, 2), 'Phase Amplitude'); + title (handles(1, 2), 'Filtered Carrier Phase'); + + %----- Carrier Frequency -------------------------------- + plot (handles(2, 1), timeAxisInSeconds(2:end), ... + trackResults(channelNr).state2(2:settings.msToProcess), 'Color',[0.42 0.25 0.39]); + + grid (handles(2, 1)); + axis (handles(2, 1)); + xlim (handles(2, 1), [timeStart, timeAxisInSeconds(end)]); + xlabel(handles(2, 1), 'Time (s)'); + ylabel(handles(2, 1), 'Freq (hz)'); + title (handles(2, 1), 'Filtered Doppler Frequency'); + + %----- Carrier Frequency Rate -------------------------------- + plot (handles(2, 2), timeAxisInSeconds(2:end), ... + trackResults(channelNr).state3(2:settings.msToProcess), 'Color',[0.42 0.25 0.39]); + + grid (handles(2, 2)); + axis (handles(2, 2)); + xlim (handles(2, 2), [timeStart, timeAxisInSeconds(end)]); + xlabel(handles(2, 2), 'Time (s)'); + ylabel(handles(2, 2), 'Freq (hz)'); + title (handles(2, 2), 'Filtered Doppler Frequency Rate'); + + %----- PLL discriminator unfiltered-------------------------------- + plot (handles(3, 1), timeAxisInSeconds, ... + trackResults(channelNr).innovation, 'r'); + + grid (handles(3, 1)); + axis (handles(3, 1), 'auto'); + xlim (handles(3, 1), [timeStart, timeAxisInSeconds(end)]); + xlabel(handles(3, 1), 'Time (s)'); + ylabel(handles(3, 1), 'Amplitude'); + title (handles(3, 1), 'Raw PLL discriminator (Innovation)'); + + + %----- PLL discriminator covariance -------------------------------- + plot (handles(4, 1), timeAxisInSeconds, ... + trackResults(channelNr).r_noise_cov, 'r'); + + grid (handles(4, 1)); + axis (handles(4, 1), 'auto'); + xlim (handles(4, 1), [timeStart, timeAxisInSeconds(end)]); + xlabel(handles(4, 1), 'Time (s)'); + ylabel(handles(4, 1), 'Variance'); + title (handles(4, 1), 'Estimated Noise Variance'); +end % for channelNr = channelList diff --git a/src/utils/reproducibility/ieee-access18/L2-access18.conf b/src/utils/reproducibility/ieee-access18/L2-access18.conf index e4bc4ae44..e4d7b5e67 100644 --- a/src/utils/reproducibility/ieee-access18/L2-access18.conf +++ b/src/utils/reproducibility/ieee-access18/L2-access18.conf @@ -85,7 +85,7 @@ Acquisition_2S.doppler_step=125 Acquisition_2S.use_CFAR_algorithm=false -Acquisition_2S.threshold=19.5 +Acquisition_2S.threshold=10 Acquisition_2S.blocking=true @@ -133,7 +133,7 @@ PVT.display_rate_ms=500 ;# KML, GeoJSON, NMEA and RTCM output configuration ;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump. -PVT.dump_filename=./data/PVT +PVT.dump_filename=./data/access18 ;#nmea_dump_filename: NMEA log path and filename PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea diff --git a/src/utils/reproducibility/ieee-access18/plot_dump.m b/src/utils/reproducibility/ieee-access18/plot_dump.m index 33416ad77..11aaba424 100644 --- a/src/utils/reproducibility/ieee-access18/plot_dump.m +++ b/src/utils/reproducibility/ieee-access18/plot_dump.m @@ -62,26 +62,46 @@ ylabel('Navigation data bits','fontname','Times','fontsize', fontsize) grid on -fileID = fopen('data/PVT_ls_pvt.dat', 'r'); -dinfo = dir('data/PVT_ls_pvt.dat'); +fileID = fopen('data/access18.dat', 'r'); +dinfo = dir('data/access18.dat'); filesize = dinfo.bytes; aux = 1; while ne(ftell(fileID), filesize) - navsol.RX_time(aux) = fread(fileID, 1, 'double'); - navsol.X(aux) = fread(fileID, 1, 'double'); - navsol.Y(aux) = fread(fileID, 1, 'double'); - navsol.Z(aux) = fread(fileID, 1, 'double'); - navsol.user_clock(aux) = fread(fileID, 1, 'double'); - navsol.lat(aux) = fread(fileID, 1, 'double'); - navsol.long(aux) = fread(fileID, 1, 'double'); - navsol.height(aux) = fread(fileID, 1, 'double'); + navsol.TOW_at_current_symbol_ms(aux) = fread(fileID, 1, 'uint32'); + navsol.week(aux) = fread(fileID, 1, 'uint32'); + navsol.RX_time(aux) = fread(fileID, 1, 'double'); + navsol.user_clock_offset(aux) = fread(fileID, 1, 'double'); + navsol.X(aux) = fread(fileID, 1, 'double'); + navsol.Y(aux) = fread(fileID, 1, 'double'); + navsol.Z(aux) = fread(fileID, 1, 'double'); + navsol.VX(aux) = fread(fileID, 1, 'double'); + navsol.VY(aux) = fread(fileID, 1, 'double'); + navsol.VZ(aux) = fread(fileID, 1, 'double'); + navsol.varXX(aux) = fread(fileID, 1, 'double'); + navsol.varYY(aux) = fread(fileID, 1, 'double'); + navsol.varZZ(aux) = fread(fileID, 1, 'double'); + navsol.varXY(aux) = fread(fileID, 1, 'double'); + navsol.varYZ(aux) = fread(fileID, 1, 'double'); + navsol.varZX(aux) = fread(fileID, 1, 'double'); + navsol.latitude(aux) = fread(fileID, 1, 'double'); + navsol.longitude(aux) = fread(fileID, 1, 'double'); + navsol.height(aux) = fread(fileID, 1, 'double'); + navsol.number_sats(aux) = fread(fileID, 1, 'uint8'); + navsol.solution_status(aux) = fread(fileID, 1, 'uint8'); + navsol.solution_type(aux) = fread(fileID, 1, 'uint8'); + navsol.AR_ratio_factor(aux) = fread(fileID, 1, 'float'); + navsol.AR_ratio_threshold(aux) = fread(fileID, 1, 'float'); + navsol.GDOP(aux) = fread(fileID, 1, 'double'); + navsol.PDOP(aux) = fread(fileID, 1, 'double'); + navsol.HDOP(aux) = fread(fileID, 1, 'double'); + navsol.VDOP(aux) = fread(fileID, 1, 'double'); aux = aux + 1; end fclose(fileID); -mean_Latitude = mean(navsol.lat); -mean_Longitude = mean(navsol.long); +mean_Latitude = mean(navsol.latitude); +mean_Longitude = mean(navsol.longitude); mean_h = mean(navsol.height); utmZone = findUtmZone(mean_Latitude, mean_Longitude); [ref_X_cart, ref_Y_cart, ref_Z_cart] = geo2cart(dms2mat(deg2dms(mean_Latitude)), dms2mat(deg2dms(mean_Longitude)), mean_h, 5); diff --git a/src/utils/rinex2assist/CMakeLists.txt b/src/utils/rinex2assist/CMakeLists.txt new file mode 100644 index 000000000..344c0694b --- /dev/null +++ b/src/utils/rinex2assist/CMakeLists.txt @@ -0,0 +1,80 @@ +# Copyright (C) 2012-2018 (see AUTHORS file for a list of contributors) +# +# This file is part of GNSS-SDR. +# +# GNSS-SDR is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GNSS-SDR is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNSS-SDR. If not, see . +# + +find_package(GPSTK QUIET) +if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) + include(GNUInstallDirs) + string(REGEX REPLACE /[^/]*$ "" LIBDIR ${CMAKE_INSTALL_LIBDIR}) + set(GPSTK_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/../../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/${LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(GPSTK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../thirdparty/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/include) +endif() + +set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} ${GPSTK_INCLUDE_DIR}/gpstk) + +find_package(Boost COMPONENTS iostreams serialization QUIET) + +find_program(UNCOMPRESS_EXECUTABLE uncompress + PATHS /bin + /usr/bin + /usr/sbin +) + +if(NOT UNCOMPRESS_EXECUTABLE-NOTFOUND) + add_definitions(-DUNCOMPRESS_EXECUTABLE="${UNCOMPRESS_EXECUTABLE}") +else() + add_definitions(-DUNCOMPRESS_EXECUTABLE="") +endif() + +if(Boost_FOUND) + include_directories( + ${CMAKE_SOURCE_DIR}/src/core/system_parameters + ${GFlags_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${GPSTK_INCLUDE_DIR}/gpstk + ${GPSTK_INCLUDE_DIR} + ) + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated") + + add_executable(rinex2assist ${CMAKE_CURRENT_SOURCE_DIR}/main.cc) + + target_link_libraries(rinex2assist + ${Boost_LIBRARIES} + ${GPSTK_LIBRARY} + ${GFlags_LIBS} + gnss_sp_libs + gnss_rx + ) + + if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) + add_dependencies(rinex2assist gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}) + endif() + + add_custom_command(TARGET rinex2assist POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $ + ${CMAKE_SOURCE_DIR}/install/$ + ) + + install(TARGETS rinex2assist + RUNTIME DESTINATION bin + COMPONENT "rinex2assist" + ) +else() + message(STATUS "Boost Iostreams library not found.") + message(STATUS "rinex2assist will not be built.") +endif() diff --git a/src/utils/rinex2assist/README.md b/src/utils/rinex2assist/README.md new file mode 100644 index 000000000..9d378d797 --- /dev/null +++ b/src/utils/rinex2assist/README.md @@ -0,0 +1,81 @@ +Rinex2assist +------------ + +This program reads data from RINEX navigation files and generates XML files that can be read by GNSS-SDR as Assisted GNSS data. + +### Building + +This program is built along with GNSS-SDR if the options `ENABLE_UNIT_TESTING_EXTRA` or `ENABLE_SYSTEM_TESTING_EXTRA` are set to `ON` when calling CMake: + +``` +$ cmake -DENABLE_SYSTEM_TESTING_EXTRA=ON .. +$ make +$ sudo make intall +``` + +The last step is optional. Without it, you will get the executable at `../install/rinex2assist`. + +The building requires two extra dependencies: the Boost Iostreams library and the program `uncompress`: + + * The Boost Iostreams library can be installed through a package: + - In Debian / Ubuntu: `sudo apt-get install libboost-iostreams-dev` + - In Fedora / CentOS: `sudo yum install boost-iostreams` + - In OpenSUSE: `sudo zypper install libboost_iostreams-devel` + - In Arch Linux: included in `boost-libs` package. + - In MacOS: included in Macports / Homebrew `boost` package. + * The program `uncompress` is available by default in most UNIX and GNU/Linux systems. + - In Fedora / CentOS: `sudo yum install ncompress` + - In OpenSUSE: `sudo zypper install ncompress` + +### Usage + +The usage is as follows: + +``` +$ rinex2assist /path/to/RINEX_nav_file +``` + +The argument is mandatory (the name of the RINEX navigation file). The name `gps_ephemeris.xml` is given to the output if GPS NAV data is fould. If the RINEX file contains Galileo data, the corresponding `gal_ephemeris.xml` file will be generated. The program is also able to extract parameters of the UTC and the Ionospheric models from the RINEX header, if available. They will be called `gps_utc_model.xml`, `gps_iono.xml`, `gal_utc_model.xml` and `gal_iono.xml`. + +There are some servers available for downloading recent RINEX navigation files. For instance: + * NASA: [ftp://cddis.gsfc.nasa.gov/pub/gnss/data/hourly/](ftp://gssc.esa.int/gnss/data/hourly/) + * ESA: [ftp://gssc.esa.int/gnss/data/hourly/](ftp://gssc.esa.int/gnss/data/hourly/) + * UNAVCO: [ftp://data-out.unavco.org/pub/hourly/rinex/](ftp://data-out.unavco.org/pub/hourly/rinex/) + +Just make sure to pick up a recent file from a [station near you](http://www.igs.org/network). + +The program accepts either versions 2.xx or 3.xx for the RINEX navigation data file, as well as compressed files (ending in `.gz` or `.Z`). + +Examples: + +``` +$ rinex2assist EBRE00ESP_R_20183290400_01H_GN.rnx.gz +Generated file: gps_ephemeris.xml +Generated file: gps_utc_model.xml +Generated file: gps_iono.xml +``` + +and + +``` +$ rinex2assist EBRE00ESP_R_20183290000_01H_EN.rnx.gz +Generated file: gal_ephemeris.xml +Generated file: gal_utc_model.xml +Generated file: gal_iono.xml +``` + + +An example of GNSS-SDR configuration using ephemeris, UTC and ionospheric model parameters for GPS L1 and Galileo signals is shown below: + +``` +GNSS-SDR.AGNSS_XML_enabled=true +GNSS-SDR.AGNSS_ref_location=41.39,2.31 +GNSS-SDR.AGNSS_gps_ephemeris_xml=gps_ephemeris.xml +GNSS-SDR.AGNSS_gps_iono_xml=gps_iono.xml +GNSS-SDR.AGNSS_gps_utc_model_xml=gps_utc_model.xml +GNSS-SDR.AGNSS_gal_ephemeris_xml=gal_ephemeris.xml +GNSS-SDR.AGNSS_gal_iono_xml=gal_iono.xml +GNSS-SDR.AGNSS_gal_utc_model_xml=gal_utc_model.xml +``` + +More info about the usage of AGNSS data [here](https://gnss-sdr.org/docs/sp-blocks/global-parameters/#assisted-gnss-with-xml-files). diff --git a/src/utils/rinex2assist/main.cc b/src/utils/rinex2assist/main.cc new file mode 100644 index 000000000..31fcd3ebb --- /dev/null +++ b/src/utils/rinex2assist/main.cc @@ -0,0 +1,434 @@ +/*! + * \file main.cc + * \brief converts navigation RINEX files into XML files for Assisted GNSS. + * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.cat + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "gps_ephemeris.h" +#include "galileo_ephemeris.h" +#include "gps_utc_model.h" +#include "gps_iono.h" +#include "galileo_utc_model.h" +#include "galileo_iono.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int main(int argc, char** argv) +{ + const std::string intro_help( + std::string("\n rinex2assist converts navigation RINEX files into XML files for Assisted GNSS\n") + + "Copyright (C) 2018 (see AUTHORS file for a list of contributors)\n" + + "This program comes with ABSOLUTELY NO WARRANTY;\n" + + "See COPYING file to see a copy of the General Public License.\n \n" + + "Usage: \n" + + " rinex2assist "); + + google::SetUsageMessage(intro_help); + google::SetVersionString("1.0"); + google::ParseCommandLineFlags(&argc, &argv, true); + + if ((argc != 2)) + { + std::cerr << "Usage:" << std::endl; + std::cerr << " " << argv[0] + << " " + << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + std::string xml_filename; + + // Uncompress if RINEX file is gzipped + std::string rinex_filename(argv[1]); + std::string input_filename = rinex_filename; + std::size_t found = rinex_filename.find_last_of("."); + if (found != std::string::npos) + { + if ((rinex_filename.substr(found + 1, found + 3).compare("gz") == 0)) + { + std::ifstream file(rinex_filename, std::ios_base::in | std::ios_base::binary); + if (file.fail()) + { + std::cerr << "Could not open file " << rinex_filename << std::endl; + return 1; + } + boost::iostreams::filtering_streambuf in; + try + { + in.push(boost::iostreams::gzip_decompressor()); + } + catch (const boost::exception& e) + { + std::cerr << "Could not decompress file " << rinex_filename << std::endl; + return 1; + } + in.push(file); + std::string rinex_filename_unzipped = rinex_filename.substr(0, found); + std::ofstream output_file(rinex_filename_unzipped.c_str(), std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); + if (file.fail()) + { + std::cerr << "Could not create file " << rinex_filename_unzipped << std::endl; + return 1; + } + boost::iostreams::copy(in, output_file); + input_filename = rinex_filename_unzipped; + } + if ((rinex_filename.substr(found + 1, found + 2).compare("Z") == 0)) + { + std::ifstream file(rinex_filename, std::ios_base::in | std::ios_base::binary); + if (file.fail()) + { + std::cerr << "Could not open file" << rinex_filename << std::endl; + return 1; + } + file.close(); + std::string uncompress_executable(UNCOMPRESS_EXECUTABLE); + if (!uncompress_executable.empty()) + { + // option k is not always available, so we save a copy of the original file + std::string argum = std::string("/bin/cp " + rinex_filename + " " + rinex_filename + ".aux"); + int s1 = std::system(argum.c_str()); + std::string argum2 = std::string(uncompress_executable + " -f " + rinex_filename); + int s2 = std::system(argum2.c_str()); + std::string argum3 = std::string("/bin/mv " + rinex_filename + +".aux" + " " + rinex_filename); + int s3 = std::system(argum3.c_str()); + input_filename = rinex_filename.substr(0, found); + if ((s1 != 0) or (s2 != 0) or (s3 != 0)) + { + std::cerr << "Failure uncompressing file." << std::endl; + return 1; + } + } + else + { + std::cerr << "uncompress program not found." << std::endl; + return 1; + } + } + } + + std::map eph_map; + std::map eph_gal_map; + + Gps_Utc_Model gps_utc_model; + Gps_Iono gps_iono; + Galileo_Utc_Model gal_utc_model; + Galileo_Iono gal_iono; + + int i = 0; + int j = 0; + try + { + // Read nav file + gpstk::Rinex3NavStream rnffs(input_filename.c_str()); // Open navigation data file + gpstk::Rinex3NavData rne; + gpstk::Rinex3NavHeader hdr; + + // Read header + rnffs >> hdr; + + // Check that it really is a RINEX navigation file + if (hdr.fileType.substr(0, 1).compare("N") != 0) + { + std::cerr << "This is not a valid RINEX navigation file, or file not found." << std::endl; + std::cerr << "No XML file will be created." << std::endl; + return 1; + } + + // Collect UTC parameters from RINEX header + if (hdr.fileSys.compare("G: (GPS)") == 0 || hdr.fileSys.compare("MIXED") == 0) + { + gps_utc_model.valid = (hdr.valid > 2147483648) ? true : false; + gps_utc_model.d_A1 = hdr.mapTimeCorr["GPUT"].A0; + gps_utc_model.d_A0 = hdr.mapTimeCorr["GPUT"].A1; + gps_utc_model.d_t_OT = hdr.mapTimeCorr["GPUT"].refSOW; + gps_utc_model.i_WN_T = hdr.mapTimeCorr["GPUT"].refWeek; + gps_utc_model.d_DeltaT_LS = hdr.leapSeconds; + gps_utc_model.i_WN_LSF = hdr.leapWeek; + gps_utc_model.i_DN = hdr.leapDay; + gps_utc_model.d_DeltaT_LSF = hdr.leapDelta; + + // Collect iono parameters from RINEX header + gps_iono.valid = (hdr.mapIonoCorr["GPSA"].param[0] == 0) ? false : true; + gps_iono.d_alpha0 = hdr.mapIonoCorr["GPSA"].param[0]; + gps_iono.d_alpha1 = hdr.mapIonoCorr["GPSA"].param[1]; + gps_iono.d_alpha2 = hdr.mapIonoCorr["GPSA"].param[2]; + gps_iono.d_alpha3 = hdr.mapIonoCorr["GPSA"].param[3]; + gps_iono.d_beta0 = hdr.mapIonoCorr["GPSB"].param[0]; + gps_iono.d_beta1 = hdr.mapIonoCorr["GPSB"].param[1]; + gps_iono.d_beta2 = hdr.mapIonoCorr["GPSB"].param[2]; + gps_iono.d_beta3 = hdr.mapIonoCorr["GPSB"].param[3]; + } + if (hdr.fileSys.compare("E: (GAL)") == 0 || hdr.fileSys.compare("MIXED") == 0) + { + gal_utc_model.A0_6 = hdr.mapTimeCorr["GAUT"].A0; + gal_utc_model.A1_6 = hdr.mapTimeCorr["GAUT"].A1; + gal_utc_model.Delta_tLS_6 = hdr.leapSeconds; + gal_utc_model.t0t_6 = hdr.mapTimeCorr["GAUT"].refSOW; + gal_utc_model.WNot_6 = hdr.mapTimeCorr["GAUT"].refWeek; + gal_utc_model.WN_LSF_6 = hdr.leapWeek; + gal_utc_model.DN_6 = hdr.leapDay; + gal_utc_model.Delta_tLSF_6 = hdr.leapDelta; + gal_utc_model.flag_utc_model = (hdr.mapTimeCorr["GAUT"].A0 == 0.0); + gal_iono.ai0_5 = hdr.mapIonoCorr["GAL"].param[0]; + gal_iono.ai1_5 = hdr.mapIonoCorr["GAL"].param[1]; + gal_iono.ai2_5 = hdr.mapIonoCorr["GAL"].param[2]; + gal_iono.Region1_flag_5 = false; + gal_iono.Region2_flag_5 = false; + gal_iono.Region3_flag_5 = false; + gal_iono.Region4_flag_5 = false; + gal_iono.Region5_flag_5 = false; + gal_iono.TOW_5 = 0.0; + gal_iono.WN_5 = 0.0; + } + + // Read navigation data + while (rnffs >> rne) + { + if (rne.satSys.compare("G") == 0 or rne.satSys.empty()) + { + // Fill GPS ephemeris object + Gps_Ephemeris eph; + eph.i_satellite_PRN = rne.PRNID; + eph.d_TOW = rne.xmitTime; + eph.d_IODE_SF2 = rne.IODE; + eph.d_IODE_SF3 = rne.IODE; + eph.d_Crs = rne.Crs; + eph.d_Delta_n = rne.dn; + eph.d_M_0 = rne.M0; + eph.d_Cuc = rne.Cuc; + eph.d_e_eccentricity = rne.ecc; + eph.d_Cus = rne.Cus; + eph.d_sqrt_A = rne.Ahalf; + eph.d_Toe = rne.Toe; + eph.d_Toc = rne.Toc; + eph.d_Cic = rne.Cic; + eph.d_OMEGA0 = rne.OMEGA0; + eph.d_Cis = rne.Cis; + eph.d_i_0 = rne.i0; + eph.d_Crc = rne.Crc; + eph.d_OMEGA = rne.w; + eph.d_OMEGA_DOT = rne.OMEGAdot; + eph.d_IDOT = rne.idot; + eph.i_code_on_L2 = rne.codeflgs; // + eph.i_GPS_week = rne.weeknum; + eph.b_L2_P_data_flag = rne.L2Pdata; + eph.i_SV_accuracy = rne.accuracy; + eph.i_SV_health = rne.health; + eph.d_TGD = rne.Tgd; + eph.d_IODC = rne.IODC; + eph.i_AODO = 0; // + eph.b_fit_interval_flag = (rne.fitint > 4) ? 1 : 0; + eph.d_spare1 = 0.0; + eph.d_spare2 = 0.0; + eph.d_A_f0 = rne.af0; + eph.d_A_f1 = rne.af1; + eph.d_A_f2 = rne.af2; + eph.b_integrity_status_flag = 0; // + eph.b_alert_flag = 0; // + eph.b_antispoofing_flag = 0; // + eph_map[i] = eph; + i++; + } + if (rne.satSys.compare("E") == 0) + { + // Fill Galileo ephemeris object + Galileo_Ephemeris eph; + eph.i_satellite_PRN = rne.PRNID; + eph.M0_1 = rne.M0; + eph.e_1 = rne.ecc; + eph.A_1 = rne.Ahalf; + eph.OMEGA_0_2 = rne.OMEGA0; + eph.i_0_2 = rne.i0; + eph.omega_2 = rne.w; + eph.OMEGA_dot_3 = rne.OMEGAdot; + eph.delta_n_3 = rne.dn; + eph.iDot_2 = rne.idot; + eph.C_uc_3 = rne.Cuc; + eph.C_us_3 = rne.Cus; + eph.C_rc_3 = rne.Crc; + eph.C_rs_3 = rne.Crs; + eph.C_ic_4 = rne.Cic; + eph.C_is_4 = rne.Cis; + eph.t0e_1 = rne.Toe; + eph.t0c_4 = rne.Toc; + eph.af0_4 = rne.af0; + eph.af1_4 = rne.af1; + eph.af2_4 = rne.af2; + eph.WN_5 = rne.weeknum; + eph_gal_map[j] = eph; + j++; + } + } + } + catch (std::exception& e) + { + std::cerr << "Error reading the RINEX file: " << e.what() << std::endl; + std::cerr << "No XML file will be created." << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + + if (i == 0 and j == 0) + { + std::cerr << "No navigation data found in the RINEX file. No XML file will be created." << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + + // Write XML ephemeris + if (i != 0) + { + std::ofstream ofs; + if (xml_filename.empty()) + { + xml_filename = "gps_ephemeris.xml"; + } + try + { + ofs.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs); + xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", eph_map); + } + catch (std::exception& e) + { + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + std::cout << "Generated file: " << xml_filename << std::endl; + } + if (j != 0) + { + std::ofstream ofs2; + xml_filename = "gal_ephemeris.xml"; + try + { + ofs2.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs2); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_ephemeris_map", eph_gal_map); + } + catch (std::exception& e) + { + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + std::cout << "Generated file: " << xml_filename << std::endl; + } + + // Write XML UTC + if (gps_utc_model.valid) + { + std::ofstream ofs3; + xml_filename = "gps_utc_model.xml"; + try + { + ofs3.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs3); + xml << boost::serialization::make_nvp("GNSS-SDR_utc_model", gps_utc_model); + } + catch (std::exception& e) + { + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + std::cout << "Generated file: " << xml_filename << std::endl; + } + + // Write XML iono + if (gps_iono.valid) + { + std::ofstream ofs4; + xml_filename = "gps_iono.xml"; + try + { + ofs4.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs4); + xml << boost::serialization::make_nvp("GNSS-SDR_iono_model", gps_iono); + } + catch (std::exception& e) + { + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + std::cout << "Generated file: " << xml_filename << std::endl; + } + + if (gal_utc_model.A0_6 != 0) + { + std::ofstream ofs5; + xml_filename = "gal_utc_model.xml"; + try + { + ofs5.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs5); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_utc_model", gal_utc_model); + } + catch (std::exception& e) + { + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + std::cout << "Generated file: " << xml_filename << std::endl; + } + if (gal_iono.ai0_5 != 0) + { + std::ofstream ofs7; + xml_filename = "gal_iono.xml"; + try + { + ofs7.open(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out); + boost::archive::xml_oarchive xml(ofs7); + xml << boost::serialization::make_nvp("GNSS-SDR_gal_iono_model", gal_iono); + } + catch (std::exception& e) + { + std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << std::endl; + google::ShutDownCommandLineFlags(); + return 1; + } + std::cout << "Generated file: " << xml_filename << std::endl; + } + google::ShutDownCommandLineFlags(); + return 0; +} diff --git a/src/utils/scripts/gnss-sdr-harness.sh b/src/utils/scripts/gnss-sdr-harness.sh new file mode 100755 index 000000000..b025bb07b --- /dev/null +++ b/src/utils/scripts/gnss-sdr-harness.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# GNSS-SDR shell script that enables the remote GNSS-SDR restart telecommand +# usage: ./gnss-sdr-harness.sh ./gnss-sdr -c config_file.conf +echo $@ +$@ +while [ $? -eq 42 ] +do + echo "restarting GNSS-SDR..." + $@ +done