mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-26 00:46:59 +00:00
Merge remote-tracking branch 'origin/next' into gps_galileo_hybrid
This commit is contained in:
commit
32a66b8a41
2
AUTHORS
2
AUTHORS
@ -42,6 +42,8 @@ David Pubill david.pubill@cttc.cat Developer
|
||||
Mara Branzanti mara.branzanti@gmail.com Developer
|
||||
Marc Molina marc.molina.pena@gmail.com Developer
|
||||
Daniel Fehr daniel.co@bluewin.ch Developer
|
||||
Marc Sales marcsales92@gmail.com Developer
|
||||
Damian Miralles dmiralles2009@gmail.com Developer
|
||||
Leonardo Tonetto tonetto.dev@gmail.com Contributor
|
||||
Ignacio Paniego ignacio.paniego@gmail.com Web design
|
||||
Eva Puchol eva.puchol@gmail.com Web developer
|
||||
|
412
CMakeLists.txt
412
CMakeLists.txt
@ -5,7 +5,7 @@
|
||||
# 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.
|
||||
# (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
|
||||
@ -16,20 +16,34 @@
|
||||
# along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
message(FATAL_ERROR "Prevented in-tree build. This is bad practice. Try 'cd build && cmake ../' ")
|
||||
endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
|
||||
########################################################################
|
||||
# Project setup
|
||||
########################################################################
|
||||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
message(FATAL_ERROR "Prevented in-tree build. This is bad practice. Try 'cd build && cmake ../' ")
|
||||
endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(gnss-sdr CXX C)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||
file(RELATIVE_PATH RELATIVE_CMAKE_CALL ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# Set the version information here
|
||||
|
||||
########################################################################
|
||||
# Determine optional blocks/libraries to be built (default: not built)
|
||||
# Enable them here or at the command line by doing 'cmake -DENABLE_XXX=ON ../'
|
||||
########################################################################
|
||||
|
||||
option(ENABLE_GN3S "Enable the use of the GN3S dongle as signal source (experimental)" OFF)
|
||||
option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal source (experimental)" OFF)
|
||||
option(ENABLE_RTLSDR "Enable the use of RTL dongles as signal source (experimental)" OFF)
|
||||
option(ENABLE_OPENCL "Enable building of processing blocks implemented with OpenCL (experimental)" OFF)
|
||||
option(ENABLE_GPERFTOOLS "Enable linking to Gperftools libraries (tcmalloc and profiler)" OFF)
|
||||
|
||||
|
||||
###############################
|
||||
# GNSS-SDR version information
|
||||
###############################
|
||||
# Get the current working branch
|
||||
execute_process(
|
||||
COMMAND git rev-parse --abbrev-ref HEAD
|
||||
@ -48,10 +62,10 @@ execute_process(
|
||||
|
||||
set(VERSION_INFO_MAJOR_VERSION 0)
|
||||
set(VERSION_INFO_API_COMPAT 0)
|
||||
set(VERSION_INFO_MINOR_VERSION 2.git-${GIT_BRANCH}-${GIT_COMMIT_HASH})
|
||||
set(VERSION_INFO_MINOR_VERSION 3.git-${GIT_BRANCH}-${GIT_COMMIT_HASH})
|
||||
set(VERSION ${VERSION_INFO_MAJOR_VERSION}.${VERSION_INFO_API_COMPAT}.${VERSION_INFO_MINOR_VERSION})
|
||||
|
||||
file(RELATIVE_PATH RELATIVE_CMAKE_CALL ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
|
||||
########################################################################
|
||||
# Environment setup
|
||||
@ -145,7 +159,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(LINUX_DISTRIBUTION "Generic")
|
||||
set(LINUX_VER "Unknown")
|
||||
endif(NOT LINUX_DISTRIBUTION)
|
||||
message(STATUS "Configuring GNSS-SDR to be built on ${LINUX_DISTRIBUTION} GNU/Linux Release ${LINUX_VER} ${ARCH_}")
|
||||
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")
|
||||
|
||||
# Detect Mac OS X Version
|
||||
@ -159,23 +173,29 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
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 to be built on Mac OS X 10.9 Mavericks")
|
||||
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 to be built on Mac OS X 10.8 Mountain Lion")
|
||||
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 to be built on Mac OS X 10.7 Lion")
|
||||
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 to be built on Mac OS X 10.6 Snow Leopard")
|
||||
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")
|
||||
|
||||
|
||||
#select the release build type by default to get optimization flags
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
message(STATUS "Build type not specified: defaulting to Release.")
|
||||
if(ENABLE_GPERFTOOLS)
|
||||
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
|
||||
message(STATUS "Build type not specified: defaulting to RelWithDebInfo.")
|
||||
else(ENABLE_GPERFTOOLS)
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
message(STATUS "Build type not specified: defaulting to Release.")
|
||||
endif(ENABLE_GPERFTOOLS)
|
||||
endif(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
|
||||
|
||||
@ -198,6 +218,7 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
|
||||
endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
|
||||
|
||||
################################################################################
|
||||
# Googletest - http://code.google.com/p/googletest/
|
||||
################################################################################
|
||||
@ -219,7 +240,6 @@ endif(GTEST_DIR)
|
||||
################################################################################
|
||||
# Boost - http://www.boost.org
|
||||
################################################################################
|
||||
|
||||
if(UNIX AND EXISTS "/usr/lib64")
|
||||
list(APPEND BOOST_LIBRARYDIR "/usr/lib64") # Fedora 64-bit fix
|
||||
endif(UNIX AND EXISTS "/usr/lib64")
|
||||
@ -247,9 +267,7 @@ endif(NOT Boost_FOUND)
|
||||
################################################################################
|
||||
# GNU Radio - http://gnuradio.org/redmine/projects/gnuradio/wiki
|
||||
################################################################################
|
||||
|
||||
find_package(Gnuradio)
|
||||
|
||||
if(NOT GNURADIO_RUNTIME_FOUND)
|
||||
message(STATUS "CMake cannot find GNU Radio >= 3.7")
|
||||
if(OS_IS_LINUX)
|
||||
@ -372,7 +390,6 @@ endif(NOT GFlags_FOUND OR LOCAL_GLOG)
|
||||
################################################################################
|
||||
# glog - http://code.google.com/p/google-glog/
|
||||
################################################################################
|
||||
|
||||
find_package(GLOG)
|
||||
set(glog_RELEASE 0.3.3)
|
||||
if (NOT GLOG_FOUND OR LOCAL_GFLAGS)
|
||||
@ -474,97 +491,14 @@ endif(NOT GLOG_FOUND OR LOCAL_GFLAGS)
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# GPerftools - http://code.google.com/p/gperftools/
|
||||
################################################################################
|
||||
|
||||
set(GCC_GPERFTOOLS_FLAGS "")
|
||||
find_package(Gperftools)
|
||||
if ( NOT GPERFTOOLS_FOUND )
|
||||
message(STATUS "The optional library GPerftools has not been found.")
|
||||
else( NOT GPERFTOOLS_FOUND )
|
||||
message (STATUS "GPerftools library found." )
|
||||
link_libraries(${GPERFTOOLS_PROFILER} ${GPERFTOOLS_TCMALLOC})
|
||||
endif( NOT GPERFTOOLS_FOUND )
|
||||
list(APPEND CMAKE_CXX_FLAGS ${GCC_GPERFTOOLS_FLAGS})
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Doxygen - http://www.stack.nl/~dimitri/doxygen/index.html
|
||||
################################################################################
|
||||
|
||||
find_package(Doxygen)
|
||||
if(DOXYGEN_FOUND)
|
||||
message(STATUS "Doxygen found.")
|
||||
message(STATUS "You can build the documentation with 'make doc'." )
|
||||
message(STATUS "When done, point your browser to ${CMAKE_SOURCE_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_SOURCE_DIR}/docs/doxygen/Doxyfile
|
||||
@ONLY
|
||||
)
|
||||
add_custom_target(doc
|
||||
${DOXYGEN_EXECUTABLE} ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen." VERBATIM
|
||||
)
|
||||
if(LATEX_COMPILER)
|
||||
message(STATUS "'make pdfmanual' will generate a manual at ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf")
|
||||
add_custom_target(pdfmanual
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy refman.pdf ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM} clean
|
||||
DEPENDS doc
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/latex
|
||||
COMMENT "Generating PDF manual with Doxygen." VERBATIM
|
||||
)
|
||||
endif(LATEX_COMPILER)
|
||||
message(STATUS "'make doc-clean' will clean the documentation.")
|
||||
add_custom_target(doc-clean
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/html
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/latex
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_SOURCE_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(" or simply by doing 'sudo yum install doxygen-latex'.")
|
||||
else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
message(" 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)
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Armadillo - http://arma.sourceforge.net/
|
||||
################################################################################
|
||||
|
||||
if(OS_IS_LINUX)
|
||||
#############################################
|
||||
#############################################################################
|
||||
# Check that LAPACK is found in the system
|
||||
#############################################
|
||||
# LAPACK is required for matrix decompositions (eg. SVD) and matrix inverse.
|
||||
#############################################################################
|
||||
find_library(LAPACK lapack)
|
||||
if(NOT LAPACK)
|
||||
message(" The LAPACK library has not been found.")
|
||||
@ -578,9 +512,11 @@ if(OS_IS_LINUX)
|
||||
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
message(FATAL_ERROR "LAPACK is required to build gnss-sdr")
|
||||
endif(NOT LAPACK)
|
||||
#############################################
|
||||
#############################################################################
|
||||
# Check that BLAS is found in the system
|
||||
#############################################
|
||||
# BLAS is used for matrix multiplication.
|
||||
# Without BLAS, matrix multiplication will still work, but might be slower.
|
||||
#############################################################################
|
||||
find_library(BLAS blas)
|
||||
if(NOT BLAS)
|
||||
message(" The BLAS library has not been found.")
|
||||
@ -657,31 +593,22 @@ if(NOT ARMADILLO_FOUND)
|
||||
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
message(FATAL_ERROR "The patch command is required to download and build armadillo")
|
||||
endif(NOT PATCH_EXECUTABLE)
|
||||
set(armadillo_RELEASE 4.300.9)
|
||||
set(armadillo_MD5 "d51d1beb2a335f3002702d112c4814f3")
|
||||
set(armadillo_RELEASE 4.400.0)
|
||||
set(armadillo_MD5 "616744dbc96af1c5d6d32c6c69f6fe94")
|
||||
if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}/armadillo-${armadillo_RELEASE}.tar.gz)
|
||||
set(ARMADILLO_PATCH_FILE ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_no.patch)
|
||||
file(WRITE ${ARMADILLO_PATCH_FILE} "")
|
||||
set(ARMADILLO_PATCH_FILE2 ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_no2.patch)
|
||||
file(WRITE ${ARMADILLO_PATCH_FILE2} "")
|
||||
else(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}/armadillo-${armadillo_RELEASE}.tar.gz)
|
||||
set(ARMADILLO_PATCH_FILE ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_staticlib.patch)
|
||||
set(ARMADILLO_PATCH_FILE2 ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_enable_lapack.patch)
|
||||
set(ARMADILLO_PATCH_FILE ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_enable_lapack.patch)
|
||||
file(WRITE ${ARMADILLO_PATCH_FILE}
|
||||
"30c30
|
||||
< set(ARMA_USE_LAPACK false)
|
||||
---
|
||||
> set(ARMA_USE_LAPACK true)
|
||||
312c312
|
||||
< add_library( armadillo SHARED \${PROJECT_SOURCE_DIR}/src/wrapper.cpp )
|
||||
---
|
||||
> add_library( armadillo STATIC \${PROJECT_SOURCE_DIR}/src/wrapper.cpp )
|
||||
")
|
||||
file(WRITE ${ARMADILLO_PATCH_FILE2}
|
||||
"12c12
|
||||
< // #define ARMA_USE_LAPACK
|
||||
---
|
||||
> #define ARMA_USE_LAPACK
|
||||
> #define ARMA_USE_LAPACK
|
||||
19c19
|
||||
< // #define ARMA_USE_BLAS
|
||||
---
|
||||
> #define ARMA_USE_BLAS
|
||||
")
|
||||
endif(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}/armadillo-${armadillo_RELEASE}.tar.gz)
|
||||
ExternalProject_Add(
|
||||
@ -689,9 +616,9 @@ if(NOT ARMADILLO_FOUND)
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}
|
||||
URL http://sourceforge.net/projects/arma/files/armadillo-${armadillo_RELEASE}.tar.gz
|
||||
DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}
|
||||
URL_MD5 ${armadillo_MD5}
|
||||
PATCH_COMMAND patch -N <BINARY_DIR>/CMakeLists.txt ${ARMADILLO_PATCH_FILE} && patch -N <BINARY_DIR>/include/armadillo_bits/config.hpp ${ARMADILLO_PATCH_FILE2}
|
||||
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
URL_MD5 ${armadillo_MD5}
|
||||
PATCH_COMMAND patch -N <BINARY_DIR>/include/armadillo_bits/config.hpp ${ARMADILLO_PATCH_FILE}
|
||||
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DBUILD_SHARED_LIBS=OFF
|
||||
BUILD_IN_SOURCE 1
|
||||
BUILD_COMMAND make
|
||||
UPDATE_COMMAND ""
|
||||
@ -702,7 +629,14 @@ if(NOT ARMADILLO_FOUND)
|
||||
ExternalProject_Get_Property(armadillo-${armadillo_RELEASE} binary_dir)
|
||||
set(ARMADILLO_INCLUDE_DIRS ${binary_dir}/include )
|
||||
find_library(LAPACK NAMES lapack HINTS /usr/lib /usr/local/lib /usr/lib64)
|
||||
set(ARMADILLO_LIBRARIES ${LAPACK} ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo.a)
|
||||
if(OS_IS_MACOSX)
|
||||
find_library(BLAS blas)
|
||||
endif(OS_IS_MACOSX)
|
||||
find_package(OpenBLAS)
|
||||
if(OPENBLAS_FOUND)
|
||||
set(BLAS ${OPENBLAS})
|
||||
endif(OPENBLAS_FOUND)
|
||||
set(ARMADILLO_LIBRARIES ${BLAS} ${LAPACK} ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo.a)
|
||||
set(LOCAL_ARMADILLO true CACHE STRING "Armadillo downloaded and built automatically" FORCE)
|
||||
# Save a copy at the thirdparty folder
|
||||
file(COPY ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}
|
||||
@ -716,27 +650,6 @@ endif(NOT ARMADILLO_FOUND)
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# OpenCL
|
||||
###############################################################################
|
||||
find_package(OpenCL)
|
||||
if($ENV{DISABLE_OPENCL})
|
||||
set(DISABLE_OPENCL TRUE)
|
||||
endif($ENV{DISABLE_OPENCL})
|
||||
if(DISABLE_OPENCL)
|
||||
set(OPENCL_FOUND FALSE)
|
||||
else(DISABLE_OPENCL)
|
||||
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 -DDISABLE_OPENCL=1 ../' ")
|
||||
endif(OPENCL_FOUND)
|
||||
endif(DISABLE_OPENCL)
|
||||
if(NOT OPENCL_FOUND)
|
||||
message(STATUS "Processing blocks using OpenCL will not be built.")
|
||||
endif(NOT OPENCL_FOUND)
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# OpenSSL - http://www.openssl.org
|
||||
################################################################################
|
||||
@ -758,41 +671,169 @@ if(NOT OPENSSL_FOUND)
|
||||
endif(NOT OPENSSL_FOUND)
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Doxygen - http://www.stack.nl/~dimitri/doxygen/index.html (OPTIONAL)
|
||||
################################################################################
|
||||
find_package(Doxygen)
|
||||
if(DOXYGEN_FOUND)
|
||||
message(STATUS "Doxygen found.")
|
||||
message(STATUS "You can build the documentation with 'make doc'." )
|
||||
message(STATUS "When done, point your browser to ${CMAKE_SOURCE_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_SOURCE_DIR}/docs/doxygen/Doxyfile
|
||||
@ONLY
|
||||
)
|
||||
add_custom_target(doc
|
||||
${DOXYGEN_EXECUTABLE} ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen." VERBATIM
|
||||
)
|
||||
if(LATEX_COMPILER)
|
||||
message(STATUS "'make pdfmanual' will generate a manual at ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf")
|
||||
add_custom_target(pdfmanual
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy refman.pdf ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM} clean
|
||||
DEPENDS doc
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/latex
|
||||
COMMENT "Generating PDF manual with Doxygen." VERBATIM
|
||||
)
|
||||
endif(LATEX_COMPILER)
|
||||
message(STATUS "'make doc-clean' will clean the documentation.")
|
||||
add_custom_target(doc-clean
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/html
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/latex
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_SOURCE_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(" or simply by doing 'sudo yum install doxygen-latex'.")
|
||||
else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
|
||||
message(" 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)
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# OpenCL (OPTIONAL)
|
||||
###############################################################################
|
||||
if(ENABLE_OPENCL)
|
||||
find_package(OpenCL)
|
||||
if($ENV{DISABLE_OPENCL})
|
||||
set(DISABLE_OPENCL TRUE)
|
||||
endif($ENV{DISABLE_OPENCL})
|
||||
if(DISABLE_OPENCL)
|
||||
set(OPENCL_FOUND FALSE)
|
||||
else(DISABLE_OPENCL)
|
||||
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)
|
||||
if(NOT OPENCL_FOUND)
|
||||
message(STATUS "Processing blocks using OpenCL will not be built.")
|
||||
endif(NOT OPENCL_FOUND)
|
||||
else(ENABLE_OPENCL)
|
||||
set(OPENCL_FOUND FALSE)
|
||||
endif(ENABLE_OPENCL)
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# GPerftools - http://code.google.com/p/gperftools/ (OPTIONAL)
|
||||
################################################################################
|
||||
|
||||
if(ENABLE_GPERFTOOLS)
|
||||
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 http://code.google.com/p/gperftools/")
|
||||
else( NOT GPERFTOOLS_FOUND )
|
||||
message(STATUS "GPerftools libraries found." )
|
||||
message(STATUS "Binaries will be compiled with 'tcmalloc' and 'profiler' libraries.")
|
||||
endif( NOT GPERFTOOLS_FOUND )
|
||||
endif(ENABLE_GPERFTOOLS)
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Setup of optional drivers
|
||||
################################################################################
|
||||
if( $ENV{GN3S_DRIVER} )
|
||||
message(STATUS "GN3S_DRIVER variable found." )
|
||||
# copy firmware to install folder
|
||||
# Build project gr-gn3s
|
||||
else( $ENV{GN3S_DRIVER} )
|
||||
if( GN3S_DRIVER )
|
||||
message(STATUS "GN3S driver will be compiled")
|
||||
else( GNSS_DRIVER )
|
||||
message(STATUS "GN3S_DRIVER is not defined." )
|
||||
message(STATUS "Define it with 'export GN3S_DRIVER=1' to add support for the GN3S dongle." )
|
||||
endif( GN3S_DRIVER )
|
||||
endif($ENV{GN3S_DRIVER} )
|
||||
|
||||
if( $ENV{RAW_ARRAY_DRIVER} )
|
||||
message(STATUS "RAW_ARRAY_DRIVER variable found." )
|
||||
if($ENV{GN3S_DRIVER})
|
||||
message(STATUS "GN3S_DRIVER environment variable found." )
|
||||
set(ENABLE_GN3S ON)
|
||||
endif($ENV{GN3S_DRIVER})
|
||||
if(GN3S_DRIVER)
|
||||
set(ENABLE_GN3S ON)
|
||||
endif(GN3S_DRIVER)
|
||||
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)
|
||||
|
||||
|
||||
if($ENV{RAW_ARRAY_DRIVER})
|
||||
message(STATUS "RAW_ARRAY_DRIVER environment variable found." )
|
||||
set(ENABLE_ARRAY ON)
|
||||
endif($ENV{RAW_ARRAY_DRIVER})
|
||||
if(RAW_ARRAY_DRIVER)
|
||||
set(ENABLE_ARRAY ON)
|
||||
endif(RAW_ARRAY_DRIVER)
|
||||
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 ../'" )
|
||||
# copy firmware to install folder
|
||||
# Build project gr-dbfcttc
|
||||
else( $ENV{RAW_ARRAY_DRIVER} )
|
||||
if( RAW_ARRAY_DRIVER )
|
||||
message(STATUS "RAW_ARRAY_DRIVER driver will be compiled")
|
||||
else( RAW_ARRAY_DRIVER )
|
||||
message(STATUS "RAW_ARRAY_DRIVER is not defined." )
|
||||
message(STATUS "Define it with 'export RAW_ARRAY_DRIVER=1' to add support for the CTTC experimental array front-end." )
|
||||
endif( RAW_ARRAY_DRIVER )
|
||||
endif($ENV{RAW_ARRAY_DRIVER} )
|
||||
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)
|
||||
|
||||
if( $ENV{RTLSDR_DRIVER} )
|
||||
message(STATUS "RTLSDR_DRIVER variable found." )
|
||||
|
||||
if($ENV{RTLSDR_DRIVER})
|
||||
message(STATUS "RTLSDR_DRIVER environment variable found." )
|
||||
set(ENABLE_RTLSDR ON)
|
||||
endif($ENV{RTLSDR_DRIVER})
|
||||
if(RAW_ARRAY_DRIVER)
|
||||
set(ENABLE_RTLSDR ON)
|
||||
endif(RAW_ARRAY_DRIVER)
|
||||
if(ENABLE_RTLSDR)
|
||||
message(STATUS "The driver for RTL-based dongles will be compiled." )
|
||||
message(STATUS "You can disable it with 'cmake -DENABLE_RTLSDR=OFF ../'" )
|
||||
# find libosmosdr (done in src/algorithms/signal_sources/adapters)
|
||||
# find gr-osmosdr (done in src/algorithms/signal_sources/adapters)
|
||||
endif($ENV{RTLSDR_DRIVER} )
|
||||
|
||||
else(ENABLE_RTLSDR)
|
||||
message(STATUS "The (optional) driver for RTL-based dongles is not enabled." )
|
||||
message(STATUS "Enable it with 'cmake -DENABLE_RTLSDR=ON ../' to add support for Realtek's RTL2832U-based USB dongles." )
|
||||
endif(ENABLE_RTLSDR)
|
||||
|
||||
|
||||
########################################################################
|
||||
@ -827,13 +868,18 @@ if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
|
||||
add_definitions(-fvisibility=hidden)
|
||||
endif()
|
||||
|
||||
# Set GPerftools related flags if it is available
|
||||
# See http://gperftools.googlecode.com/svn/trunk/README
|
||||
if(GPERFTOOLS_FOUND)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX 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(GPERFTOOLS_FOUND)
|
||||
if(ENABLE_GPERFTOOLS)
|
||||
# Set GPerftools related flags if it is available
|
||||
# See http://gperftools.googlecode.com/svn/trunk/README
|
||||
if(GPERFTOOLS_FOUND)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX 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)
|
||||
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)
|
||||
|
||||
list(APPEND CMAKE_CXX_FLAGS ${MY_CXX_FLAGS})
|
||||
|
||||
|
214
README.md
214
README.md
@ -11,7 +11,7 @@ If you have questions about GNSS-SDR, please [subscribe to the gnss-sdr-develope
|
||||
# How to build GNSS-SDR
|
||||
|
||||
|
||||
This section describes how to set up the compilation environment in GNU/Linux or Mac OS X, and to build GNSS-SDR. See also [our Building Guide](http://gnss-sdr.org/documentation/building-guide "GNSS-SDR's Building Guide").
|
||||
This section describes how to set up the compilation environment in GNU/Linux or [Mac OS X](#macosx), and to build GNSS-SDR. See also [our Building Guide](http://gnss-sdr.org/documentation/building-guide "GNSS-SDR's Building Guide").
|
||||
|
||||
GNU/Linux
|
||||
----------
|
||||
@ -72,9 +72,9 @@ $ sudo apt-get install libopenblas-dev liblapack-dev gfortran # For Debian/Ubu
|
||||
$ sudo yum install lapack-devel blas-devel gcc-fortran # For Fedora/CentOS/RHEL
|
||||
$ sudo zypper install lapack-devel blas-devel gcc-fortran # For OpenSUSE
|
||||
|
||||
$ wget http://sourceforge.net/projects/arma/files/armadillo-4.300.9.tar.gz
|
||||
$ tar xvfz armadillo-4.300.9.tar.gz
|
||||
$ cd armadillo-4.300.9
|
||||
$ wget http://sourceforge.net/projects/arma/files/armadillo-4.400.0.tar.gz
|
||||
$ tar xvfz armadillo-4.400.0.tar.gz
|
||||
$ cd armadillo-4.400.0
|
||||
$ cmake .
|
||||
$ make
|
||||
$ sudo make install
|
||||
@ -125,10 +125,10 @@ $ make
|
||||
Please **DO NOT install** gtest (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 gtest its own tests; it is only required that you tell the system where the gtest folder that you downloaded resides. Just add to your ```$HOME/.bashrc``` file the following line:
|
||||
|
||||
~~~~~~
|
||||
$ export GTEST_DIR=/home/username/gtest-1.7.0
|
||||
export GTEST_DIR=/home/username/gtest-1.7.0
|
||||
~~~~~~
|
||||
|
||||
changing /home/username/gtest-1.7.0 by the actual directory where you downloaded gtest. Again, it is recommended to add this line to your ```$HOME/.bashrc``` file.
|
||||
changing /home/username/gtest-1.7.0 by the actual directory where you downloaded gtest.
|
||||
|
||||
|
||||
|
||||
@ -168,13 +168,72 @@ Cloning the GNSS-SDR repository as in the line above will create a folder named
|
||||
~~~~~~
|
||||
|
||||
|
||||
|
||||
### Build GNSS-SDR
|
||||
|
||||
Go to GNSS-SDR's build directory:
|
||||
|
||||
~~~~~~
|
||||
$ cd gnss-sdr/build
|
||||
~~~~~~
|
||||
|
||||
Configure and build the application:
|
||||
|
||||
~~~~~~
|
||||
$ cmake ../
|
||||
$ make
|
||||
$ make install
|
||||
~~~~~~
|
||||
|
||||
By default, CMake will build the Release version, meaning that the compiler will generate a fast, optimized executable. This is the recommended build type when using a RF front-end and you need to attain real time. If working with a file (and thus without real-time constraints), you may want to obtain more information about the internals of the receiver, as well as more fine-grained logging. This can be done by building the Debug version, by doing:
|
||||
|
||||
~~~~~~
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../
|
||||
$ make
|
||||
$ make install
|
||||
~~~~~~
|
||||
|
||||
If everything goes well, two new executables will be created at gnss-sdr/install, namely ```gnss-sdr``` and ```run_tests```.
|
||||
|
||||
You can create the documentation by doing:
|
||||
|
||||
~~~~~~
|
||||
$ make doc
|
||||
~~~~~~
|
||||
|
||||
from the gnss-sdr/build folder. This will generate HTML documentation that can be retrieved pointing your browser of preference to gnss-sdr/docs/html/index.html.
|
||||
If a LaTeX installation is detected in your system,
|
||||
|
||||
~~~~~~
|
||||
$ make pdfmanual
|
||||
~~~~~~
|
||||
|
||||
will create a PDF manual at gnss-sdr/docs/GNSS-SDR_manual.pdf. Finally,
|
||||
|
||||
~~~~~~
|
||||
$ make doc-clean
|
||||
~~~~~~
|
||||
|
||||
will remove the content of previously-generated documentation.
|
||||
|
||||
|
||||
If you are using Eclipse as your development environment, CMake can create the project for you. Type:
|
||||
|
||||
~~~~~~
|
||||
$ cmake -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DECLIPSE_CDT4_GENERATE_SOURCE_PROJECT=TRUE -DCMAKE_ECLIPSE_VERSION=3.7 -DCMAKE_ECLIPSE_MAKE_ARGUMENTS=-j8 ../
|
||||
~~~~~~
|
||||
|
||||
and then import the created project file into Eclipse:
|
||||
|
||||
1. Import project using Menu File -> Import.
|
||||
2. Select General -> Existing projects into workspace.
|
||||
3. Browse where your build tree is and select the root build tree directory. Keep "Copy projects into workspace" unchecked.
|
||||
4. You get a fully functional Eclipse project.
|
||||
|
||||
|
||||
###### Build GN3S V2 Custom firmware and driver (OPTIONAL):
|
||||
|
||||
Go to GR-GN3S root directory, compile and install the driver (read the drivers/gr-gn3s/README for more information):
|
||||
|
||||
|
||||
~~~~~~
|
||||
$ cd gnss-sdr/drivers/gr-gn3s
|
||||
$ cd build
|
||||
@ -184,18 +243,17 @@ $ sudo make install
|
||||
$ sudo ldconfig
|
||||
~~~~~~
|
||||
|
||||
|
||||
Set the environment variable ```GN3S_DRIVER=1``` in order to enable the GN3S_Signal_Source in GNSS-SDR:
|
||||
|
||||
Then configure GNSS-SDR to build the GN3S_Signal_Source by:
|
||||
|
||||
~~~~~~
|
||||
$ export GN3S_DRIVER=1
|
||||
$ cmake -DENABLE_GN3S=ON ../
|
||||
$ make && make install
|
||||
~~~~~~
|
||||
|
||||
In order to gain access to USB ports, gnss-sdr should be used as root. In addition, the driver requires access to the GN3S firmware binary file. It should be available in the same path where the application is called.
|
||||
GNSS-SDR comes with a pre-compiled custom GN3S firmware available at gnss-sdr/firmware/GN3S_v2/bin/gn3s_firmware.ihx. Please copy this file to the application path. The GNSS-SDR default path is gnss-sdr/install
|
||||
|
||||
(in order to disable the GN3S_Signal_Source compilation, you should remove the GN3S_DRIVER variable and build again GNSS-SDR).
|
||||
(in order to disable the GN3S_Signal_Source compilation, you can pass -DENABLE_GN3S=OFF to cmake and build GNSS-SDR again).
|
||||
|
||||
|
||||
|
||||
@ -225,109 +283,31 @@ $ sudo ldconfig
|
||||
~~~~~~
|
||||
|
||||
|
||||
Set the environment variable ```RTLSDR_DRIVER=1``` in order to enable the Rtlsdr_Signal_Source in GNSS-SDR:
|
||||
|
||||
Then configure GNSS-SDR to build the Rtlsdr_Signal_Source by:
|
||||
|
||||
~~~~~~
|
||||
$ export RTLSDR_DRIVER=1
|
||||
$ cmake -DENABLE_RTLSDR=ON ../
|
||||
$ make && make install
|
||||
~~~~~~
|
||||
|
||||
(in order to disable the Rtlsdr_Signal_Source compilation, you can pass -DENABLE_RTLSDR=OFF to cmake and build GNSS-SDR again).
|
||||
|
||||
|
||||
|
||||
###### Build OpenCL support (OPTIONAL):
|
||||
|
||||
In order to enable the building of blocks that use OpenCL, type:
|
||||
|
||||
~~~~~~
|
||||
$ cmake -DENABLE_OPENCL=ON ../
|
||||
$ make && make install
|
||||
~~~~~~
|
||||
|
||||
|
||||
In order to compile the RTLSDR adapter you should also provide the path to the gr-osmosdr source code using:
|
||||
|
||||
|
||||
~~~~~~
|
||||
$ export OSMOSDR_ROOT=/path/to/gr-osmosdr
|
||||
~~~~~~
|
||||
|
||||
|
||||
The default will be ```OSMOSDR_ROOT=/usr/local```
|
||||
|
||||
(in order to disable the Rtlsdr_Signal_Source compilation, you should remove the RTLSDR_DRIVER variable and build again GNSS-SDR).
|
||||
|
||||
|
||||
|
||||
### Build GNSS-SDR
|
||||
|
||||
Go to GNSS-SDR's build directory:
|
||||
|
||||
~~~~~~
|
||||
$ cd gnss-sdr/build
|
||||
~~~~~~
|
||||
|
||||
Configure and build the application:
|
||||
|
||||
~~~~~~
|
||||
$ cmake ../
|
||||
$ make
|
||||
~~~~~~
|
||||
|
||||
By default, CMake is configured to build the release version. If you want to build the debug version, please use:
|
||||
|
||||
~~~~~~
|
||||
$ cmake ../ -DCMAKE_BUILD_TYPE=Debug
|
||||
~~~~~~
|
||||
|
||||
Move the executables to the install folder:
|
||||
|
||||
~~~~~~
|
||||
$ make install
|
||||
~~~~~~
|
||||
|
||||
If everything goes well, two new executables will be created at gnss-sdr/install, namely ```gnss-sdr``` and ```run_tests```.
|
||||
|
||||
You can create the documentation by doing:
|
||||
|
||||
~~~~~~
|
||||
$ make doc
|
||||
~~~~~~
|
||||
|
||||
from the gnss-sdr/build folder. This will generate HTML documentation that can be retrieved pointing your browser of preference to gnss-sdr/docs/html/index.html.
|
||||
If a LaTeX installation is detected in your system,
|
||||
|
||||
~~~~~~
|
||||
$ make pdfmanual
|
||||
~~~~~~
|
||||
|
||||
will create a PDF manual at gnss-sdr/docs/GNSS-SDR_manual.pdf. Please note that the PDF generation requires some fonts to be installed on the host system. In Ubuntu 12.10, those fonts do not come by default. You can install them by doing:
|
||||
|
||||
~~~~~~
|
||||
$ sudo apt-get install texlive-fonts-recommended
|
||||
~~~~~~
|
||||
|
||||
and then run ```cmake ../``` and make pdfmanual again. Finally,
|
||||
|
||||
~~~~~~
|
||||
$ make doc-clean
|
||||
~~~~~~
|
||||
|
||||
will remove the content of previously-generated documentation.
|
||||
|
||||
By default, CMake will build the Release version, meaning that the compiler will generate a faster, optimized executable. This is the recommended build type when using a RF front-end and you need to attain real time. If you are working with a file (and thus without real-time constraints), you may want to obtain more information about the internals of the receiver, as well as more fine-grained logging. This can be done by building the Debug version, by doing:
|
||||
|
||||
~~~~~~
|
||||
$ cd gnss-sdr/build
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../
|
||||
$ make
|
||||
$ make install
|
||||
~~~~~~
|
||||
|
||||
If you are using Eclipse as your development environment, CMake can create the project for you. Type:
|
||||
|
||||
~~~~~~
|
||||
$ cmake -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DECLIPSE_CDT4_GENERATE_SOURCE_PROJECT=TRUE -DCMAKE_ECLIPSE_VERSION=3.7 -DCMAKE_ECLIPSE_MAKE_ARGUMENTS=-j8 ../
|
||||
~~~~~~
|
||||
|
||||
and then import the created project file into Eclipse:
|
||||
|
||||
1. Import project using Menu File -> Import.
|
||||
2. Select General -> Existing projects into workspace.
|
||||
3. Browse where your build tree is and select the root build tree directory. Keep "Copy projects into workspace" unchecked.
|
||||
4. You get a fully functional Eclipse project.
|
||||
|
||||
|
||||
|
||||
Mac OS X
|
||||
<a name="macosx">Mac OS X</a>
|
||||
---------
|
||||
|
||||
Tested versions: 10.8 (Mountain Lion) and 10.9 (Mavericks).
|
||||
@ -336,7 +316,17 @@ Tested versions: 10.8 (Mountain Lion) and 10.9 (Mavericks).
|
||||
|
||||
### Mac OS X 10.9 Mavericks
|
||||
|
||||
If you still have not installed [Xcode](http://developer.apple.com/xcode/), do it now from the App Store (it's free).
|
||||
If you still have not installed [Xcode](http://developer.apple.com/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
|
||||
~~~~~~
|
||||
|
||||
Agree to Xcode license:
|
||||
|
||||
~~~~~~
|
||||
$ sudo xcodebuild -license
|
||||
~~~~~~
|
||||
|
||||
Then, [install Macports](http://www.macports.org/install.php). If you are upgrading from a previous installation, please follow the [migration rules](http://trac.macports.org/wiki/Migration).
|
||||
|
||||
@ -346,7 +336,7 @@ In a terminal, type:
|
||||
$ sudo port selfupdate
|
||||
$ sudo port upgrade outdated
|
||||
$ sudo port install doxygen +latex
|
||||
$ sudo port install uhd gnuradio
|
||||
$ sudo port install gnuradio
|
||||
$ sudo port install armadillo
|
||||
$ sudo port install google-glog +gflags
|
||||
~~~~~~
|
||||
@ -356,7 +346,7 @@ Finally, you are ready to clone the GNSS-SDR repository and build the software:
|
||||
~~~~~~
|
||||
$ git clone git://git.code.sf.net/p/gnss-sdr/cttc gnss-sdr
|
||||
$ cd gnss-sdr/build
|
||||
$ cmake ../ -DCMAKE_CXX_COMPILER=/usr/bin/clang++
|
||||
$ cmake -DCMAKE_CXX_COMPILER=/usr/bin/clang++ ../
|
||||
$ make
|
||||
$ make install
|
||||
~~~~~~
|
||||
@ -414,7 +404,7 @@ Then, you are ready to clone the GNSS-SDR repository and build the software:
|
||||
~~~~~~
|
||||
$ git clone git://git.code.sf.net/p/gnss-sdr/cttc gnss-sdr
|
||||
$ cd gnss-sdr/build
|
||||
$ cmake ../ -DCMAKE_CXX_COMPILER=g++
|
||||
$ cmake -DCMAKE_CXX_COMPILER=g++ ../
|
||||
$ make
|
||||
$ make install
|
||||
~~~~~~
|
||||
|
25
cmake/Modules/FindOpenBLAS.cmake
Normal file
25
cmake/Modules/FindOpenBLAS.cmake
Normal file
@ -0,0 +1,25 @@
|
||||
# - Try to find OpenBLAS library (not headers!)
|
||||
#
|
||||
# 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
|
||||
)
|
||||
|
||||
FIND_LIBRARY(OPENBLAS NAMES openblas PATHS ${OPEN_BLAS_SEARCH_PATHS})
|
||||
|
||||
IF (OPENBLAS)
|
||||
SET(OPENBLAS_FOUND ON)
|
||||
MESSAGE(STATUS "Found OpenBLAS")
|
||||
ENDIF (OPENBLAS)
|
||||
|
||||
MARK_AS_ADVANCED(OPENBLAS)
|
@ -29,10 +29,10 @@ GNSS-SDR.SUPL_CI=0x31b0
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=/media/DATALOGGER/Agilent GPS Generator/cap2/agilent_cap2.dat
|
||||
SignalSource.filename=../../../Documents/workspace/code2/trunk/data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
SignalSource.item_type=gr_complex
|
||||
SignalSource.item_type=short
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=4000000
|
||||
@ -69,13 +69,13 @@ SignalSource.enable_throttle_control=false
|
||||
;#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
|
||||
SignalConditioner.implementation=Pass_Through
|
||||
SignalConditioner.implementation=Signal_Conditioner
|
||||
;SignalConditioner.implementation=Pass_Through
|
||||
|
||||
;######### DATA_TYPE_ADAPTER CONFIG ############
|
||||
;## Changes the type of input data. Please disable it in this version.
|
||||
;#implementation: [Pass_Through] disables this block
|
||||
DataTypeAdapter.implementation=Pass_Through
|
||||
DataTypeAdapter.implementation=Ishort_To_Complex
|
||||
|
||||
;######### INPUT_FILTER CONFIG ############
|
||||
;## Filter the input data. Can be combined with frequency translation for IF signals
|
||||
@ -186,60 +186,9 @@ Channel.system=GPS
|
||||
|
||||
;#signal:
|
||||
;# "1C" GPS L1 C/A
|
||||
;# "1P" GPS L1 P
|
||||
;# "1W" GPS L1 Z-tracking and similar (AS on)
|
||||
;# "1Y" GPS L1 Y
|
||||
;# "1M" GPS L1 M
|
||||
;# "1N" GPS L1 codeless
|
||||
;# "2C" GPS L2 C/A
|
||||
;# "2D" GPS L2 L1(C/A)+(P2-P1) semi-codeless
|
||||
;# "2S" GPS L2 L2C (M)
|
||||
;# "2L" GPS L2 L2C (L)
|
||||
;# "2X" GPS L2 L2C (M+L)
|
||||
;# "2P" GPS L2 P
|
||||
;# "2W" GPS L2 Z-tracking and similar (AS on)
|
||||
;# "2Y" GPS L2 Y
|
||||
;# "2M" GPS GPS L2 M
|
||||
;# "2N" GPS L2 codeless
|
||||
;# "5I" GPS L5 I
|
||||
;# "5Q" GPS L5 Q
|
||||
;# "5X" GPS L5 I+Q
|
||||
;# "1C" GLONASS G1 C/A
|
||||
;# "1P" GLONASS G1 P
|
||||
;# "2C" GLONASS G2 C/A (Glonass M)
|
||||
;# "2P" GLONASS G2 P
|
||||
;# "1A" GALILEO E1 A (PRS)
|
||||
;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL)
|
||||
;# "1C" GALILEO E1 C (no data)
|
||||
;# "1X" GALILEO E1 B+C
|
||||
;# "1Z" GALILEO E1 A+B+C
|
||||
;# "5I" GALILEO E5a I (F/NAV OS)
|
||||
;# "5Q" GALILEO E5a Q (no data)
|
||||
;# "5X" GALILEO E5a I+Q
|
||||
;# "7I" GALILEO E5b I
|
||||
;# "7Q" GALILEO E5b Q
|
||||
;# "7X" GALILEO E5b I+Q
|
||||
;# "8I" GALILEO E5 I
|
||||
;# "8Q" GALILEO E5 Q
|
||||
;# "8X" GALILEO E5 I+Q
|
||||
;# "6A" GALILEO E6 A
|
||||
;# "6B" GALILEO E6 B
|
||||
;# "6C" GALILEO E6 C
|
||||
;# "6X" GALILEO E6 B+C
|
||||
;# "6Z" GALILEO E6 A+B+C
|
||||
;# "1C" SBAS L1 C/A
|
||||
;# "5I" SBAS L5 I
|
||||
;# "5Q" SBAS L5 Q
|
||||
;# "5X" SBAS L5 I+Q
|
||||
;# "2I" COMPASS E2 I
|
||||
;# "2Q" COMPASS E2 Q
|
||||
;# "2X" COMPASS E2 IQ
|
||||
;# "7I" COMPASS E5b I
|
||||
;# "7Q" COMPASS E5b Q
|
||||
;# "7X" COMPASS E5b IQ
|
||||
;# "6I" COMPASS E6 I
|
||||
;# "6Q" COMPASS E6 Q
|
||||
;# "6X" COMPASS E6 IQ
|
||||
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
Channel.signal=1C
|
||||
|
||||
@ -248,17 +197,17 @@ Channel.signal=1C
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
|
||||
Channel0.system=GPS
|
||||
Channel0.signal=1C
|
||||
;Channel0.system=GPS
|
||||
;Channel0.signal=1C
|
||||
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
Channel0.satellite=11
|
||||
;Channel0.satellite=11
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
Channel1.system=GPS
|
||||
Channel1.signal=1C
|
||||
Channel1.satellite=18
|
||||
;Channel1.system=GPS
|
||||
;Channel1.signal=1C
|
||||
;Channel1.satellite=18
|
||||
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
@ -313,7 +262,8 @@ Acquisition.max_dwells=1
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking]
|
||||
Tracking.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
;Tracking.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
Tracking.implementation=GPS_L1_CA_DLL_PLL_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
|
||||
@ -330,7 +280,7 @@ Tracking.dump_filename=./tracking_ch_
|
||||
Tracking.pll_bw_hz=50.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
Tracking.dll_bw_hz=4.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
|
411
conf/gnss-sdr_acq_QuickSync.conf
Normal file
411
conf/gnss-sdr_acq_QuickSync.conf
Normal file
@ -0,0 +1,411 @@
|
||||
; 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_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
|
||||
GNSS-SDR.internal_fs_hz=4000000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] or [Rtlsdr_Signal_Source]
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=/home/dmiralles2009/Downloads/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples.
|
||||
;#Use gr_complex for 32 bits float I/Q or short for I/Q interleaved short integer.
|
||||
;#If short is selected you should have to instantiate the Ishort_To_Complex data_type_adapter.
|
||||
|
||||
SignalSource.item_type=short
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=4000000
|
||||
|
||||
;#freq: RF front-end center frequency in [Hz]
|
||||
SignalSource.freq=1575420000
|
||||
|
||||
;#gain: Front-end Gain in [dB]
|
||||
SignalSource.gain=60
|
||||
|
||||
;#AGC_enabled: RTLSDR AGC enabled [true or false]
|
||||
|
||||
SignalSource.AGC_enabled=true
|
||||
|
||||
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
|
||||
SignalSource.subdevice=B:0
|
||||
|
||||
;#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. Please disable it in this version.
|
||||
;#implementation: Use [Ishort_To_Complex] or [Pass_Through]
|
||||
DataTypeAdapter.implementation=Ishort_To_Complex
|
||||
;#dump: Dump the filtered data to a file.
|
||||
DataTypeAdapter.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
DataTypeAdapter.dump_filename=../data/data_type_adapter.dat
|
||||
|
||||
;######### 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]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Fir_Filter] enables a FIR Filter
|
||||
;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz.
|
||||
|
||||
;InputFilter.implementation=Fir_Filter
|
||||
;InputFilter.implementation=Freq_Xlating_Fir_Filter
|
||||
InputFilter.implementation=Pass_Through
|
||||
|
||||
;#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=gr_complex
|
||||
|
||||
;#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.8
|
||||
InputFilter.band1_end=0.85
|
||||
InputFilter.band2_begin=0.90
|
||||
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
|
||||
|
||||
;#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.sampling_frequency=4000000
|
||||
InputFilter.IF=0
|
||||
|
||||
|
||||
|
||||
;######### 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=Direct_Resampler
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the resamplered data to a file.
|
||||
Resampler.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
Resampler.dump_filename=../data/resampler.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
;#sample_freq_in: the sample frequency of the input signal
|
||||
Resampler.sample_freq_in=4000000
|
||||
|
||||
;#sample_freq_out: the desired sample frequency of the output signal
|
||||
Resampler.sample_freq_out=4000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=5
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
Channels.in_acquisition=1
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel0.system=GPS
|
||||
|
||||
;#signal:
|
||||
;# "1C" GPS L1 C/A
|
||||
;# "1P" GPS L1 P
|
||||
;# "1W" GPS L1 Z-tracking and similar (AS on)
|
||||
;# "1Y" GPS L1 Y
|
||||
;# "1M" GPS L1 M
|
||||
;# "1N" GPS L1 codeless
|
||||
;# "2C" GPS L2 C/A
|
||||
;# "2D" GPS L2 L1(C/A)+(P2-P1) semi-codeless
|
||||
;# "2S" GPS L2 L2C (M)
|
||||
;# "2L" GPS L2 L2C (L)
|
||||
;# "2X" GPS L2 L2C (M+L)
|
||||
;# "2P" GPS L2 P
|
||||
;# "2W" GPS L2 Z-tracking and similar (AS on)
|
||||
;# "2Y" GPS L2 Y
|
||||
;# "2M" GPS GPS L2 M
|
||||
;# "2N" GPS L2 codeless
|
||||
;# "5I" GPS L5 I
|
||||
;# "5Q" GPS L5 Q
|
||||
;# "5X" GPS L5 I+Q
|
||||
;# "1C" GLONASS G1 C/A
|
||||
;# "1P" GLONASS G1 P
|
||||
;# "2C" GLONASS G2 C/A (Glonass M)
|
||||
;# "2P" GLONASS G2 P
|
||||
;# "1A" GALILEO E1 A (PRS)
|
||||
;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL)
|
||||
;# "1C" GALILEO E1 C (no data)
|
||||
;# "1X" GALILEO E1 B+C
|
||||
;# "1Z" GALILEO E1 A+B+C
|
||||
;# "5I" GALILEO E5a I (F/NAV OS)
|
||||
;# "5Q" GALILEO E5a Q (no data)
|
||||
;# "5X" GALILEO E5a I+Q
|
||||
;# "7I" GALILEO E5b I
|
||||
;# "7Q" GALILEO E5b Q
|
||||
;# "7X" GALILEO E5b I+Q
|
||||
;# "8I" GALILEO E5 I
|
||||
;# "8Q" GALILEO E5 Q
|
||||
;# "8X" GALILEO E5 I+Q
|
||||
;# "6A" GALILEO E6 A
|
||||
;# "6B" GALILEO E6 B
|
||||
;# "6C" GALILEO E6 C
|
||||
;# "6X" GALILEO E6 B+C
|
||||
;# "6Z" GALILEO E6 A+B+C
|
||||
;# "1C" SBAS L1 C/A
|
||||
;# "5I" SBAS L5 I
|
||||
;# "5Q" SBAS L5 Q
|
||||
;# "5X" SBAS L5 I+Q
|
||||
;# "2I" COMPASS E2 I
|
||||
;# "2Q" COMPASS E2 Q
|
||||
;# "2X" COMPASS E2 IQ
|
||||
;# "7I" COMPASS E5b I
|
||||
;# "7Q" COMPASS E5b Q
|
||||
;# "7X" COMPASS E5b IQ
|
||||
;# "6I" COMPASS E6 I
|
||||
;# "6Q" COMPASS E6 Q
|
||||
;# "6X" COMPASS E6 IQ
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
|
||||
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
Channel0.system=GPS
|
||||
Channel0.signal=1C
|
||||
Channel0.satellite=1
|
||||
Channel0.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
|
||||
Channel1.system=GPS
|
||||
Channel1.signal=1C
|
||||
Channel1.satellite=11
|
||||
Channel1.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 2 CONFIG ############
|
||||
|
||||
Channel2.system=GPS
|
||||
Channel2.signal=1C
|
||||
Channel2.satellite=17
|
||||
Channel2.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 3 CONFIG ############
|
||||
|
||||
Channel3.system=GPS
|
||||
Channel3.signal=1C
|
||||
Channel3.satellite=20
|
||||
Channel3.repeat_satellite=false
|
||||
|
||||
;######### CHANNEL 4 CONFIG ############
|
||||
|
||||
Channel4.system=GPS
|
||||
Channel4.signal=1C
|
||||
Channel4.satellite=32
|
||||
Channel4.repeat_satellite=false
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=true
|
||||
;#filename: Log path and filename
|
||||
;Acquisition.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
|
||||
Acquisition.coherent-integration_time_ms=4
|
||||
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition]
|
||||
Acquisition0.implementation=GPS_L1_CA_PCPS_QuickSync_Acquisition
|
||||
;#threshold: Acquisition threshold
|
||||
Acquisition0.threshold=0.4
|
||||
;#doppler_max: Maximum expected Doppler shift [Hz]
|
||||
Acquisition0.doppler_max=10000
|
||||
;#doppler_max: Doppler step in the grid search [Hz]
|
||||
Acquisition0.doppler_step=250
|
||||
;#repeat_satellite: Use only jointly with the satellte PRN ID option.
|
||||
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
Acquisition1.implementation=GPS_L1_CA_PCPS_QuickSync_Acquisition
|
||||
Acquisition1.threshold=0.4
|
||||
Acquisition1.doppler_max=10000
|
||||
Acquisition1.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 2 CONFIG ############
|
||||
Acquisition2.implementation=GPS_L1_CA_PCPS_QuickSync_Acquisition
|
||||
Acquisition2.threshold=0.5
|
||||
Acquisition2.doppler_max=10000
|
||||
Acquisition2.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 3 CONFIG ############
|
||||
Acquisition3.implementation=GPS_L1_CA_PCPS_QuickSync_Acquisition
|
||||
Acquisition3.threshold=0.5
|
||||
Acquisition3.doppler_max=10000
|
||||
Acquisition3.doppler_step=250
|
||||
|
||||
|
||||
;######### ACQUISITION CH 4 CONFIG ############
|
||||
Acquisition4.implementation=GPS_L1_CA_PCPS_QuickSync_Acquisition
|
||||
Acquisition4.threshold=0.6
|
||||
Acquisition4.doppler_max=10000
|
||||
Acquisition4.doppler_step=250
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking]
|
||||
Tracking.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=false
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=./tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=50.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=4.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
|
||||
Tracking.early_late_space_chips=0.5;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A.
|
||||
TelemetryDecoder.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
Observables.implementation=GPS_L1_CA_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 ############
|
||||
;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version.
|
||||
PVT.implementation=GPS_L1_CA_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=10
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=true
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=100;
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500;
|
||||
|
||||
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
|
||||
PVT.dump=false
|
||||
|
||||
;#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=./PVT
|
||||
|
||||
;######### OUTPUT_FILTER CONFIG ############
|
||||
;# Receiver output filter: Leave this block disabled in this version
|
||||
OutputFilter.implementation=Null_Sink_Output_Filter
|
||||
OutputFilter.filename=data/gnss-sdr.dat
|
||||
OutputFilter.item_type=gr_complex
|
416
conf/gnss-sdr_acq_QuickSync_Galileo.conf
Normal file
416
conf/gnss-sdr_acq_QuickSync_Galileo.conf
Normal file
@ -0,0 +1,416 @@
|
||||
; 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_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
|
||||
GNSS-SDR.internal_fs_hz=4000000
|
||||
|
||||
;######### CONTROL_THREAD CONFIG ############
|
||||
ControlThread.wait_for_flowgraph=false
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] or [Rtlsdr_Signal_Source]
|
||||
SignalSource.implementation=File_Signal_Source
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
SignalSource.filename=/home/dmiralles2009/Downloads/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
|
||||
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples.
|
||||
;#Use gr_complex for 32 bits float I/Q or short for I/Q interleaved short integer.
|
||||
;#If short is selected you should have to instantiate the Ishort_To_Complex data_type_adapter.
|
||||
|
||||
SignalSource.item_type=short
|
||||
|
||||
;#sampling_frequency: Original Signal sampling frequency in [Hz]
|
||||
SignalSource.sampling_frequency=4000000
|
||||
|
||||
;#freq: RF front-end center frequency in [Hz]
|
||||
SignalSource.freq=1575420000
|
||||
|
||||
;#gain: Front-end Gain in [dB]
|
||||
SignalSource.gain=60
|
||||
|
||||
;#AGC_enabled: RTLSDR AGC enabled [true or false]
|
||||
|
||||
SignalSource.AGC_enabled=true
|
||||
|
||||
;#subdevice: UHD subdevice specification (for USRP1 use A:0 or B:0)
|
||||
SignalSource.subdevice=B:0
|
||||
|
||||
;#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. Please disable it in this version.
|
||||
;#implementation: Use [Ishort_To_Complex] or [Pass_Through]
|
||||
DataTypeAdapter.implementation=Ishort_To_Complex
|
||||
;#dump: Dump the filtered data to a file.
|
||||
DataTypeAdapter.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
DataTypeAdapter.dump_filename=../data/data_type_adapter.dat
|
||||
|
||||
;######### 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]
|
||||
;#[Pass_Through] disables this block
|
||||
;#[Fir_Filter] enables a FIR Filter
|
||||
;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz.
|
||||
|
||||
;InputFilter.implementation=Fir_Filter
|
||||
;InputFilter.implementation=Freq_Xlating_Fir_Filter
|
||||
InputFilter.implementation=Pass_Through
|
||||
|
||||
;#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=gr_complex
|
||||
|
||||
;#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
|
||||
|
||||
#used for gps
|
||||
InputFilter.band1_begin=0.0
|
||||
;InputFilter.band1_end=0.8
|
||||
InputFilter.band1_end=0.85
|
||||
InputFilter.band2_begin=0.90
|
||||
InputFilter.band2_end=1.0
|
||||
|
||||
#used for galileo
|
||||
InputFilter.band1_begin=0.0
|
||||
;InputFilter.band1_end=0.8
|
||||
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
|
||||
|
||||
;#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.sampling_frequency=4000000
|
||||
InputFilter.IF=0
|
||||
|
||||
|
||||
|
||||
;######### 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=Direct_Resampler
|
||||
Resampler.implementation=Pass_Through
|
||||
|
||||
;#dump: Dump the resamplered data to a file.
|
||||
Resampler.dump=false
|
||||
;#dump_filename: Log path and filename.
|
||||
Resampler.dump_filename=../data/resampler.dat
|
||||
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Resampler.item_type=gr_complex
|
||||
|
||||
;#sample_freq_in: the sample frequency of the input signal
|
||||
Resampler.sample_freq_in=4000000
|
||||
|
||||
;#sample_freq_out: the desired sample frequency of the output signal
|
||||
Resampler.sample_freq_out=4000000
|
||||
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
;#count: Number of available satellite channels.
|
||||
Channels.count=4
|
||||
;#in_acquisition: Number of channels simultaneously acquiring
|
||||
Channels.in_acquisition=1
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
|
||||
;#if the option is disabled by default is assigned GPS
|
||||
Channel.system = Galileo
|
||||
;Channel.system = GPS
|
||||
|
||||
|
||||
;#signal:
|
||||
;# "1C" GPS L1 C/A
|
||||
;# "1P" GPS L1 P
|
||||
;# "1W" GPS L1 Z-tracking and similar (AS on)
|
||||
;# "1Y" GPS L1 Y
|
||||
;# "1M" GPS L1 M
|
||||
;# "1N" GPS L1 codeless
|
||||
;# "2C" GPS L2 C/A
|
||||
;# "2D" GPS L2 L1(C/A)+(P2-P1) semi-codeless
|
||||
;# "2S" GPS L2 L2C (M)
|
||||
;# "2L" GPS L2 L2C (L)
|
||||
;# "2X" GPS L2 L2C (M+L)
|
||||
;# "2P" GPS L2 P
|
||||
;# "2W" GPS L2 Z-tracking and similar (AS on)
|
||||
;# "2Y" GPS L2 Y
|
||||
;# "2M" GPS GPS L2 M
|
||||
;# "2N" GPS L2 codeless
|
||||
;# "5I" GPS L5 I
|
||||
;# "5Q" GPS L5 Q
|
||||
;# "5X" GPS L5 I+Q
|
||||
;# "1C" GLONASS G1 C/A
|
||||
;# "1P" GLONASS G1 P
|
||||
;# "2C" GLONASS G2 C/A (Glonass M)
|
||||
;# "2P" GLONASS G2 P
|
||||
;# "1A" GALILEO E1 A (PRS)
|
||||
;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL)
|
||||
;# "1C" GALILEO E1 C (no data)
|
||||
;# "1X" GALILEO E1 B+C
|
||||
;# "1Z" GALILEO E1 A+B+C
|
||||
;# "5I" GALILEO E5a I (F/NAV OS)
|
||||
;# "5Q" GALILEO E5a Q (no data)
|
||||
;# "5X" GALILEO E5a I+Q
|
||||
;# "7I" GALILEO E5b I
|
||||
;# "7Q" GALILEO E5b Q
|
||||
;# "7X" GALILEO E5b I+Q
|
||||
;# "8I" GALILEO E5 I
|
||||
;# "8Q" GALILEO E5 Q
|
||||
;# "8X" GALILEO E5 I+Q
|
||||
;# "6A" GALILEO E6 A
|
||||
;# "6B" GALILEO E6 B
|
||||
;# "6C" GALILEO E6 C
|
||||
;# "6X" GALILEO E6 B+C
|
||||
;# "6Z" GALILEO E6 A+B+C
|
||||
;# "1C" SBAS L1 C/A
|
||||
;# "5I" SBAS L5 I
|
||||
;# "5Q" SBAS L5 Q
|
||||
;# "5X" SBAS L5 I+Q
|
||||
;# "2I" COMPASS E2 I
|
||||
;# "2Q" COMPASS E2 Q
|
||||
;# "2X" COMPASS E2 IQ
|
||||
;# "7I" COMPASS E5b I
|
||||
;# "7Q" COMPASS E5b Q
|
||||
;# "7X" COMPASS E5b IQ
|
||||
;# "6I" COMPASS E6 I
|
||||
;# "6Q" COMPASS E6 Q
|
||||
;# "6X" COMPASS E6 IQ
|
||||
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
|
||||
|
||||
|
||||
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
|
||||
|
||||
;######### CHANNEL 0 CONFIG ############
|
||||
;### Uncoment these lines for Galileo Systems
|
||||
Channel0.system=Galileo
|
||||
Channel0.signal=1B
|
||||
Channel0.satellite=20
|
||||
;Channel0.repeat_satellite=true
|
||||
|
||||
|
||||
;######### CHANNEL 1 CONFIG ############
|
||||
;### Uncoment these lines for Galileo Systems
|
||||
Channel1.system=Galileo
|
||||
Channel1.signal=1B
|
||||
Channel1.satellite=12
|
||||
;Channel1.repeat_satellite=true
|
||||
|
||||
;######### CHANNEL 2 CONFIG ############
|
||||
;### Uncoment these lines for Galileo Systems
|
||||
Channel2.system=Galileo
|
||||
Channel2.signal=1B
|
||||
Channel2.satellite=19
|
||||
;Channel2.repeat_satellite=true
|
||||
|
||||
;######### CHANNEL 3 CONFIG ############
|
||||
;### Uncoment these lines for Galileo Systems
|
||||
Channel3.system=Galileo
|
||||
Channel3.signal=1B
|
||||
Channel3.satellite=11
|
||||
;Channel3.repeat_satellite=true
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
|
||||
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
|
||||
Acquisition.dump=true
|
||||
;#filename: Log path and filename
|
||||
Acquisition.dump_filename=./acq_dump.dat
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
|
||||
Acquisition.item_type=gr_complex
|
||||
;#if: Signal intermediate frequency in [Hz]
|
||||
Acquisition.if=0
|
||||
;#sampled_ms: Signal block duration for the acquisition signal detection [ms];
|
||||
Acquisition.coherent_integration_time_ms=8
|
||||
Acquisition.repeat_satellite=true
|
||||
;######### ACQUISITION CHANNELS CONFIG ######
|
||||
|
||||
;######### ACQUISITION CONFIG PARAMETERS ############
|
||||
|
||||
;######### ACQUISITION CH 0 CONFIG ############
|
||||
;### Uncoment these lines for Galileo Systems
|
||||
Acquisition0.implementation=Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition
|
||||
Acquisition0.doppler_step=125
|
||||
Acquisition0.threshold=0.05
|
||||
Acquisition0.doppler_max=10000
|
||||
Acquisition0.repeat_satellite=true
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
;### Uncoment these lines for Galileo Systems
|
||||
Acquisition1.implementation=Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition
|
||||
Acquisition1.doppler_step=125
|
||||
Acquisition1.threshold=0.05
|
||||
Acquisition1.doppler_max=15000
|
||||
Acquisition1.repeat_satellite=true
|
||||
|
||||
;######### ACQUISITION CH 2 CONFIG ############
|
||||
;### Uncoment these lines for Galileo Systems
|
||||
Acquisition2.implementation=Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition
|
||||
Acquisition2.threshold=0.04
|
||||
Acquisition2.doppler_max=10000
|
||||
Acquisition2.doppler_step=125
|
||||
Acquisition2.repeat_satellite=true
|
||||
|
||||
;######### ACQUISITION CH 3 CONFIG ############
|
||||
;### Uncoment these lines for Galileo Systems
|
||||
Acquisition3.implementation=Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition
|
||||
Acquisition3.threshold=0.04
|
||||
Acquisition3.doppler_max=15000
|
||||
Acquisition3.doppler_step=62
|
||||
Acquisition3.repeat_satellite=true
|
||||
|
||||
;######### ACQUISITION CH 1 CONFIG ############
|
||||
Acquisition.cboc=false
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
|
||||
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking] or [GPS_L1_CA_TCP_CONNECTOR_Tracking] or [Galileo_E1_DLL_PLL_VEML_Tracking]
|
||||
Tracking.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
|
||||
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
|
||||
Tracking.item_type=gr_complex
|
||||
|
||||
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
|
||||
Tracking.if=0
|
||||
|
||||
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
|
||||
Tracking.dump=true
|
||||
|
||||
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
|
||||
Tracking.dump_filename=../data/veml_tracking_ch_
|
||||
|
||||
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
|
||||
Tracking.pll_bw_hz=20.0;
|
||||
|
||||
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
|
||||
Tracking.dll_bw_hz=2.0;
|
||||
|
||||
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
|
||||
Tracking.fll_bw_hz=10.0;
|
||||
|
||||
;#order: PLL/DLL loop filter order [2] or [3]
|
||||
Tracking.order=3;
|
||||
|
||||
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5] for GPS and [0.15] for Galileo
|
||||
Tracking.early_late_space_chips=0.15;
|
||||
|
||||
;#very_early_late_space_chips: only for [Galileo_E1_DLL_PLL_VEML_Tracking], correlator very early-late space [chips]. Use [0.6]
|
||||
Tracking.very_early_late_space_chips=0.6;
|
||||
|
||||
;######### TELEMETRY DECODER CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A or [Galileo_E1B_Telemetry_Decoder] for Galileo E1B
|
||||
TelemetryDecoder.implementation=Galileo_E1B_Telemetry_Decoder
|
||||
TelemetryDecoder.dump=false
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
|
||||
Observables.implementation=Galileo_E1B_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 ############
|
||||
;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version.
|
||||
PVT.implementation=GALILEO_E1_PVT
|
||||
|
||||
;#averaging_depth: Number of PVT observations in the moving average algorithm
|
||||
PVT.averaging_depth=100
|
||||
|
||||
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
|
||||
PVT.flag_averaging=true
|
||||
|
||||
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
|
||||
PVT.output_rate_ms=100;
|
||||
|
||||
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
|
||||
PVT.display_rate_ms=500;
|
||||
|
||||
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
|
||||
PVT.dump=false
|
||||
|
||||
;#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=./PVT
|
||||
|
||||
;######### OUTPUT_FILTER CONFIG ############
|
||||
;# Receiver output filter: Leave this block disabled in this version
|
||||
OutputFilter.implementation=Null_Sink_Output_Filter
|
||||
OutputFilter.filename=data/gnss-sdr.dat
|
||||
OutputFilter.item_type=gr_complex
|
@ -24,9 +24,9 @@
|
||||
All the current GPS Interface Control Documents can be downloaded from <a href="http://www.gps.gov" target="_blank">GPS.gov</a>, the official U.S. Government webpage for GPS.
|
||||
|
||||
|
||||
\li GPS L1 and L2C: Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-200G.pdf" target="_blank"><b>Interface Specification IS-GPS-200 Revision G</b></a>. January, 2013.
|
||||
\li GPS L1C (available with first Block III launch, currently scheduled for 2013): Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-800C.pdf" target="_blank"><b>Interface Specification IS-GPS-800 Revision C</b></a>. January, 2013.
|
||||
\li GPS L5 (first Block IIF satellite launched on May, 2010): Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-705C.pdf" target="_blank"><b>Interface Specification IS-GPS-705 Revision C</b></a>. January, 2013.
|
||||
\li GPS L1 and L2C: Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-200H.pdf" target="_blank"><b>Interface Specification IS-GPS-200 Revision H</b></a>. September, 2013.
|
||||
\li GPS L1C (available with first Block III launch): Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-800D.pdf" target="_blank"><b>Interface Specification IS-GPS-800 Revision D</b></a>. September, 2013.
|
||||
\li GPS L5 (first Block IIF satellite launched on May, 2010): Global Positioning System Directorate, <a href="http://www.gps.gov/technical/icwg/IS-GPS-705D.pdf" target="_blank"><b>Interface Specification IS-GPS-705 Revision D</b></a>. September, 2013.
|
||||
|
||||
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
#define MUL_RE(a,b) (a.x*b.x - a.y*b.y)
|
||||
#define MUL_IM(a,b) (a.x*b.y + a.y*b.x)
|
||||
#define SUM_RE(a,b) (a.x + b.x)
|
||||
#define SUM_IM(a,b) (a.y + b.y)
|
||||
|
||||
__kernel void add_vectors(__global const float2* src1, __global const float2* src2, __global float2* dest)
|
||||
{
|
||||
int gid = get_global_id(0);
|
||||
dest[gid] = (float2)(SUM_RE(src1[gid],src2[gid]),SUM_IM(src1[gid],src2[gid]));
|
||||
}
|
||||
|
||||
__kernel void mult_vectors(__global const float2* src1, __global const float2* src2, __global float2* dest)
|
||||
{
|
||||
int gid = get_global_id(0);
|
||||
dest[gid] = (float2)(MUL_RE(src1[gid],src2[gid]),MUL_IM(src1[gid],src2[gid]));
|
||||
}
|
||||
|
||||
__kernel void conj_vector(__global const float2* src, __global float2* dest)
|
||||
{
|
||||
int gid = get_global_id(0);
|
||||
dest[gid] = ((float2)(1,-1)) * src[gid];
|
||||
}
|
||||
|
||||
__kernel void magnitude_squared(__global const float2* src, __global float* dest)
|
||||
{
|
||||
int gid = get_global_id(0);
|
||||
dest[gid] = src[gid].x*src[gid].x + src[gid].y*src[gid].y;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ arma::vec galileo_e1_ls_pvt::rotateSatellite(double traveltime, arma::vec X_sat)
|
||||
|
||||
//--- Find rotation angle --------------------------------------------------
|
||||
double omegatau;
|
||||
omegatau = OMEGA_EARTH_DOT * traveltime;
|
||||
omegatau = GALILEO_OMEGA_EARTH_DOT * traveltime;
|
||||
|
||||
//--- Build a rotation matrix ----------------------------------------------
|
||||
arma::mat R3 = arma::zeros(3,3);
|
||||
@ -147,6 +147,9 @@ arma::vec galileo_e1_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arm
|
||||
double rho2;
|
||||
double traveltime;
|
||||
double trop;
|
||||
double dlambda;
|
||||
double dphi;
|
||||
double h;
|
||||
arma::mat mat_tmp;
|
||||
arma::vec x;
|
||||
|
||||
@ -179,6 +182,15 @@ arma::vec galileo_e1_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arm
|
||||
&d_visible_satellites_Distance[i],
|
||||
pos.subvec(0,2),
|
||||
Rot_X - pos.subvec(0, 2));
|
||||
if(traveltime < 0.1 && nmbOfSatellites > 3)
|
||||
{
|
||||
//--- Find receiver's height
|
||||
togeod(&dphi, &dlambda, &h, 6378137.0, 298.257223563, pos(0), pos(1), pos(2));
|
||||
|
||||
//--- Find delay due to troposphere (in meters)
|
||||
tropo(&trop, sin(d_visible_satellites_El[i] * GALILEO_PI/180.0), h/1000, 1013.0, 293.0, 50.0, 0.0, 0.0, 0.0);
|
||||
if(trop > 50.0 ) trop = 0.0;
|
||||
}
|
||||
}
|
||||
//--- Apply the corrections ----------------------------------------
|
||||
omc(i) = (obs(i) - norm(Rot_X - pos.subvec(0, 2), 2) - pos(3) - trop); // Armadillo
|
||||
@ -221,14 +233,12 @@ bool galileo_e1_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map
|
||||
std::map<int,Galileo_Ephemeris>::iterator galileo_ephemeris_iter;
|
||||
int valid_pseudoranges = gnss_pseudoranges_map.size();
|
||||
|
||||
arma::mat W = arma::eye(valid_pseudoranges, valid_pseudoranges); //channels weights matrix
|
||||
arma::mat W = arma::eye(valid_pseudoranges, valid_pseudoranges); // channels weights matrix
|
||||
arma::vec obs = arma::zeros(valid_pseudoranges); // pseudoranges observation vector
|
||||
arma::mat satpos = arma::zeros(3, valid_pseudoranges); //satellite positions matrix
|
||||
arma::mat satpos = arma::zeros(3, valid_pseudoranges); // satellite positions matrix
|
||||
|
||||
int Galileo_week_number = 0;
|
||||
double utc = 0;
|
||||
double SV_clock_drift_s = 0;
|
||||
double SV_relativistic_clock_corr_s = 0;
|
||||
double TX_time_corrected_s;
|
||||
double SV_clock_bias_s = 0;
|
||||
|
||||
@ -265,16 +275,12 @@ bool galileo_e1_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map
|
||||
//to compute satellite position we need GST = WN+TOW (everything expressed in seconds)
|
||||
//double Rx_time = galileo_current_time + Galileo_week_number*sec_in_day*day_in_week;
|
||||
|
||||
double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m/GALILEO_C_m_s;
|
||||
double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m / GALILEO_C_m_s;
|
||||
|
||||
// 2- compute the clock drift using the clock model (broadcast) for this SV
|
||||
SV_clock_drift_s = galileo_ephemeris_iter->second.sv_clock_drift(Tx_time);
|
||||
// 2- compute the clock drift using the clock model (broadcast) for this SV, including relativistic effect
|
||||
SV_clock_bias_s = galileo_ephemeris_iter->second.sv_clock_drift(Tx_time);
|
||||
|
||||
// 3- compute the relativistic clock drift using the clock model (broadcast) for this SV
|
||||
SV_relativistic_clock_corr_s = galileo_ephemeris_iter->second.sv_clock_relativistic_term(Tx_time);
|
||||
|
||||
// 4- compute the current ECEF position for this SV using corrected TX time
|
||||
SV_clock_bias_s = SV_clock_drift_s + SV_relativistic_clock_corr_s;
|
||||
// 3- compute the current ECEF position for this SV using corrected TX time
|
||||
TX_time_corrected_s = Tx_time - SV_clock_bias_s;
|
||||
galileo_ephemeris_iter->second.satellitePosition(TX_time_corrected_s);
|
||||
|
||||
@ -282,8 +288,8 @@ bool galileo_e1_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map
|
||||
satpos(1,obs_counter) = galileo_ephemeris_iter->second.d_satpos_Y;
|
||||
satpos(2,obs_counter) = galileo_ephemeris_iter->second.d_satpos_Z;
|
||||
|
||||
// 5- fill the observations vector with the corrected pseudoranges
|
||||
obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s*GALILEO_C_m_s;
|
||||
// 4- fill the observations vector with the corrected pseudoranges
|
||||
obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s * GALILEO_C_m_s;
|
||||
d_visible_satellites_IDs[valid_obs] = galileo_ephemeris_iter->second.i_satellite_PRN;
|
||||
d_visible_satellites_CN0_dB[valid_obs] = gnss_pseudoranges_iter->second.CN0_dB_hz;
|
||||
valid_obs++;
|
||||
@ -530,8 +536,8 @@ void galileo_e1_ls_pvt::cart2geo(double X, double Y, double Z, int elipsoid_sele
|
||||
}
|
||||
}
|
||||
while (abs(h - oldh) > 1.0e-12);
|
||||
d_latitude_d = phi * 180.0 / GPS_PI;
|
||||
d_longitude_d = lambda * 180 / GPS_PI;
|
||||
d_latitude_d = phi * 180.0 / GALILEO_PI;
|
||||
d_longitude_d = lambda * 180 / GALILEO_PI;
|
||||
d_height_m = h;
|
||||
}
|
||||
|
||||
@ -672,7 +678,7 @@ void galileo_e1_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
double lambda;
|
||||
double phi;
|
||||
double h;
|
||||
double dtr = GPS_PI/180.0;
|
||||
double dtr = GALILEO_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
|
||||
|
||||
@ -727,3 +733,103 @@ void galileo_e1_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
|
||||
*D = sqrt(dx(0)*dx(0) + dx(1)*dx(1) + dx(2)*dx(2));
|
||||
}
|
||||
|
||||
void galileo_e1_ls_pvt::tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km)
|
||||
{
|
||||
/* Inputs:
|
||||
sinel - sin of elevation angle of satellite
|
||||
hsta_km - height of station in km
|
||||
p_mb - atmospheric pressure in mb at height hp_km
|
||||
t_kel - surface temperature in degrees Kelvin at height htkel_km
|
||||
hum - humidity in % at height hhum_km
|
||||
hp_km - height of pressure measurement in km
|
||||
htkel_km - height of temperature measurement in km
|
||||
hhum_km - height of humidity measurement in km
|
||||
|
||||
Outputs:
|
||||
ddr_m - range correction (meters)
|
||||
|
||||
Reference
|
||||
Goad, C.C. & Goodman, L. (1974) A Modified Hopfield Tropospheric
|
||||
Refraction Correction Model. Paper presented at the
|
||||
American Geophysical Union Annual Fall Meeting, San
|
||||
Francisco, December 12-17
|
||||
|
||||
Translated to C++ by Carles Fernandez from a Matlab implementation by Kai Borre
|
||||
*/
|
||||
|
||||
const double a_e = 6378.137; // semi-major axis of earth ellipsoid
|
||||
const double b0 = 7.839257e-5;
|
||||
const double tlapse = -6.5;
|
||||
const double em = -978.77 / (2.8704e6 * tlapse * 1.0e-5);
|
||||
|
||||
double tkhum = t_kel + tlapse * (hhum_km - htkel_km);
|
||||
double atkel = 7.5*(tkhum - 273.15) / (237.3 + tkhum - 273.15);
|
||||
double e0 = 0.0611 * hum * pow(10, atkel);
|
||||
double tksea = t_kel - tlapse * htkel_km;
|
||||
double tkelh = tksea + tlapse * hhum_km;
|
||||
double e0sea = e0 * pow((tksea / tkelh), (4 * em));
|
||||
double tkelp = tksea + tlapse * hp_km;
|
||||
double psea = p_mb * pow((tksea / tkelp), em);
|
||||
|
||||
if(sinel < 0) { sinel = 0.0; }
|
||||
|
||||
double tropo_delay = 0.0;
|
||||
bool done = false;
|
||||
double refsea = 77.624e-6 / tksea;
|
||||
double htop = 1.1385e-5 / refsea;
|
||||
refsea = refsea * psea;
|
||||
double ref = refsea * pow(((htop - hsta_km) / htop), 4);
|
||||
|
||||
double a;
|
||||
double b;
|
||||
double rtop;
|
||||
|
||||
while(1)
|
||||
{
|
||||
rtop = pow((a_e + htop), 2) - pow((a_e + hsta_km), 2) * (1 - pow(sinel, 2));
|
||||
|
||||
// check to see if geometry is crazy
|
||||
if(rtop < 0) { rtop = 0; }
|
||||
|
||||
rtop = sqrt(rtop) - (a_e + hsta_km) * sinel;
|
||||
|
||||
a = -sinel / (htop - hsta_km);
|
||||
b = -b0 * (1 - pow(sinel,2)) / (htop - hsta_km);
|
||||
|
||||
arma::vec rn = arma::vec(8);
|
||||
rn.zeros();
|
||||
|
||||
for(int i = 0; i<8; i++)
|
||||
{
|
||||
rn(i) = pow(rtop, (i+1+1));
|
||||
|
||||
}
|
||||
|
||||
arma::rowvec alpha = {2 * a, 2 * pow(a, 2) + 4 * b /3, a * (pow(a, 2) + 3 * b),
|
||||
pow(a, 4)/5 + 2.4 * pow(a, 2) * b + 1.2 * pow(b, 2), 2 * a * b * (pow(a, 2) + 3 * b)/3,
|
||||
pow(b, 2) * (6 * pow(a, 2) + 4 * b) * 1.428571e-1, 0, 0};
|
||||
|
||||
if(pow(b, 2) > 1.0e-35)
|
||||
{
|
||||
alpha(6) = a * pow(b, 3) /2;
|
||||
alpha(7) = pow(b, 4) / 9;
|
||||
}
|
||||
|
||||
double dr = rtop;
|
||||
arma::mat aux_ = alpha * rn;
|
||||
dr = dr + aux_(0, 0);
|
||||
tropo_delay = tropo_delay + dr * ref * 1000;
|
||||
|
||||
if(done == true)
|
||||
{
|
||||
*ddr_m = tropo_delay;
|
||||
break;
|
||||
}
|
||||
|
||||
done = true;
|
||||
refsea = (371900.0e-6 / tksea - 12.92e-6) / tksea;
|
||||
htop = 1.1385e-5 * (1255 / tksea + 0.05) / refsea;
|
||||
ref = refsea * e0sea * pow(((htop - hsta_km) / htop), 4);
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ private:
|
||||
arma::vec rotateSatellite(double traveltime, arma::vec X_sat);
|
||||
void topocent(double *Az, double *El, double *D, arma::vec x, arma::vec dx);
|
||||
void togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z);
|
||||
void tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km);
|
||||
public:
|
||||
int d_nchannels; //!< Number of available channels for positioning
|
||||
int d_valid_observations; //!< Number of valid pseudorange observations (valid satellites)
|
||||
|
@ -27,14 +27,16 @@
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
#define GLOG_NO_ABBREVIATED_SEVERITIES
|
||||
|
||||
|
||||
#include "gps_l1_ca_ls_pvt.h"
|
||||
#include <gflags/gflags.h>
|
||||
#include <glog/logging.h>
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
DEFINE_bool(tropo, true, "Apply tropospheric correction");
|
||||
|
||||
gps_l1_ca_ls_pvt::gps_l1_ca_ls_pvt(int nchannels,std::string dump_filename, bool flag_dump_to_file)
|
||||
{
|
||||
@ -107,7 +109,7 @@ arma::vec gps_l1_ca_ls_pvt::rotateSatellite(double traveltime, arma::vec X_sat)
|
||||
R3(1, 2) = 0.0;
|
||||
R3(2, 0) = 0.0;
|
||||
R3(2, 1) = 0.0;
|
||||
R3(2, 2) = 1;
|
||||
R3(2, 2) = 1.0;
|
||||
|
||||
//--- Do the rotation ------------------------------------------------------
|
||||
arma::vec X_sat_rot;
|
||||
@ -147,6 +149,9 @@ arma::vec gps_l1_ca_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arma
|
||||
double rho2;
|
||||
double traveltime;
|
||||
double trop;
|
||||
double dlambda;
|
||||
double dphi;
|
||||
double h;
|
||||
arma::mat mat_tmp;
|
||||
arma::vec x;
|
||||
|
||||
@ -164,21 +169,33 @@ arma::vec gps_l1_ca_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arma
|
||||
else
|
||||
{
|
||||
//--- Update equations -----------------------------------------
|
||||
rho2 = (X(0, i) - pos(0)) *
|
||||
(X(0, i) - pos(0)) + (X(1, i) - pos(1)) *
|
||||
(X(1, i) - pos(1)) + (X(2,i) - pos(2)) *
|
||||
(X(2,i) - pos(2));
|
||||
rho2 = (X(0, i) - pos(0)) * (X(0, i) - pos(0))
|
||||
+ (X(1, i) - pos(1)) * (X(1, i) - pos(1))
|
||||
+ (X(2, i) - pos(2)) * (X(2, i) - pos(2));
|
||||
traveltime = sqrt(rho2) / GPS_C_m_s;
|
||||
|
||||
//--- Correct satellite position (do to earth rotation) --------
|
||||
Rot_X = rotateSatellite(traveltime, X.col(i)); //armadillo
|
||||
|
||||
//--- Find DOA and range of satellites
|
||||
//--- Find satellites' DOA
|
||||
topocent(&d_visible_satellites_Az[i], &d_visible_satellites_El[i],
|
||||
&d_visible_satellites_Distance[i], pos.subvec(0,2), Rot_X - pos.subvec(0,2));
|
||||
//[az(i), el(i), dist] = topocent(pos(1:3, :), Rot_X - pos(1:3, :));
|
||||
|
||||
if(FLAGS_tropo)
|
||||
{
|
||||
if(traveltime < 0.1 && nmbOfSatellites > 3)
|
||||
{
|
||||
//--- Find receiver's height
|
||||
togeod(&dphi, &dlambda, &h, 6378137.0, 298.257223563, pos(0), pos(1), pos(2));
|
||||
|
||||
//--- Find delay due to troposphere (in meters)
|
||||
tropo(&trop, sin(d_visible_satellites_El[i] * GPS_PI / 180.0), h / 1000, 1013.0, 293.0, 50.0, 0.0, 0.0, 0.0);
|
||||
if(trop > 50.0 ) trop = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- Apply the corrections ----------------------------------------
|
||||
omc(i) = (obs(i) - norm(Rot_X - pos.subvec(0,2),2) - pos(3) - trop); // Armadillo
|
||||
|
||||
@ -189,16 +206,16 @@ arma::vec gps_l1_ca_ls_pvt::leastSquarePos(arma::mat satpos, arma::vec obs, arma
|
||||
A(i,2) = (-(Rot_X(2) - pos(2))) / obs(i);
|
||||
A(i,3) = 1.0;
|
||||
}
|
||||
|
||||
|
||||
//--- Find position update ---------------------------------------------
|
||||
x = arma::solve(w*A, w*omc); // Armadillo
|
||||
|
||||
//--- Apply position update --------------------------------------------
|
||||
pos = pos + x;
|
||||
if (arma::norm(x, 2) < 1e-4)
|
||||
{
|
||||
break; // exit the loop because we assume that the LS algorithm has converged (err < 0.1 cm)
|
||||
}
|
||||
{
|
||||
break; // exit the loop because we assume that the LS algorithm has converged (err < 0.1 cm)
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
@ -221,13 +238,11 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
int valid_pseudoranges = gnss_pseudoranges_map.size();
|
||||
|
||||
arma::mat W = arma::eye(valid_pseudoranges, valid_pseudoranges); //channels weights matrix
|
||||
arma::vec obs = arma::zeros(valid_pseudoranges); // pseudoranges observation vector
|
||||
arma::mat satpos = arma::zeros(3, valid_pseudoranges); //satellite positions matrix
|
||||
arma::vec obs = arma::zeros(valid_pseudoranges); // pseudoranges observation vector
|
||||
arma::mat satpos = arma::zeros(3, valid_pseudoranges); //satellite positions matrix
|
||||
|
||||
int GPS_week = 0;
|
||||
double utc = 0;
|
||||
double SV_clock_drift_s = 0;
|
||||
double SV_relativistic_clock_corr_s = 0;
|
||||
double TX_time_corrected_s;
|
||||
double SV_clock_bias_s = 0;
|
||||
|
||||
@ -254,16 +269,12 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
// COMMON RX TIME PVT ALGORITHM MODIFICATION (Like RINEX files)
|
||||
// first estimate of transmit time
|
||||
double Rx_time = GPS_current_time;
|
||||
double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m/GPS_C_m_s;
|
||||
double Tx_time = Rx_time - gnss_pseudoranges_iter->second.Pseudorange_m / GPS_C_m_s;
|
||||
|
||||
// 2- compute the clock drift using the clock model (broadcast) for this SV
|
||||
SV_clock_drift_s = gps_ephemeris_iter->second.sv_clock_drift(Tx_time);
|
||||
// 2- compute the clock drift using the clock model (broadcast) for this SV, including relativistic effect
|
||||
SV_clock_bias_s = gps_ephemeris_iter->second.sv_clock_drift(Tx_time); //- gps_ephemeris_iter->second.d_TGD;
|
||||
|
||||
// 3- compute the relativistic clock drift using the clock model (broadcast) for this SV
|
||||
SV_relativistic_clock_corr_s = gps_ephemeris_iter->second.sv_clock_relativistic_term(Tx_time);
|
||||
|
||||
// 4- compute the current ECEF position for this SV using corrected TX time
|
||||
SV_clock_bias_s = SV_clock_drift_s + SV_relativistic_clock_corr_s - gps_ephemeris_iter->second.d_TGD;
|
||||
// 3- compute the current ECEF position for this SV using corrected TX time
|
||||
TX_time_corrected_s = Tx_time - SV_clock_bias_s;
|
||||
gps_ephemeris_iter->second.satellitePosition(TX_time_corrected_s);
|
||||
|
||||
@ -271,8 +282,8 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
satpos(1, obs_counter) = gps_ephemeris_iter->second.d_satpos_Y;
|
||||
satpos(2, obs_counter) = gps_ephemeris_iter->second.d_satpos_Z;
|
||||
|
||||
// 5- fill the observations vector with the corrected pseudorranges
|
||||
obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s*GPS_C_m_s;
|
||||
// 4- fill the observations vector with the corrected pseudoranges
|
||||
obs(obs_counter) = gnss_pseudoranges_iter->second.Pseudorange_m + SV_clock_bias_s * GPS_C_m_s;
|
||||
d_visible_satellites_IDs[valid_obs] = gps_ephemeris_iter->second.i_satellite_PRN;
|
||||
d_visible_satellites_CN0_dB[valid_obs] = gnss_pseudoranges_iter->second.CN0_dB_hz;
|
||||
valid_obs++;
|
||||
@ -284,7 +295,7 @@ bool gps_l1_ca_ls_pvt::get_PVT(std::map<int,Gnss_Synchro> gnss_pseudoranges_map,
|
||||
<< " [m] Z=" << gps_ephemeris_iter->second.d_satpos_Z
|
||||
<< " [m] PR_obs=" << obs(obs_counter) << " [m]";
|
||||
|
||||
// compute the UTC time for this SV (just to print the asociated UTC timestamp)
|
||||
// compute the UTC time for this SV (just to print the associated UTC timestamp)
|
||||
GPS_week = gps_ephemeris_iter->second.i_GPS_week;
|
||||
utc = gps_utc_model.utc_time(TX_time_corrected_s, GPS_week);
|
||||
}
|
||||
@ -566,7 +577,7 @@ void gps_l1_ca_ls_pvt::togeod(double *dphi, double *dlambda, double *h, double a
|
||||
{
|
||||
*dlambda = *dlambda + 360.0;
|
||||
}
|
||||
double r = sqrt(P*P + Z*Z); // r is distance from origin (0,0,0)
|
||||
double r = sqrt(P * P + Z * Z); // r is distance from origin (0,0,0)
|
||||
|
||||
double sinphi;
|
||||
if (r > 1.0E-20)
|
||||
@ -587,7 +598,7 @@ void gps_l1_ca_ls_pvt::togeod(double *dphi, double *dlambda, double *h, double a
|
||||
return;
|
||||
}
|
||||
|
||||
*h = r - a*(1-sinphi*sinphi/finv);
|
||||
*h = r - a * (1 - sinphi * sinphi / finv);
|
||||
|
||||
// iterate
|
||||
double cosphi;
|
||||
@ -602,18 +613,18 @@ void gps_l1_ca_ls_pvt::togeod(double *dphi, double *dlambda, double *h, double a
|
||||
cosphi = cos(*dphi);
|
||||
|
||||
// compute radius of curvature in prime vertical direction
|
||||
N_phi = a / sqrt(1 - esq*sinphi*sinphi);
|
||||
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));
|
||||
*h = *h + (sinphi * dZ + cosphi * dP);
|
||||
*dphi = *dphi + (cosphi * dZ - sinphi * dP)/(N_phi + (*h));
|
||||
|
||||
// test for convergence
|
||||
if ((dP*dP + dZ*dZ) < tolsq)
|
||||
if ((dP * dP + dZ * dZ) < tolsq)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -645,9 +656,9 @@ void gps_l1_ca_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
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
|
||||
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
|
||||
togeod(&phi, &lambda, &h, a, finv, x(0), x(1), x(2));
|
||||
@ -660,12 +671,12 @@ void gps_l1_ca_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
arma::mat F = arma::zeros(3,3);
|
||||
|
||||
F(0,0) = -sl;
|
||||
F(0,1) = -sb*cl;
|
||||
F(0,2) = cb*cl;
|
||||
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(1,1) = -sb * sl;
|
||||
F(1,2) = cb * sl;
|
||||
|
||||
F(2,0) = 0;
|
||||
F(2,1) = cb;
|
||||
@ -680,7 +691,7 @@ void gps_l1_ca_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
double U = local_vector(2);
|
||||
|
||||
double hor_dis;
|
||||
hor_dis = sqrt(E*E + N*N);
|
||||
hor_dis = sqrt(E * E + N * N);
|
||||
|
||||
if (hor_dis < 1.0E-20)
|
||||
{
|
||||
@ -689,8 +700,8 @@ void gps_l1_ca_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
}
|
||||
else
|
||||
{
|
||||
*Az = atan2(E, N)/dtr;
|
||||
*El = atan2(U, hor_dis)/dtr;
|
||||
*Az = atan2(E, N) / dtr;
|
||||
*El = atan2(U, hor_dis) / dtr;
|
||||
}
|
||||
|
||||
if (*Az < 0)
|
||||
@ -698,5 +709,106 @@ void gps_l1_ca_ls_pvt::topocent(double *Az, double *El, double *D, arma::vec x,
|
||||
*Az = *Az + 360.0;
|
||||
}
|
||||
|
||||
*D = sqrt(dx(0)*dx(0) + dx(1)*dx(1) + dx(2)*dx(2));
|
||||
*D = sqrt(dx(0) * dx(0) + dx(1) * dx(1) + dx(2) * dx(2));
|
||||
}
|
||||
|
||||
|
||||
void gps_l1_ca_ls_pvt::tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km)
|
||||
{
|
||||
/* Inputs:
|
||||
sinel - sin of elevation angle of satellite
|
||||
hsta_km - height of station in km
|
||||
p_mb - atmospheric pressure in mb at height hp_km
|
||||
t_kel - surface temperature in degrees Kelvin at height htkel_km
|
||||
hum - humidity in % at height hhum_km
|
||||
hp_km - height of pressure measurement in km
|
||||
htkel_km - height of temperature measurement in km
|
||||
hhum_km - height of humidity measurement in km
|
||||
|
||||
Outputs:
|
||||
ddr_m - range correction (meters)
|
||||
|
||||
Reference
|
||||
Goad, C.C. & Goodman, L. (1974) A Modified Hopfield Tropospheric
|
||||
Refraction Correction Model. Paper presented at the
|
||||
American Geophysical Union Annual Fall Meeting, San
|
||||
Francisco, December 12-17
|
||||
|
||||
Translated to C++ by Carles Fernandez from a Matlab implementation by Kai Borre
|
||||
*/
|
||||
|
||||
const double a_e = 6378.137; // semi-major axis of earth ellipsoid
|
||||
const double b0 = 7.839257e-5;
|
||||
const double tlapse = -6.5;
|
||||
const double em = -978.77 / (2.8704e6 * tlapse * 1.0e-5);
|
||||
|
||||
double tkhum = t_kel + tlapse * (hhum_km - htkel_km);
|
||||
double atkel = 7.5 * (tkhum - 273.15) / (237.3 + tkhum - 273.15);
|
||||
double e0 = 0.0611 * hum * pow(10, atkel);
|
||||
double tksea = t_kel - tlapse * htkel_km;
|
||||
double tkelh = tksea + tlapse * hhum_km;
|
||||
double e0sea = e0 * pow((tksea / tkelh), (4 * em));
|
||||
double tkelp = tksea + tlapse * hp_km;
|
||||
double psea = p_mb * pow((tksea / tkelp), em);
|
||||
|
||||
if(sinel < 0) { sinel = 0.0; }
|
||||
|
||||
double tropo_delay = 0.0;
|
||||
bool done = false;
|
||||
double refsea = 77.624e-6 / tksea;
|
||||
double htop = 1.1385e-5 / refsea;
|
||||
refsea = refsea * psea;
|
||||
double ref = refsea * pow(((htop - hsta_km) / htop), 4);
|
||||
|
||||
double a;
|
||||
double b;
|
||||
double rtop;
|
||||
|
||||
while(1)
|
||||
{
|
||||
rtop = pow((a_e + htop), 2) - pow((a_e + hsta_km), 2) * (1 - pow(sinel, 2));
|
||||
|
||||
// check to see if geometry is crazy
|
||||
if(rtop < 0) { rtop = 0; }
|
||||
|
||||
rtop = sqrt(rtop) - (a_e + hsta_km) * sinel;
|
||||
|
||||
a = -sinel / (htop - hsta_km);
|
||||
b = -b0 * (1 - pow(sinel,2)) / (htop - hsta_km);
|
||||
|
||||
arma::vec rn = arma::vec(8);
|
||||
rn.zeros();
|
||||
|
||||
for(int i = 0; i<8; i++)
|
||||
{
|
||||
rn(i) = pow(rtop, (i+1+1));
|
||||
|
||||
}
|
||||
|
||||
arma::rowvec alpha = {2 * a, 2 * pow(a, 2) + 4 * b /3, a * (pow(a, 2) + 3 * b),
|
||||
pow(a, 4)/5 + 2.4 * pow(a, 2) * b + 1.2 * pow(b, 2), 2 * a * b * (pow(a, 2) + 3 * b)/3,
|
||||
pow(b, 2) * (6 * pow(a, 2) + 4 * b) * 1.428571e-1, 0, 0};
|
||||
|
||||
if(pow(b, 2) > 1.0e-35)
|
||||
{
|
||||
alpha(6) = a * pow(b, 3) /2;
|
||||
alpha(7) = pow(b, 4) / 9;
|
||||
}
|
||||
|
||||
double dr = rtop;
|
||||
arma::mat aux_ = alpha * rn;
|
||||
dr = dr + aux_(0, 0);
|
||||
tropo_delay = tropo_delay + dr * ref * 1000;
|
||||
|
||||
if(done == true)
|
||||
{
|
||||
*ddr_m = tropo_delay;
|
||||
break;
|
||||
}
|
||||
|
||||
done = true;
|
||||
refsea = (371900.0e-6 / tksea - 12.92e-6) / tksea;
|
||||
htop = 1.1385e-5 * (1255 / tksea + 0.05) / refsea;
|
||||
ref = refsea * e0sea * pow(((htop - hsta_km) / htop), 4);
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ private:
|
||||
arma::vec rotateSatellite(double traveltime, arma::vec X_sat);
|
||||
void topocent(double *Az, double *El, double *D, arma::vec x, arma::vec dx);
|
||||
void togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z);
|
||||
void tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km);
|
||||
public:
|
||||
int d_nchannels; //!< Number of available channels for positioning
|
||||
int d_valid_observations; //!< Number of valid pseudorange observations (valid satellites)
|
||||
|
@ -23,9 +23,11 @@ if(OPENCL_FOUND)
|
||||
gps_l1_ca_pcps_assisted_acquisition.cc
|
||||
gps_l1_ca_pcps_acquisition_fine_doppler.cc
|
||||
gps_l1_ca_pcps_tong_acquisition.cc
|
||||
gps_l1_ca_pcps_quicksync_acquisition.cc
|
||||
gps_l1_ca_pcps_opencl_acquisition.cc
|
||||
galileo_e1_pcps_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_quicksync_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_tong_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_8ms_ambiguous_acquisition.cc
|
||||
)
|
||||
@ -36,8 +38,10 @@ else(OPENCL_FOUND)
|
||||
gps_l1_ca_pcps_assisted_acquisition.cc
|
||||
gps_l1_ca_pcps_acquisition_fine_doppler.cc
|
||||
gps_l1_ca_pcps_tong_acquisition.cc
|
||||
gps_l1_ca_pcps_quicksync_acquisition.cc
|
||||
galileo_e1_pcps_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_quicksync_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_tong_ambiguous_acquisition.cc
|
||||
galileo_e1_pcps_8ms_ambiguous_acquisition.cc
|
||||
)
|
||||
|
@ -0,0 +1,348 @@
|
||||
/*!
|
||||
* \file galileo_e1_pcps_quicksync_ambiguous_acquisition.cc
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||
* Galileo E1 Signals using the QuickSync Algorithm
|
||||
* \author Damian Miralles, 2014. dmiralles2009@gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "galileo_e1_pcps_quicksync_ambiguous_acquisition.h"
|
||||
#include <iostream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/math/distributions/exponential.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include <cmath>
|
||||
#include "galileo_e1_signal_processing.h"
|
||||
#include "Galileo_E1.h"
|
||||
#include "configuration_interface.h"
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcquisition(
|
||||
ConfigurationInterface* configuration, std::string role,
|
||||
unsigned int in_streams, unsigned int out_streams,
|
||||
boost::shared_ptr<gr::msg_queue> queue) :
|
||||
role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue)
|
||||
{
|
||||
configuration_ = configuration;
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string default_dump_filename = "../data/acquisition.dat";
|
||||
|
||||
DLOG(INFO) << "role " << role;
|
||||
|
||||
item_type_ = configuration_->property(role + ".item_type",
|
||||
default_item_type);
|
||||
|
||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000);
|
||||
if_ = configuration_->property(role + ".ifreq", 0);
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
shift_resolution_ = configuration_->property(role + ".doppler_max", 15);
|
||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 8);
|
||||
|
||||
/*--- Find number of samples per spreading code (4 ms) -----------------*/
|
||||
code_length_ = round(
|
||||
fs_in_
|
||||
/ (Galileo_E1_CODE_CHIP_RATE_HZ
|
||||
/ Galileo_E1_B_CODE_LENGTH_CHIPS));
|
||||
|
||||
int samples_per_ms = round(code_length_ / 4.0);
|
||||
|
||||
|
||||
/*Calculate the folding factor value based on the formula described in the paper.
|
||||
This may be a bug, but acquisition also work by variying the folding factor at va-
|
||||
lues different that the expressed in the paper. In adition, it is important to point
|
||||
out that by making the folding factor smaller we were able to get QuickSync work with
|
||||
Galileo. Future work should be directed to test this asumption statistically.*/
|
||||
|
||||
//folding_factor_ = (unsigned int)ceil(sqrt(log2(code_length_)));
|
||||
folding_factor_ = configuration_->property(role + ".folding_factor", 2);
|
||||
|
||||
if (sampled_ms_ % (folding_factor_*4) != 0)
|
||||
{
|
||||
LOG(WARNING) << "QuickSync Algorithm requires a coherent_integration_time"
|
||||
<< " multiple of "<<(folding_factor_*4)<<"ms, Value entered "
|
||||
<<sampled_ms_<<" ms";
|
||||
|
||||
if(sampled_ms_ < (folding_factor_*4))
|
||||
{
|
||||
sampled_ms_ = (int) (folding_factor_*4);
|
||||
}
|
||||
else
|
||||
{
|
||||
sampled_ms_ = (int)(sampled_ms_/(folding_factor_*4)) * (folding_factor_*4);
|
||||
}
|
||||
LOG(WARNING) << "coherent_integration_time should be multiple of "
|
||||
<< "Galileo code length (4 ms). coherent_integration_time = "
|
||||
<< sampled_ms_ << " ms will be used.";
|
||||
|
||||
}
|
||||
// vector_length_ = (sampled_ms_/folding_factor_) * code_length_;
|
||||
vector_length_ = sampled_ms_ * samples_per_ms;
|
||||
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||
|
||||
if (!bit_transition_flag_)
|
||||
{
|
||||
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
max_dwells_ = 2;
|
||||
}
|
||||
|
||||
dump_filename_ = configuration_->property(role + ".dump_filename",
|
||||
default_dump_filename);
|
||||
|
||||
code_ = new gr_complex[code_length_];
|
||||
LOG(INFO) <<"Vector Length: "<<vector_length_
|
||||
<<", Samples per ms: "<<samples_per_ms
|
||||
<<", Folding factor: "<<folding_factor_
|
||||
<<", Sampled ms: "<<sampled_ms_
|
||||
<<", Code Length: "<<code_length_;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
acquisition_cc_ = pcps_quicksync_make_acquisition_cc(folding_factor_,
|
||||
sampled_ms_, max_dwells_, shift_resolution_, if_, fs_in_,
|
||||
samples_per_ms, code_length_, bit_transition_flag_, queue_,
|
||||
dump_, dump_filename_);
|
||||
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_,
|
||||
vector_length_);
|
||||
DLOG(INFO) << "stream_to_vector_quicksync("
|
||||
<< stream_to_vector_->unique_id() << ")";
|
||||
DLOG(INFO) << "acquisition_quicksync(" << acquisition_cc_->unique_id()
|
||||
<< ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_
|
||||
<< " unknown acquisition item type";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::~GalileoE1PcpsQuickSyncAmbiguousAcquisition()
|
||||
{
|
||||
delete[] code_;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_channel(channel_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_threshold(float threshold)
|
||||
{
|
||||
|
||||
float pfa = configuration_->property(role_+ boost::lexical_cast<std::string>(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_;
|
||||
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_threshold(threshold_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_doppler_max(unsigned int doppler_max)
|
||||
{
|
||||
doppler_max_ = doppler_max;
|
||||
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_doppler_max(doppler_max_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_doppler_step(unsigned int doppler_step)
|
||||
{
|
||||
doppler_step_ = doppler_step;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_doppler_step(doppler_step_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_channel_queue(
|
||||
concurrent_queue<int> *channel_internal_queue)
|
||||
{
|
||||
channel_internal_queue_ = channel_internal_queue;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_channel_queue(channel_internal_queue_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_gnss_synchro(
|
||||
Gnss_Synchro* gnss_synchro)
|
||||
{
|
||||
gnss_synchro_ = gnss_synchro;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_gnss_synchro(gnss_synchro_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
signed int
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::mag()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
return acquisition_cc_->mag();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::init()
|
||||
{
|
||||
acquisition_cc_->init();
|
||||
set_local_code();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_local_code()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
bool cboc = configuration_->property(
|
||||
"Acquisition" + boost::lexical_cast<std::string>(channel_)
|
||||
+ ".cboc", false);
|
||||
|
||||
std::complex<float> * code = new std::complex<float>[code_length_];
|
||||
|
||||
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_/(folding_factor_*4)); i++)
|
||||
{
|
||||
memcpy(&(code_[i*code_length_]), code,
|
||||
sizeof(gr_complex)*code_length_);
|
||||
}
|
||||
|
||||
// memcpy(code_, code,sizeof(gr_complex)*code_length_);
|
||||
acquisition_cc_->set_local_code(code_);
|
||||
|
||||
delete[] code;
|
||||
code = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::reset()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_active(true);
|
||||
}
|
||||
}
|
||||
|
||||
float GalileoE1PcpsQuickSyncAmbiguousAcquisition::calculate_threshold(float pfa)
|
||||
{
|
||||
unsigned int frequency_bins = 0;
|
||||
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
|
||||
{
|
||||
frequency_bins++;
|
||||
}
|
||||
|
||||
DLOG(INFO) <<"Channel "<<channel_<<" Pfa = "<< pfa;
|
||||
|
||||
unsigned int ncells = code_length_/folding_factor_ * frequency_bins;
|
||||
double exponent = 1 / (double)ncells;
|
||||
double val = pow(1.0 - pfa, exponent);
|
||||
double lambda = double(code_length_/folding_factor_);
|
||||
boost::math::exponential_distribution<double> mydist (lambda);
|
||||
float threshold = (float)quantile(mydist,val);
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GalileoE1PcpsQuickSyncAmbiguousAcquisition::get_left_block()
|
||||
{
|
||||
return stream_to_vector_;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GalileoE1PcpsQuickSyncAmbiguousAcquisition::get_right_block()
|
||||
{
|
||||
return acquisition_cc_;
|
||||
}
|
||||
|
@ -0,0 +1,163 @@
|
||||
/*!
|
||||
* \file galileo_e1_pcps_quicksync_ambiguous_acquisition.h
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for Galileo E1 Signals
|
||||
* \date June, 2014
|
||||
* \author Damian Miralles Sanchez. dmiralles2009@gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H_
|
||||
#define GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H_
|
||||
|
||||
#include <string>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/blocks/stream_to_vector.h>
|
||||
#include "gnss_synchro.h"
|
||||
#include "acquisition_interface.h"
|
||||
#include "pcps_quicksync_acquisition_cc.h"
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class adapts a PCPS acquisition block to an
|
||||
* AcquisitionInterface for Galileo E1 Signals
|
||||
*/
|
||||
class GalileoE1PcpsQuickSyncAmbiguousAcquisition: public AcquisitionInterface
|
||||
{
|
||||
public:
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisition(ConfigurationInterface* configuration,
|
||||
std::string role, unsigned int in_streams,
|
||||
unsigned int out_streams, boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
virtual ~GalileoE1PcpsQuickSyncAmbiguousAcquisition();
|
||||
|
||||
std::string role()
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition"
|
||||
*/
|
||||
std::string implementation()
|
||||
{
|
||||
return "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition";
|
||||
}
|
||||
size_t item_size()
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
void connect(gr::top_block_sptr top_block);
|
||||
void disconnect(gr::top_block_sptr top_block);
|
||||
gr::basic_block_sptr get_left_block();
|
||||
gr::basic_block_sptr get_right_block();
|
||||
|
||||
/*!
|
||||
* \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);
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition channel unique ID
|
||||
*/
|
||||
void set_channel(unsigned int channel);
|
||||
|
||||
/*!
|
||||
* \brief Set statistics threshold of PCPS algorithm
|
||||
*/
|
||||
void set_threshold(float threshold);
|
||||
|
||||
/*!
|
||||
* \brief Set maximum Doppler off grid search
|
||||
*/
|
||||
void set_doppler_max(unsigned int doppler_max);
|
||||
|
||||
/*!
|
||||
* \brief Set Doppler steps for the grid search
|
||||
*/
|
||||
void set_doppler_step(unsigned int doppler_step);
|
||||
|
||||
/*!
|
||||
* \brief Set tracking channel internal queue
|
||||
*/
|
||||
void set_channel_queue(concurrent_queue<int> *channel_internal_queue);
|
||||
|
||||
/*!
|
||||
* \brief Initializes acquisition algorithm.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/*!
|
||||
* \brief Sets local code for Galileo E1 PCPS acquisition algorithm.
|
||||
*/
|
||||
void set_local_code();
|
||||
|
||||
/*!
|
||||
* \brief Returns the maximum peak of grid search
|
||||
*/
|
||||
signed int mag();
|
||||
|
||||
/*!
|
||||
* \brief Restart acquisition algorithm
|
||||
*/
|
||||
void reset();
|
||||
|
||||
private:
|
||||
ConfigurationInterface* configuration_;
|
||||
pcps_quicksync_acquisition_cc_sptr acquisition_cc_;
|
||||
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
||||
size_t item_size_;
|
||||
std::string item_type_;
|
||||
unsigned int vector_length_;
|
||||
unsigned int code_length_;
|
||||
bool bit_transition_flag_;
|
||||
unsigned int channel_;
|
||||
float threshold_;
|
||||
unsigned int doppler_max_;
|
||||
unsigned int doppler_step_;
|
||||
unsigned int shift_resolution_;
|
||||
unsigned int sampled_ms_;
|
||||
unsigned int max_dwells_;
|
||||
unsigned int folding_factor_;
|
||||
long fs_in_;
|
||||
long if_;
|
||||
bool dump_;
|
||||
std::string dump_filename_;
|
||||
std::complex<float> * code_;
|
||||
Gnss_Synchro * gnss_synchro_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
concurrent_queue<int> *channel_internal_queue_;
|
||||
float calculate_threshold(float pfa);
|
||||
};
|
||||
|
||||
#endif /* GNSS_SDR_GALILEO_E1_PCPS_QUICKSYNC_AMBIGUOUS_ACQUISITION_H_ */
|
@ -0,0 +1,330 @@
|
||||
/*!
|
||||
* \file gps_l1_ca_pcps_quicksync_acquisition.cc
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
|
||||
* GPS L1 C/A signals using the QuickSync Algorithm
|
||||
* \author Damian Miralles, 2014. dmiralles2009@gmail.com
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "gps_l1_ca_pcps_quicksync_acquisition.h"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
#include <boost/math/distributions/exponential.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include "gps_sdr_signal_processing.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include "configuration_interface.h"
|
||||
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition(
|
||||
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)
|
||||
{
|
||||
configuration_ = configuration;
|
||||
std::string default_item_type = "gr_complex";
|
||||
std::string default_dump_filename = "./data/acquisition.dat";
|
||||
|
||||
DLOG(INFO) << "role " << role;
|
||||
|
||||
item_type_ = configuration_->property(role + ".item_type", default_item_type);
|
||||
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000);
|
||||
if_ = configuration_->property(role + ".ifreq", 0);
|
||||
dump_ = configuration_->property(role + ".dump", false);
|
||||
shift_resolution_ = configuration_->property(role + ".doppler_max", 15);
|
||||
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 4);
|
||||
|
||||
|
||||
//--- Find number of samples per spreading code -------------------------
|
||||
code_length_ = round(fs_in_
|
||||
/ (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
|
||||
|
||||
|
||||
/*Calculate the folding factor value based on the calculations*/
|
||||
unsigned int temp = (unsigned int)ceil(sqrt(log2(code_length_)));
|
||||
folding_factor_ = configuration_->property(role + ".folding_factor", temp);
|
||||
|
||||
if ( sampled_ms_ % folding_factor_ != 0)
|
||||
{
|
||||
LOG(WARNING) << "QuickSync Algorithm requires a coherent_integration_time"
|
||||
<< " multiple of " << folding_factor_ << "ms, Value entered "
|
||||
<< sampled_ms_ << " ms";
|
||||
if(sampled_ms_ < folding_factor_)
|
||||
{
|
||||
sampled_ms_ = (int) folding_factor_;
|
||||
}
|
||||
else
|
||||
{
|
||||
sampled_ms_ = (int)(sampled_ms_/folding_factor_) * folding_factor_;
|
||||
}
|
||||
|
||||
LOG(WARNING) <<" Coherent_integration_time of "
|
||||
<< sampled_ms_ << " ms will be used instead.";
|
||||
|
||||
}
|
||||
vector_length_ = code_length_ * sampled_ms_;
|
||||
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
|
||||
|
||||
if (!bit_transition_flag_)
|
||||
{
|
||||
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
max_dwells_ = 2;
|
||||
}
|
||||
|
||||
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
|
||||
|
||||
int samples_per_ms = round(code_length_);
|
||||
code_= new gr_complex[code_length_];
|
||||
/*Object relevant information for debugging*/
|
||||
LOG(INFO) <<"Implementation: "<<this->implementation()
|
||||
<<", Vector Length: "<<vector_length_
|
||||
<<", Samples per ms: "<<samples_per_ms
|
||||
<<", Folding factor: "<<folding_factor_
|
||||
<<", Sampled ms: "<<sampled_ms_
|
||||
<<", Code Length: "<<code_length_;
|
||||
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
acquisition_cc_ = pcps_quicksync_make_acquisition_cc(folding_factor_,
|
||||
sampled_ms_, max_dwells_,shift_resolution_, if_, fs_in_,
|
||||
samples_per_ms, code_length_,bit_transition_flag_, queue_,
|
||||
dump_, dump_filename_);
|
||||
|
||||
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_,
|
||||
code_length_*folding_factor_);
|
||||
|
||||
DLOG(INFO) << "stream_to_vector_quicksync(" << stream_to_vector_->unique_id() << ")";
|
||||
DLOG(INFO) << "acquisition(" << acquisition_cc_->unique_id() << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_ << " unknown acquisition item type";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
GpsL1CaPcpsQuickSyncAcquisition::~GpsL1CaPcpsQuickSyncAcquisition()
|
||||
{
|
||||
delete[] code_;
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_channel(unsigned int channel)
|
||||
{
|
||||
channel_ = channel;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_channel(channel_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_threshold(float threshold)
|
||||
{
|
||||
float pfa = configuration_->property(role_ +
|
||||
boost::lexical_cast<std::string>(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_;
|
||||
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_threshold(threshold_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_doppler_max(unsigned int doppler_max)
|
||||
{
|
||||
doppler_max_ = doppler_max;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_doppler_max(doppler_max_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_doppler_step(unsigned int doppler_step)
|
||||
{
|
||||
doppler_step_ = doppler_step;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_doppler_step(doppler_step_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_channel_queue(
|
||||
concurrent_queue<int> *channel_internal_queue)
|
||||
{
|
||||
channel_internal_queue_ = channel_internal_queue;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_channel_queue(channel_internal_queue_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_gnss_synchro(Gnss_Synchro* gnss_synchro)
|
||||
{
|
||||
gnss_synchro_ = gnss_synchro;
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_gnss_synchro(gnss_synchro_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
signed int GpsL1CaPcpsQuickSyncAcquisition::mag()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
return acquisition_cc_->mag();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::init()
|
||||
{
|
||||
acquisition_cc_->init();
|
||||
set_local_code();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::set_local_code()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
std::complex<float>* code = new std::complex<float>[code_length_];
|
||||
|
||||
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0);
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < (sampled_ms_/folding_factor_); i++)
|
||||
{
|
||||
memcpy(&(code_[i*code_length_]), code,
|
||||
sizeof(gr_complex)*code_length_);
|
||||
}
|
||||
|
||||
//memcpy(code_, code,sizeof(gr_complex)*code_length_);
|
||||
acquisition_cc_->set_local_code(code_);
|
||||
|
||||
delete[] code;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::reset()
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
acquisition_cc_->set_active(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float GpsL1CaPcpsQuickSyncAcquisition::calculate_threshold(float pfa)
|
||||
{
|
||||
//Calculate the threshold
|
||||
unsigned int frequency_bins = 0;
|
||||
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
|
||||
{
|
||||
frequency_bins++;
|
||||
}
|
||||
DLOG(INFO) << "Channel " << channel_<< " Pfa = " << pfa;
|
||||
unsigned int ncells = (code_length_/folding_factor_)*frequency_bins;
|
||||
double exponent = 1/(double)ncells;
|
||||
double val = pow(1.0 - pfa, exponent);
|
||||
double lambda = double((code_length_/folding_factor_));
|
||||
boost::math::exponential_distribution<double> mydist (lambda);
|
||||
float threshold = (float)quantile(mydist,val);
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
top_block->connect(stream_to_vector_, 0, acquisition_cc_, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisition::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (item_type_.compare("gr_complex") == 0)
|
||||
{
|
||||
top_block->disconnect(stream_to_vector_, 0, acquisition_cc_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GpsL1CaPcpsQuickSyncAcquisition::get_left_block()
|
||||
{
|
||||
return stream_to_vector_;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr GpsL1CaPcpsQuickSyncAcquisition::get_right_block()
|
||||
{
|
||||
return acquisition_cc_;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,169 @@
|
||||
/*!
|
||||
* \file gps_l1_ca_pcps_quicksync_acquisition.h
|
||||
* \brief Adapts a PCPS acquisition block to an AcquisitionInterface for GPS L1 C/A signals implementing the QuickSync Algorithm.
|
||||
* \date June, 2014
|
||||
* \author Damian Miralles Sanchez. dmiralles2009@gmail.com
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H_
|
||||
#define GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H_
|
||||
|
||||
#include <string>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/blocks/stream_to_vector.h>
|
||||
#include "gnss_synchro.h"
|
||||
#include "acquisition_interface.h"
|
||||
#include "pcps_quicksync_acquisition_cc.h"
|
||||
#include "configuration_interface.h"
|
||||
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class adapts a PCPS acquisition block to an AcquisitionInterface
|
||||
* for GPS L1 C/A signals
|
||||
*/
|
||||
class GpsL1CaPcpsQuickSyncAcquisition: public AcquisitionInterface
|
||||
{
|
||||
public:
|
||||
GpsL1CaPcpsQuickSyncAcquisition(ConfigurationInterface* configuration,
|
||||
std::string role, unsigned int in_streams,
|
||||
unsigned int out_streams, boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
virtual ~GpsL1CaPcpsQuickSyncAcquisition();
|
||||
|
||||
std::string role()
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "GPS_L1_CA_PCPS_QuickSync_Acquisition"
|
||||
*/
|
||||
std::string implementation()
|
||||
{
|
||||
return "GPS_L1_CA_PCPS_QuickSync_Acquisition";
|
||||
}
|
||||
size_t item_size()
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
void connect(gr::top_block_sptr top_block);
|
||||
void disconnect(gr::top_block_sptr top_block);
|
||||
gr::basic_block_sptr get_left_block();
|
||||
gr::basic_block_sptr get_right_block();
|
||||
|
||||
/*!
|
||||
* \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);
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition channel unique ID
|
||||
*/
|
||||
void set_channel(unsigned int channel);
|
||||
|
||||
/*!
|
||||
* \brief Set statistics threshold of PCPS algorithm
|
||||
*/
|
||||
void set_threshold(float threshold);
|
||||
|
||||
/*!
|
||||
* \brief Set maximum Doppler off grid search
|
||||
*/
|
||||
void set_doppler_max(unsigned int doppler_max);
|
||||
|
||||
/*!
|
||||
* \brief Set Doppler steps for the grid search
|
||||
*/
|
||||
void set_doppler_step(unsigned int doppler_step);
|
||||
|
||||
/*!
|
||||
* \brief Set tracking channel internal queue
|
||||
*/
|
||||
void set_channel_queue(concurrent_queue<int> *channel_internal_queue);
|
||||
|
||||
/*!
|
||||
* \brief Initializes acquisition algorithm.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/*!
|
||||
* \brief Sets local code for GPS L1/CA PCPS acquisition algorithm.
|
||||
*/
|
||||
void set_local_code();
|
||||
|
||||
/*!
|
||||
* \brief Returns the maximum peak of grid search
|
||||
*/
|
||||
signed int mag();
|
||||
|
||||
/*!
|
||||
* \brief Restart acquisition algorithm
|
||||
*/
|
||||
void reset();
|
||||
|
||||
|
||||
private:
|
||||
ConfigurationInterface* configuration_;
|
||||
pcps_quicksync_acquisition_cc_sptr acquisition_cc_;
|
||||
gr::blocks::stream_to_vector::sptr stream_to_vector_;
|
||||
size_t item_size_;
|
||||
std::string item_type_;
|
||||
unsigned int vector_length_;
|
||||
unsigned int code_length_;
|
||||
bool bit_transition_flag_;
|
||||
unsigned int channel_;
|
||||
float threshold_;
|
||||
unsigned int doppler_max_;
|
||||
unsigned int doppler_step_;
|
||||
unsigned int shift_resolution_;
|
||||
unsigned int sampled_ms_;
|
||||
unsigned int max_dwells_;
|
||||
unsigned int folding_factor_;
|
||||
long fs_in_;
|
||||
long if_;
|
||||
bool dump_;
|
||||
std::string dump_filename_;
|
||||
std::complex<float> * code_;
|
||||
Gnss_Synchro * gnss_synchro_;
|
||||
std::string role_;
|
||||
unsigned int in_streams_;
|
||||
unsigned int out_streams_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
concurrent_queue<int> *channel_internal_queue_;
|
||||
|
||||
float calculate_threshold(float pfa);
|
||||
|
||||
};
|
||||
|
||||
#endif /* GNSS_SDR_GPS_L1_CA_PCPS_QUICKSYNC_ACQUISITION_H_ */
|
@ -24,6 +24,7 @@ if(OPENCL_FOUND)
|
||||
pcps_acquisition_fine_doppler_cc.cc
|
||||
pcps_tong_acquisition_cc.cc
|
||||
pcps_cccwsr_acquisition_cc.cc
|
||||
pcps_quicksync_acquisition_cc.cc
|
||||
galileo_pcps_8ms_acquisition_cc.cc
|
||||
pcps_opencl_acquisition_cc.cc # Needs OpenCL
|
||||
)
|
||||
@ -35,6 +36,7 @@ else(OPENCL_FOUND)
|
||||
pcps_acquisition_fine_doppler_cc.cc
|
||||
pcps_tong_acquisition_cc.cc
|
||||
pcps_cccwsr_acquisition_cc.cc
|
||||
pcps_quicksync_acquisition_cc.cc
|
||||
galileo_pcps_8ms_acquisition_cc.cc
|
||||
)
|
||||
endif(OPENCL_FOUND)
|
||||
|
@ -0,0 +1,596 @@
|
||||
/*!
|
||||
* \file pcps_quicksync_acquisition_cc.cc
|
||||
* \brief This class implements a Parallel Code Phase Search Acquisition
|
||||
* \author Damian Miralles Sanchez, 2014. dmiralles2009(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "pcps_quicksync_acquisition_cc.h"
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <glog/logging.h>
|
||||
#include <volk/volk.h>
|
||||
#include "control_message_factory.h"
|
||||
#include "gnss_signal_processing.h"
|
||||
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
pcps_quicksync_acquisition_cc_sptr pcps_quicksync_make_acquisition_cc(
|
||||
unsigned int folding_factor,
|
||||
unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename)
|
||||
{
|
||||
|
||||
return pcps_quicksync_acquisition_cc_sptr(
|
||||
new pcps_quicksync_acquisition_cc(
|
||||
folding_factor,
|
||||
sampled_ms, max_dwells, doppler_max,
|
||||
freq, fs_in, samples_per_ms,
|
||||
samples_per_code,
|
||||
bit_transition_flag,
|
||||
queue, dump, dump_filename));
|
||||
}
|
||||
|
||||
pcps_quicksync_acquisition_cc::pcps_quicksync_acquisition_cc(
|
||||
unsigned int folding_factor,
|
||||
unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename):
|
||||
gr::block("pcps_quicksync_acquisition_cc",
|
||||
gr::io_signature::make(1, 1, (sizeof(gr_complex)*sampled_ms * samples_per_ms )),
|
||||
gr::io_signature::make(0, 0, (sizeof(gr_complex)*sampled_ms * samples_per_ms )))
|
||||
{
|
||||
//DLOG(INFO) << "START CONSTRUCTOR";
|
||||
|
||||
d_sample_counter = 0; // SAMPLE COUNTER
|
||||
d_active = false;
|
||||
d_state = 0;
|
||||
d_queue = queue;
|
||||
d_freq = freq;
|
||||
d_fs_in = fs_in;
|
||||
d_samples_per_ms = samples_per_ms;
|
||||
d_samples_per_code = samples_per_code;
|
||||
d_sampled_ms = sampled_ms;
|
||||
d_max_dwells = max_dwells;
|
||||
d_well_count = 0;
|
||||
d_doppler_max = doppler_max;
|
||||
d_mag = 0;
|
||||
d_input_power = 0.0;
|
||||
d_num_doppler_bins = 0;
|
||||
d_bit_transition_flag = bit_transition_flag;
|
||||
d_folding_factor = folding_factor;
|
||||
|
||||
//fft size is reduced.
|
||||
d_fft_size = (d_samples_per_code) / d_folding_factor;
|
||||
|
||||
|
||||
//todo: do something if posix_memalign fails
|
||||
if (posix_memalign((void**)&d_fft_codes, 16, d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude, 16, d_samples_per_code * d_folding_factor * sizeof(float)) == 0){};
|
||||
if (posix_memalign((void**)&d_magnitude_folded, 16, d_fft_size * sizeof(float)) == 0){};
|
||||
|
||||
d_possible_delay = new unsigned int[d_folding_factor];
|
||||
d_corr_output_f = new float[d_folding_factor];
|
||||
|
||||
/*Create the d_code signal , which would store the values of the code in its
|
||||
original form to perform later correlation in time domain*/
|
||||
d_code = new gr_complex[d_samples_per_code]();
|
||||
|
||||
|
||||
// Direct FFT
|
||||
d_fft_if = new gr::fft::fft_complex(d_fft_size, true);
|
||||
// Inverse FFT
|
||||
d_ifft = new gr::fft::fft_complex(d_fft_size, false);
|
||||
|
||||
// For dumping samples into a file
|
||||
d_dump = dump;
|
||||
d_dump_filename = dump_filename;
|
||||
|
||||
// DLOG(INFO) << "END CONSTRUCTOR";
|
||||
}
|
||||
|
||||
pcps_quicksync_acquisition_cc::~pcps_quicksync_acquisition_cc()
|
||||
{
|
||||
//DLOG(INFO) << "START DESTROYER";
|
||||
if (d_num_doppler_bins > 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < d_num_doppler_bins; i++)
|
||||
{
|
||||
free(d_grid_doppler_wipeoffs[i]);
|
||||
}
|
||||
delete[] d_grid_doppler_wipeoffs;
|
||||
}
|
||||
|
||||
free(d_fft_codes);
|
||||
free(d_magnitude);
|
||||
free(d_magnitude_folded);
|
||||
|
||||
delete d_ifft;
|
||||
d_ifft = NULL;
|
||||
delete d_fft_if;
|
||||
d_fft_if = NULL;
|
||||
delete d_code;
|
||||
d_code = NULL;
|
||||
delete d_possible_delay;
|
||||
d_possible_delay = NULL;
|
||||
delete d_corr_output_f;
|
||||
d_corr_output_f = NULL;
|
||||
if (d_dump)
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
// DLOG(INFO) << "END DESTROYER";
|
||||
}
|
||||
|
||||
void pcps_quicksync_acquisition_cc::set_local_code(std::complex<float> * code)
|
||||
{
|
||||
// DLOG(INFO) << "START LOCAL CODE";
|
||||
|
||||
|
||||
/*save a local copy of the code without the folding process to perform corre-
|
||||
lation in time in the final steps of the acquisition stage*/
|
||||
memcpy(d_code, code, sizeof(gr_complex)*d_samples_per_code);
|
||||
|
||||
d_code_folded = new gr_complex[d_fft_size]();
|
||||
memcpy(d_fft_if->get_inbuf(), d_code_folded, sizeof(gr_complex)*(d_fft_size));
|
||||
|
||||
/*perform folding of the code by the factorial factor parameter. Notice that
|
||||
folding of the code in the time stage would result in a downsampled spectrum
|
||||
in the frequency domain after applying the fftw operation*/
|
||||
for (unsigned int i = 0; i < d_folding_factor; i++)
|
||||
{
|
||||
std::transform ((code + i*d_fft_size), (code + ((i+1)*d_fft_size)) ,
|
||||
d_fft_if->get_inbuf(), d_fft_if->get_inbuf(),
|
||||
std::plus<gr_complex>());
|
||||
}
|
||||
|
||||
|
||||
d_fft_if->execute(); // We need the FFT of local code
|
||||
|
||||
//Conjugate the local code
|
||||
if (is_unaligned())
|
||||
{
|
||||
volk_32fc_conjugate_32fc_u(d_fft_codes,d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
volk_32fc_conjugate_32fc_a(d_fft_codes,d_fft_if->get_outbuf(), d_fft_size);
|
||||
}
|
||||
// DLOG(INFO) << "END LOCAL CODE";
|
||||
|
||||
}
|
||||
|
||||
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_mag = 0.0;
|
||||
d_input_power = 0.0;
|
||||
|
||||
// Count the number of bins
|
||||
d_num_doppler_bins = 0;
|
||||
for (int doppler = (int)(-d_doppler_max);
|
||||
doppler <= (int)(d_doppler_max);
|
||||
doppler += d_doppler_step)
|
||||
{
|
||||
d_num_doppler_bins++;
|
||||
}
|
||||
|
||||
// Create the carrier Doppler wipeoff signals
|
||||
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins];
|
||||
for (unsigned int doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
|
||||
{
|
||||
if (posix_memalign((void**)&(d_grid_doppler_wipeoffs[doppler_index]), 16,
|
||||
d_samples_per_code * d_folding_factor * sizeof(gr_complex)) == 0){};
|
||||
|
||||
int doppler = -(int)d_doppler_max + d_doppler_step*doppler_index;
|
||||
complex_exp_gen_conj(d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_freq + doppler, d_fs_in,
|
||||
d_samples_per_code * d_folding_factor);
|
||||
}
|
||||
// DLOG(INFO) << "end init";
|
||||
}
|
||||
|
||||
int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
|
||||
gr_vector_int &ninput_items, gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
/*
|
||||
* By J.Arribas, L.Esteve and M.Molina
|
||||
* Acquisition strategy (Kay Borre book + CFAR threshold):
|
||||
* 1. Compute the input signal power estimation
|
||||
* 2. Doppler serial search loop
|
||||
* 3. Perform the FFT-based circular convolution (parallel time search)
|
||||
* 4. Record the maximum peak and the associated synchronization parameters
|
||||
* 5. Compute the test statistics and compare to the threshold
|
||||
* 6. Declare positive or negative acquisition using a message queue
|
||||
*/
|
||||
//DLOG(INFO) << "START GENERAL WORK";
|
||||
int acquisition_message = -1; //0=STOP_CHANNEL 1=ACQ_SUCCEES 2=ACQ_FAIL
|
||||
//std::cout<<"general_work in quicksync gnuradio block"<<std::endl;
|
||||
switch (d_state)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
//DLOG(INFO) << "START CASE 0";
|
||||
if (d_active)
|
||||
{
|
||||
//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_mag = 0.0;
|
||||
d_input_power = 0.0;
|
||||
d_test_statistics = 0.0;
|
||||
|
||||
d_state = 1;
|
||||
}
|
||||
|
||||
d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter
|
||||
consume_each(ninput_items[0]);
|
||||
//DLOG(INFO) << "END CASE 0";
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
/* initialize acquisition implementing the QuickSync algorithm*/
|
||||
//DLOG(INFO) << "START CASE 1";
|
||||
int doppler;
|
||||
unsigned int indext = 0;
|
||||
float magt = 0.0;
|
||||
const gr_complex *in = (const gr_complex *)input_items[0]; //Get the input samples pointer
|
||||
|
||||
gr_complex *in_temp;
|
||||
if (posix_memalign((void**)&(in_temp), 16,d_samples_per_code * d_folding_factor * sizeof(gr_complex)) == 0){};
|
||||
|
||||
|
||||
gr_complex *in_temp_folded;
|
||||
if (posix_memalign((void**)&(in_temp_folded), 16,d_fft_size * sizeof(gr_complex)) == 0){};
|
||||
|
||||
/*Create a signal to store a signal of size 1ms, to perform correlation
|
||||
in time. No folding on this data is required*/
|
||||
gr_complex *in_1code;
|
||||
if (posix_memalign((void**)&(in_1code), 16,d_samples_per_code * sizeof(gr_complex)) == 0){};
|
||||
|
||||
/*Stores the values of the correlation output between the local code
|
||||
and the signal with doppler shift corrected */
|
||||
gr_complex *corr_output;
|
||||
if (posix_memalign((void**)&(corr_output), 16,d_samples_per_code * sizeof(gr_complex)) == 0){};
|
||||
|
||||
/*Stores a copy of the folded version of the signal.This is used for
|
||||
the FFT operations in future steps of excecution*/
|
||||
// gr_complex in_folded[d_fft_size];
|
||||
float fft_normalization_factor = (float)d_fft_size * (float)d_fft_size;
|
||||
|
||||
d_input_power = 0.0;
|
||||
d_mag = 0.0;
|
||||
d_test_statistics = 0.0;
|
||||
d_noise_floor_power = 0.0;
|
||||
|
||||
d_sample_counter += d_sampled_ms * d_samples_per_ms; // sample counter
|
||||
|
||||
d_well_count++;
|
||||
|
||||
DLOG(INFO) << "Channel: " << d_channel
|
||||
<< " , doing acquisition of satellite: "
|
||||
<< d_gnss_synchro->System << " "<< d_gnss_synchro->PRN
|
||||
<< " ,algorithm: pcps_quicksync_acquisition"
|
||||
<< " ,folding factor: " << d_folding_factor
|
||||
<< " ,sample stamp: " << d_sample_counter << ", threshold: "
|
||||
<< d_threshold << ", doppler_max: " << d_doppler_max
|
||||
<< ", doppler_step: " << d_doppler_step << ", Signal Size: "
|
||||
<< d_samples_per_code * d_folding_factor;
|
||||
|
||||
|
||||
/* 1- Compute the input signal power estimation. This operation is
|
||||
being performed in a signal of size nxp */
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude, in, d_samples_per_code * d_folding_factor);
|
||||
volk_32f_accumulator_s32f_a(&d_input_power, d_magnitude, d_samples_per_code * d_folding_factor);
|
||||
d_input_power /= (float)(d_samples_per_code * d_folding_factor);
|
||||
|
||||
|
||||
|
||||
for (unsigned int doppler_index=0;doppler_index<d_num_doppler_bins;doppler_index++)
|
||||
{
|
||||
/*Ensure that the signal is going to start with all samples
|
||||
at zero. This is done to avoid over acumulation when performing
|
||||
the folding process to be stored in d_fft_if->get_inbuf()*/
|
||||
d_signal_folded = new gr_complex[d_fft_size]();
|
||||
memcpy( d_fft_if->get_inbuf(),d_signal_folded,
|
||||
sizeof(gr_complex)*(d_fft_size));
|
||||
|
||||
/*Doppler search steps and then multiplication of the incoming
|
||||
signal with the doppler wipeoffs to eliminate frequency offset
|
||||
*/
|
||||
doppler=-(int)d_doppler_max+d_doppler_step*doppler_index;
|
||||
|
||||
/*Perform multiplication of the incoming signal with the
|
||||
complex exponential vector. This removes the frequency doppler
|
||||
shift offset*/
|
||||
volk_32fc_x2_multiply_32fc_a(in_temp, in,
|
||||
d_grid_doppler_wipeoffs[doppler_index],
|
||||
d_samples_per_code * d_folding_factor);
|
||||
|
||||
/*Perform folding of the carrier wiped-off incoming signal. Since
|
||||
superlinear method is being used the folding factor in the
|
||||
incoming raw data signal is of d_folding_factor^2*/
|
||||
for ( int i = 0; i < (int)(d_folding_factor*d_folding_factor); i++)
|
||||
{
|
||||
std::transform ((in_temp+i*d_fft_size),
|
||||
(in_temp+((i+1)*d_fft_size)) ,
|
||||
d_fft_if->get_inbuf(),
|
||||
d_fft_if->get_inbuf(),
|
||||
std::plus<gr_complex>());
|
||||
}
|
||||
|
||||
/* 3- 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*/
|
||||
volk_32fc_x2_multiply_32fc_a(d_ifft->get_inbuf(),
|
||||
d_fft_if->get_outbuf(), d_fft_codes, d_fft_size);
|
||||
|
||||
/* compute the inverse FFT of the aliased signal*/
|
||||
d_ifft->execute();
|
||||
|
||||
/* Compute the magnitude and get the maximum value with its
|
||||
index position*/
|
||||
volk_32fc_magnitude_squared_32f_a(d_magnitude_folded,
|
||||
d_ifft->get_outbuf(), d_fft_size);
|
||||
|
||||
/* Normalize the maximum value to correct the scale factor
|
||||
introduced by FFTW*/
|
||||
//volk_32f_s32f_multiply_32f_a(d_magnitude_folded,d_magnitude_folded,
|
||||
// (1 / (fft_normalization_factor * fft_normalization_factor)), d_fft_size);
|
||||
volk_32f_index_max_16u_a(&indext, d_magnitude_folded, d_fft_size);
|
||||
|
||||
magt = d_magnitude_folded[indext]/ (fft_normalization_factor * fft_normalization_factor);
|
||||
|
||||
delete d_signal_folded;
|
||||
|
||||
// 4- record the maximum peak and the associated synchronization parameters
|
||||
if (d_mag < magt)
|
||||
{
|
||||
d_mag = magt;
|
||||
|
||||
/* In case that d_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) || !d_bit_transition_flag)
|
||||
{
|
||||
unsigned int detected_delay_samples_folded = 0;
|
||||
detected_delay_samples_folded = (indext % d_samples_per_code);
|
||||
//float d_corr_output_f[d_folding_factor];
|
||||
gr_complex complex_acumulator[100];
|
||||
//gr_complex complex_acumulator[d_folding_factor];
|
||||
//const int ff = d_folding_factor;
|
||||
//gr_complex complex_acumulator[ff];
|
||||
//gr_complex complex_acumulator[];
|
||||
//complex_acumulator = new gr_complex[d_folding_factor]();
|
||||
|
||||
for (int i = 0; i < (int)d_folding_factor; i++)
|
||||
{
|
||||
d_possible_delay[i]= detected_delay_samples_folded+
|
||||
(i)*d_fft_size;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < (int)d_folding_factor; i++)
|
||||
{
|
||||
|
||||
/*Copy a signal of 1 code length into suggested buffer.
|
||||
The copied signal must have doppler effect corrected*/
|
||||
memcpy(in_1code,&in_temp[d_possible_delay[i]],
|
||||
sizeof(gr_complex)*(d_samples_per_code));
|
||||
|
||||
/*Perform multiplication of the unmodified local
|
||||
generated code with the incoming signal with doppler
|
||||
effect corrected and accumulates its value. This
|
||||
is indeed correlation in time for an specific value
|
||||
of a shift*/
|
||||
volk_32fc_x2_multiply_32fc_a(corr_output, in_1code,
|
||||
d_code, d_samples_per_code);
|
||||
|
||||
for(int j=0; j < (d_samples_per_code); j++)
|
||||
{
|
||||
complex_acumulator[i] += (corr_output[j]);
|
||||
}
|
||||
|
||||
}
|
||||
/*Obtain maximun value of correlation given the
|
||||
possible delay selected */
|
||||
volk_32fc_magnitude_squared_32f_a(d_corr_output_f,
|
||||
complex_acumulator, d_folding_factor);
|
||||
volk_32f_index_max_16u_a(&indext, d_corr_output_f,
|
||||
d_folding_factor);
|
||||
|
||||
/*Now save the real code phase in the gnss_syncro
|
||||
block for use in other stages*/
|
||||
d_gnss_synchro->Acq_delay_samples = (double)
|
||||
(d_possible_delay[indext]);
|
||||
d_gnss_synchro->Acq_doppler_hz = (double)doppler;
|
||||
d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter;
|
||||
|
||||
|
||||
/* 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;
|
||||
//delete complex_acumulator;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Record results to file if required
|
||||
if (d_dump)
|
||||
{
|
||||
/*
|
||||
std::stringstream filename;
|
||||
std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write
|
||||
filename.str("");
|
||||
filename << "../data/test_statistics_" << d_gnss_synchro->System
|
||||
<<"_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
d_dump_file.write((char*)d_ifft->get_outbuf(), n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
d_dump_file.close();
|
||||
*/
|
||||
/*Since QuickSYnc performs a folded correlation in frequency by means
|
||||
of the FFT, it is esential to also keep the values obtained from the
|
||||
possible delay to show how it is maximize*/
|
||||
std::stringstream filename;
|
||||
std::streamsize n = sizeof(float) * (d_fft_size); // complex file write
|
||||
filename.str("");
|
||||
filename << "../data/test_statistics_" << d_gnss_synchro->System
|
||||
<<"_" << d_gnss_synchro->Signal << "_sat_"
|
||||
<< d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat";
|
||||
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
|
||||
d_dump_file.write((char*)d_magnitude_folded, n); //write directly |abs(x)|^2 in this Doppler bin?
|
||||
d_dump_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (!d_bit_transition_flag)
|
||||
{
|
||||
if (d_test_statistics > d_threshold)
|
||||
{
|
||||
d_state = 2; // Positive acquisition
|
||||
|
||||
}
|
||||
else if (d_well_count == d_max_dwells)
|
||||
{
|
||||
d_state = 3; // Negative acquisition
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d_well_count == d_max_dwells) // d_max_dwells = 2
|
||||
{
|
||||
if (d_test_statistics > d_threshold)
|
||||
{
|
||||
d_state = 2; // Positive acquisition
|
||||
}
|
||||
else
|
||||
{
|
||||
d_state = 3; // Negative acquisition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
consume_each(1);
|
||||
|
||||
delete d_code_folded;
|
||||
d_code_folded = NULL;
|
||||
|
||||
free(in_temp);
|
||||
free(in_1code);
|
||||
free(corr_output);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
//DLOG(INFO) << "START CASE 2";
|
||||
// 6.1- Declare positive acquisition using a message queue
|
||||
DLOG(INFO) << "positive acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
DLOG(INFO) << "test statistics value " << d_test_statistics;
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "folding factor " << d_folding_factor;
|
||||
DLOG(INFO) << "possible delay correlation output";
|
||||
for (int i = 0; i < (int)d_folding_factor; i++) DLOG(INFO) << d_possible_delay[i] <<"\t\t\t"<<d_corr_output_f[i];
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "magnitude folded " << d_mag;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
|
||||
d_active = false;
|
||||
d_state = 0;
|
||||
|
||||
d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter
|
||||
consume_each(ninput_items[0]);
|
||||
|
||||
acquisition_message = 1;
|
||||
d_channel_internal_queue->push(acquisition_message);
|
||||
//DLOG(INFO) << "END CASE 2";
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
//DLOG(INFO) << "START CASE 3";
|
||||
// 6.2- Declare negative acquisition using a message queue
|
||||
DLOG(INFO) << "negative acquisition";
|
||||
DLOG(INFO) << "satellite " << d_gnss_synchro->System << " " << d_gnss_synchro->PRN;
|
||||
DLOG(INFO) << "sample_stamp " << d_sample_counter;
|
||||
DLOG(INFO) << "test statistics value " << d_test_statistics;
|
||||
DLOG(INFO) << "test statistics threshold " << d_threshold;
|
||||
DLOG(INFO) << "folding factor "<<d_folding_factor;
|
||||
DLOG(INFO) << "possible delay corr output";
|
||||
for (int i = 0; i < (int)d_folding_factor; i++) DLOG(INFO) << d_possible_delay[i] <<"\t\t\t"<<d_corr_output_f[i];
|
||||
DLOG(INFO) << "code phase " << d_gnss_synchro->Acq_delay_samples;
|
||||
DLOG(INFO) << "doppler " << d_gnss_synchro->Acq_doppler_hz;
|
||||
DLOG(INFO) << "magnitude folded " << d_mag;
|
||||
DLOG(INFO) << "input signal power " << d_input_power;
|
||||
|
||||
d_active = false;
|
||||
d_state = 0;
|
||||
|
||||
d_sample_counter += d_sampled_ms * d_samples_per_ms * ninput_items[0]; // sample counter
|
||||
consume_each(ninput_items[0]);
|
||||
|
||||
acquisition_message = 2;
|
||||
d_channel_internal_queue->push(acquisition_message);
|
||||
//DLOG(INFO) << "END CASE 3";
|
||||
break;
|
||||
}
|
||||
}
|
||||
//DLOG(INFO) << "END GENERAL WORK";
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,260 @@
|
||||
/*!
|
||||
* \file pcps_quicksync_acquisition_cc.h
|
||||
* \brief This class implements a Parallel Code Phase Search Acquisition with the
|
||||
* QuickSync Algorithm
|
||||
*
|
||||
* Acquisition strategy (Kay Borre book CFAR + threshold).
|
||||
* <ol>
|
||||
* <li> Compute the input signal power estimation
|
||||
* <li> Doppler serial search loop
|
||||
* <li> Perform folding of the incoming signal and local generated code
|
||||
* <li> Perform the FFT-based circular convolution (parallel time search)
|
||||
* <li> Record the maximum peak and the associated synchronization parameters
|
||||
* <li> Compute the test statistics and compare to the threshold
|
||||
* <li> Declare positive or negative acquisition using a message queue
|
||||
* <li> Obtain the adequate acquisition parameters by correlating the incoming
|
||||
* signal shifted by the possible folded delays
|
||||
* </ol>
|
||||
*
|
||||
* Kay Borre book: K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
|
||||
* "A Software-Defined GPS and Galileo Receiver. A Single-Frequency
|
||||
* Approach", Birkha user, 2007. pp 81-84
|
||||
*
|
||||
* \date Jun2 2014
|
||||
* \author Damian Miralles Sanchez, dmiralles2009@gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_PCPS_QUICKSYNC_ACQUISITION_CC_H_
|
||||
#define GNSS_SDR_PCPS_QUICKSYNC_ACQUISITION_CC_H_
|
||||
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <assert.h>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
#include <gnuradio/fft/fft.h>
|
||||
#include "concurrent_queue.h"
|
||||
#include "gnss_synchro.h"
|
||||
|
||||
class pcps_quicksync_acquisition_cc;
|
||||
|
||||
typedef boost::shared_ptr<pcps_quicksync_acquisition_cc>
|
||||
pcps_quicksync_acquisition_cc_sptr;
|
||||
|
||||
pcps_quicksync_acquisition_cc_sptr
|
||||
pcps_quicksync_make_acquisition_cc(unsigned int folding_factor,
|
||||
unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename);
|
||||
|
||||
/*!
|
||||
* \brief This class implements a Parallel Code Phase Search Acquisition with
|
||||
* the implementation of the Sparse QuickSync Algorithm.
|
||||
*
|
||||
* Check \ref Navitec2012 "Faster GPS via the Sparse Fourier Transform",
|
||||
* for details of its implementation and functionality.
|
||||
*/
|
||||
class pcps_quicksync_acquisition_cc: public gr::block
|
||||
{
|
||||
private:
|
||||
friend pcps_quicksync_acquisition_cc_sptr
|
||||
pcps_quicksync_make_acquisition_cc(unsigned int folding_factor,
|
||||
unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename);
|
||||
|
||||
pcps_quicksync_acquisition_cc(unsigned int folding_factor,
|
||||
unsigned int sampled_ms, unsigned int max_dwells,
|
||||
unsigned int doppler_max, long freq, long fs_in,
|
||||
int samples_per_ms, int samples_per_code,
|
||||
bool bit_transition_flag,
|
||||
gr::msg_queue::sptr queue, bool dump,
|
||||
std::string dump_filename);
|
||||
|
||||
void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift,
|
||||
int doppler_offset);
|
||||
|
||||
gr_complex* d_code;
|
||||
unsigned int d_folding_factor; // also referred in the paper as 'p'
|
||||
float * d_corr_acumulator;
|
||||
unsigned int *d_possible_delay;
|
||||
float *d_corr_output_f;
|
||||
float * d_magnitude_folded;
|
||||
gr_complex *d_signal_folded;
|
||||
gr_complex *d_code_folded;
|
||||
float d_noise_floor_power;
|
||||
|
||||
long d_fs_in;
|
||||
long d_freq;
|
||||
int d_samples_per_ms;
|
||||
int d_samples_per_code;
|
||||
unsigned int d_doppler_resolution;
|
||||
float d_threshold;
|
||||
std::string d_satellite_str;
|
||||
unsigned int d_doppler_max;
|
||||
unsigned int d_doppler_step;
|
||||
unsigned int d_sampled_ms;
|
||||
unsigned int d_max_dwells;
|
||||
unsigned int d_well_count;
|
||||
unsigned int d_fft_size;
|
||||
unsigned long int d_sample_counter;
|
||||
gr_complex** d_grid_doppler_wipeoffs;
|
||||
unsigned int d_num_doppler_bins;
|
||||
gr_complex* d_fft_codes;
|
||||
gr::fft::fft_complex* d_fft_if;
|
||||
gr::fft::fft_complex* d_fft_if2;
|
||||
gr::fft::fft_complex* d_ifft;
|
||||
Gnss_Synchro *d_gnss_synchro;
|
||||
unsigned int d_code_phase;
|
||||
float d_doppler_freq;
|
||||
float d_mag;
|
||||
float* d_magnitude;
|
||||
float d_input_power;
|
||||
float d_test_statistics;
|
||||
bool d_bit_transition_flag;
|
||||
gr::msg_queue::sptr d_queue;
|
||||
concurrent_queue<int> *d_channel_internal_queue;
|
||||
std::ofstream d_dump_file;
|
||||
bool d_active;
|
||||
int d_state;
|
||||
bool d_dump;
|
||||
unsigned int d_channel;
|
||||
std::string d_dump_filename;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Default destructor.
|
||||
*/
|
||||
~pcps_quicksync_acquisition_cc();
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
|
||||
* to exchange synchronization data between acquisition and tracking blocks.
|
||||
* \param p_gnss_synchro Satellite information shared by the processing blocks.
|
||||
*/
|
||||
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
|
||||
{
|
||||
d_gnss_synchro = p_gnss_synchro;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the maximum peak of grid search.
|
||||
*/
|
||||
unsigned int mag()
|
||||
{
|
||||
return d_mag;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Initializes acquisition algorithm.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/*!
|
||||
* \brief Sets local code for PCPS acquisition algorithm.
|
||||
* \param code - Pointer to the PRN code.
|
||||
*/
|
||||
void set_local_code(std::complex<float> * code);
|
||||
|
||||
/*!
|
||||
* \brief Starts acquisition algorithm, turning from standby mode to
|
||||
* active mode
|
||||
* \param active - bool that activates/deactivates the block.
|
||||
*/
|
||||
void set_active(bool active)
|
||||
{
|
||||
d_active = active;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Set acquisition channel unique ID
|
||||
* \param channel - receiver channel.
|
||||
*/
|
||||
void set_channel(unsigned int channel)
|
||||
{
|
||||
d_channel = channel;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Set statistics threshold of PCPS algorithm.
|
||||
* \param threshold - Threshold for signal detection (check \ref Navitec2012,
|
||||
* Algorithm 1, for a definition of this threshold).
|
||||
*/
|
||||
void set_threshold(float threshold)
|
||||
{
|
||||
d_threshold = threshold;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \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)
|
||||
{
|
||||
d_doppler_max = doppler_max;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \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)
|
||||
{
|
||||
d_doppler_step = doppler_step;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Set tracking channel internal queue.
|
||||
* \param channel_internal_queue - Channel's internal blocks information queue.
|
||||
*/
|
||||
void set_channel_queue(concurrent_queue<int> *channel_internal_queue)
|
||||
{
|
||||
d_channel_internal_queue = channel_internal_queue;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parallel Code Phase Search Acquisition signal processing.
|
||||
*/
|
||||
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_PCPS_ACQUISITION_CC_H_*/
|
@ -18,7 +18,7 @@
|
||||
|
||||
# Optional drivers
|
||||
|
||||
if($ENV{GN3S_DRIVER})
|
||||
if(ENABLE_GN3S)
|
||||
##############################################
|
||||
# GN3S (USB dongle)
|
||||
##############################################
|
||||
@ -49,12 +49,10 @@ if($ENV{GN3S_DRIVER})
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/firmware/GN3S_v2/bin/gn3s_firmware.ihx
|
||||
DESTINATION ${CMAKE_SOURCE_DIR}/install/
|
||||
)
|
||||
endif($ENV{GN3S_DRIVER})
|
||||
endif(ENABLE_GN3S)
|
||||
|
||||
if($ENV{RAW_ARRAY_DRIVER})
|
||||
set(RAW_ARRAY_DRIVER ON)
|
||||
endif($ENV{RAW_ARRAY_DRIVER})
|
||||
if(RAW_ARRAY_DRIVER)
|
||||
|
||||
if(ENABLE_ARRAY)
|
||||
##############################################
|
||||
# GRDBFCTTC GNSS EXPERIMENTAL ARRAY PROTOTYPE
|
||||
##############################################
|
||||
@ -82,13 +80,10 @@ if(RAW_ARRAY_DRIVER)
|
||||
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GRDBFCTTC_LIBRARIES})
|
||||
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${GRDBFCTTC_INCLUDE_DIRS})
|
||||
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} raw_array_signal_source.cc)
|
||||
endif(RAW_ARRAY_DRIVER)
|
||||
endif(ENABLE_ARRAY)
|
||||
|
||||
|
||||
if($ENV{RTLSDR_DRIVER})
|
||||
set(RTLSDR_DRIVER ON)
|
||||
endif($ENV{RTLSDR_DRIVER})
|
||||
if(RTLSDR_DRIVER)
|
||||
if(ENABLE_RTLSDR)
|
||||
################################################################################
|
||||
# OsmoSDR - http://sdr.osmocom.org/trac/
|
||||
################################################################################
|
||||
@ -104,7 +99,7 @@ if(RTLSDR_DRIVER)
|
||||
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} rtlsdr_signal_source.cc)
|
||||
set(OPT_LIBRARIES ${OPT_LIBRARIES} ${GROSMOSDR_LIBRARIES})
|
||||
set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${RTL_DRIVER_INCLUDE_DIRS})
|
||||
endif(RTLSDR_DRIVER)
|
||||
endif(ENABLE_RTLSDR)
|
||||
|
||||
set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc
|
||||
gen_signal_source.cc
|
||||
|
@ -7,11 +7,11 @@
|
||||
* Code DLL + carrier PLL according to the algorithms described in:
|
||||
* [1] K.Borre, D.M.Akos, N.Bertelsen, P.Rinder, and S.H.Jensen,
|
||||
* A Software-Defined GPS and Galileo Receiver. A Single-Frequency
|
||||
* Approach, Birkha user, 2007
|
||||
* Approach, Birkhauser, 2007
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
|
||||
* Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
@ -21,7 +21,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -37,6 +37,7 @@
|
||||
#include "galileo_e1_dll_pll_veml_tracking_cc.h"
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <gnuradio/io_signature.h>
|
||||
@ -148,7 +149,7 @@ galileo_e1_dll_pll_veml_tracking_cc::galileo_e1_dll_pll_veml_tracking_cc(
|
||||
|
||||
//--- Initializations ------------------------------
|
||||
// Initial code frequency basis of NCO
|
||||
d_code_freq_chips = Galileo_E1_CODE_CHIP_RATE_HZ;
|
||||
d_code_freq_chips = (double)Galileo_E1_CODE_CHIP_RATE_HZ;
|
||||
// Residual code phase (in chips)
|
||||
d_rem_code_phase_samples = 0.0;
|
||||
// Residual carrier phase
|
||||
@ -369,7 +370,7 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items,gr_vect
|
||||
//carrier phase accumulator for (K) Doppler estimation
|
||||
d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * Galileo_E1_CODE_PERIOD;
|
||||
//remnant carrier phase to prevent overflow in the code NCO
|
||||
d_rem_carr_phase_rad = d_rem_carr_phase_rad + GPS_TWO_PI* d_carrier_doppler_hz * Galileo_E1_CODE_PERIOD;
|
||||
d_rem_carr_phase_rad = d_rem_carr_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * Galileo_E1_CODE_PERIOD;
|
||||
d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, GPS_TWO_PI);
|
||||
|
||||
// ################## DLL ##########################################################
|
||||
@ -385,15 +386,15 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items,gr_vect
|
||||
|
||||
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
|
||||
// keep alignment parameters for the next input buffer
|
||||
float T_chip_seconds;
|
||||
float T_prn_seconds;
|
||||
float T_prn_samples;
|
||||
float K_blk_samples;
|
||||
double T_chip_seconds;
|
||||
double T_prn_seconds;
|
||||
double T_prn_samples;
|
||||
double K_blk_samples;
|
||||
// Compute the next buffer lenght based in the new period of the PRN sequence and the code phase error estimation
|
||||
T_chip_seconds = 1 / d_code_freq_chips;
|
||||
T_chip_seconds = 1 / (double)d_code_freq_chips;
|
||||
T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS;
|
||||
T_prn_samples = T_prn_seconds * (float)d_fs_in;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs*(float)d_fs_in;
|
||||
T_prn_samples = T_prn_seconds * (double)d_fs_in;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * (double)d_fs_in;
|
||||
d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples
|
||||
//d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample
|
||||
|
||||
@ -427,12 +428,11 @@ int galileo_e1_dll_pll_veml_tracking_cc::general_work (int noutput_items,gr_vect
|
||||
{
|
||||
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
|
||||
LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
|
||||
ControlMessageFactory* cmf = new ControlMessageFactory();
|
||||
std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
|
||||
if (d_queue != gr::msg_queue::sptr())
|
||||
{
|
||||
d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
|
||||
}
|
||||
delete cmf;
|
||||
d_carrier_lock_fail_counter = 0;
|
||||
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -145,7 +145,7 @@ private:
|
||||
gr_complex *d_Very_Late;
|
||||
|
||||
// remaining code phase and carrier phase between tracking loops
|
||||
float d_rem_code_phase_samples;
|
||||
double d_rem_code_phase_samples;
|
||||
float d_rem_carr_phase_rad;
|
||||
|
||||
// PLL and DLL filter library
|
||||
@ -160,7 +160,7 @@ private:
|
||||
Correlator d_correlator;
|
||||
|
||||
// tracking vars
|
||||
float d_code_freq_chips;
|
||||
double d_code_freq_chips;
|
||||
float d_carrier_doppler_hz;
|
||||
double d_acc_carrier_phase_rad;
|
||||
double d_acc_code_phase_secs;
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "galileo_e1_tcp_connector_tracking_cc.h"
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
@ -391,20 +392,20 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_ve
|
||||
code_error_filt_chips = tcp_data.proc_pack_code_error;
|
||||
//Code phase accumulator
|
||||
float code_error_filt_secs;
|
||||
code_error_filt_secs=(Galileo_E1_CODE_PERIOD*code_error_filt_chips)/Galileo_E1_CODE_CHIP_RATE_HZ; //[seconds]
|
||||
d_acc_code_phase_secs=d_acc_code_phase_secs+code_error_filt_secs;
|
||||
code_error_filt_secs = (Galileo_E1_CODE_PERIOD * code_error_filt_chips) / Galileo_E1_CODE_CHIP_RATE_HZ; //[seconds]
|
||||
d_acc_code_phase_secs = d_acc_code_phase_secs + code_error_filt_secs;
|
||||
|
||||
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
|
||||
// keep alignment parameters for the next input buffer
|
||||
float T_chip_seconds;
|
||||
float T_prn_seconds;
|
||||
float T_prn_samples;
|
||||
float K_blk_samples;
|
||||
double T_chip_seconds;
|
||||
double T_prn_seconds;
|
||||
double T_prn_samples;
|
||||
double K_blk_samples;
|
||||
// Compute the next buffer lenght based in the new period of the PRN sequence and the code phase error estimation
|
||||
T_chip_seconds = 1 / d_code_freq_chips;
|
||||
T_chip_seconds = 1 / (double)d_code_freq_chips;
|
||||
T_prn_seconds = T_chip_seconds * Galileo_E1_B_CODE_LENGTH_CHIPS;
|
||||
T_prn_samples = T_prn_seconds * (float)d_fs_in;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs*(float)d_fs_in;
|
||||
T_prn_samples = T_prn_seconds * (double)d_fs_in;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * (double)d_fs_in;
|
||||
d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples
|
||||
d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample
|
||||
|
||||
@ -438,12 +439,11 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_ve
|
||||
{
|
||||
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
|
||||
LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
|
||||
ControlMessageFactory* cmf = new ControlMessageFactory();
|
||||
std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
|
||||
if (d_queue != gr::msg_queue::sptr())
|
||||
{
|
||||
d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
|
||||
}
|
||||
delete cmf;
|
||||
d_carrier_lock_fail_counter = 0;
|
||||
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
|
||||
}
|
||||
@ -489,23 +489,23 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_ve
|
||||
}
|
||||
else
|
||||
{
|
||||
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
|
||||
/*!
|
||||
* \todo The stop timer has to be moved to the signal source!
|
||||
*/
|
||||
// stream to collect cout calls to improve thread safety
|
||||
std::stringstream tmp_str_stream;
|
||||
if (floor(d_sample_counter / d_fs_in) != d_last_seg)
|
||||
{
|
||||
d_last_seg = floor(d_sample_counter / d_fs_in);
|
||||
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
|
||||
/*!
|
||||
* \todo The stop timer has to be moved to the signal source!
|
||||
*/
|
||||
// stream to collect cout calls to improve thread safety
|
||||
std::stringstream tmp_str_stream;
|
||||
if (floor(d_sample_counter / d_fs_in) != d_last_seg)
|
||||
{
|
||||
d_last_seg = floor(d_sample_counter / d_fs_in);
|
||||
|
||||
if (d_channel == 0)
|
||||
{
|
||||
// debug: Second counter in channel 0
|
||||
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
|
||||
std::cout << tmp_str_stream.rdbuf() << std::flush;
|
||||
}
|
||||
}
|
||||
if (d_channel == 0)
|
||||
{
|
||||
// debug: Second counter in channel 0
|
||||
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
|
||||
std::cout << tmp_str_stream.rdbuf() << std::flush;
|
||||
}
|
||||
}
|
||||
*d_Early = gr_complex(0,0);
|
||||
*d_Prompt = gr_complex(0,0);
|
||||
*d_Late = gr_complex(0,0);
|
||||
|
@ -23,7 +23,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -149,7 +149,7 @@ private:
|
||||
gr_complex *d_Very_Late;
|
||||
|
||||
// remaining code phase and carrier phase between tracking loops
|
||||
float d_rem_code_phase_samples;
|
||||
double d_rem_code_phase_samples;
|
||||
float d_next_rem_code_phase_samples;
|
||||
float d_rem_carr_phase_rad;
|
||||
|
||||
@ -161,7 +161,7 @@ private:
|
||||
Correlator d_correlator;
|
||||
|
||||
// tracking vars
|
||||
float d_code_freq_chips;
|
||||
double d_code_freq_chips;
|
||||
float d_carrier_doppler_hz;
|
||||
float d_acc_carrier_phase_rad;
|
||||
float d_acc_code_phase_secs;
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -474,12 +474,11 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
{
|
||||
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
|
||||
LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
|
||||
ControlMessageFactory* cmf = new ControlMessageFactory();
|
||||
std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
|
||||
if (d_queue != gr::msg_queue::sptr())
|
||||
{
|
||||
d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
|
||||
}
|
||||
delete cmf;
|
||||
d_carrier_lock_fail_counter = 0;
|
||||
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
|
||||
}
|
||||
@ -513,12 +512,12 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
double T_prn_seconds;
|
||||
double T_prn_samples;
|
||||
double K_blk_samples;
|
||||
T_chip_seconds = 1/d_code_freq_hz;
|
||||
T_chip_seconds = 1 / (double)d_code_freq_hz;
|
||||
T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
|
||||
T_prn_samples = T_prn_seconds * d_fs_in;
|
||||
|
||||
float code_error_filt_samples;
|
||||
code_error_filt_samples = T_prn_seconds*code_error_filt_chips*T_chip_seconds*(float)d_fs_in; //[seconds]
|
||||
code_error_filt_samples = T_prn_seconds * code_error_filt_chips * T_chip_seconds * (double)d_fs_in; //[seconds]
|
||||
d_acc_code_phase_samples = d_acc_code_phase_samples + code_error_filt_samples;
|
||||
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_samples;
|
||||
@ -529,7 +528,7 @@ int Gps_L1_Ca_Dll_Fll_Pll_Tracking_cc::general_work (int noutput_items, gr_vecto
|
||||
current_synchro_data.Prompt_I = (double)(*d_Prompt).real();
|
||||
current_synchro_data.Prompt_Q = (double)(*d_Prompt).imag();
|
||||
// Tracking_timestamp_secs is aligned with the PRN start sample
|
||||
current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_current_prn_length_samples + d_rem_code_phase_samples)/d_fs_in;
|
||||
current_synchro_data.Tracking_timestamp_secs = ((double)d_sample_counter + (double)d_current_prn_length_samples + (double)d_rem_code_phase_samples) / (double)d_fs_in;
|
||||
// This tracking block aligns the Tracking_timestamp_secs with the start sample of the PRN, Code_phase_secs=0
|
||||
current_synchro_data.Code_phase_secs = 0;
|
||||
current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad;
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -36,6 +36,7 @@
|
||||
|
||||
#include "gps_l1_ca_dll_pll_optim_tracking_cc.h"
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <gnuradio/io_signature.h>
|
||||
@ -396,9 +397,9 @@ int Gps_L1_Ca_Dll_Pll_Optim_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
// New code Doppler 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);
|
||||
//carrier phase accumulator for (K) doppler estimation
|
||||
d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + GPS_TWO_PI*d_carrier_doppler_hz*GPS_L1_CA_CODE_PERIOD;
|
||||
d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * GPS_L1_CA_CODE_PERIOD;
|
||||
//remnant carrier phase to prevent overflow in the code NCO
|
||||
d_rem_carr_phase_rad = d_rem_carr_phase_rad + GPS_TWO_PI*d_carrier_doppler_hz*GPS_L1_CA_CODE_PERIOD;
|
||||
d_rem_carr_phase_rad = d_rem_carr_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * GPS_L1_CA_CODE_PERIOD;
|
||||
d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, GPS_TWO_PI);
|
||||
|
||||
// ################## DLL ##########################################################
|
||||
@ -408,20 +409,20 @@ int Gps_L1_Ca_Dll_Pll_Optim_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); //[chips/second]
|
||||
//Code phase accumulator
|
||||
float code_error_filt_secs;
|
||||
code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD*code_error_filt_chips) / GPS_L1_CA_CODE_RATE_HZ; //[seconds]
|
||||
code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD * code_error_filt_chips) / GPS_L1_CA_CODE_RATE_HZ; //[seconds]
|
||||
d_acc_code_phase_secs = d_acc_code_phase_secs + code_error_filt_secs;
|
||||
|
||||
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
|
||||
// keep alignment parameters for the next input buffer
|
||||
float T_chip_seconds;
|
||||
float T_prn_seconds;
|
||||
float T_prn_samples;
|
||||
float K_blk_samples;
|
||||
// Compute the next buffer lenght based in the new period of the PRN sequence and the code phase error estimation
|
||||
T_chip_seconds = 1 / d_code_freq_chips;
|
||||
double T_chip_seconds;
|
||||
double T_prn_seconds;
|
||||
double T_prn_samples;
|
||||
double K_blk_samples;
|
||||
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
|
||||
T_chip_seconds = 1 / (double)d_code_freq_chips;
|
||||
T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
|
||||
T_prn_samples = T_prn_seconds * (float)d_fs_in;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs*(float)d_fs_in;
|
||||
T_prn_samples = T_prn_seconds * (double)d_fs_in;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * (double)d_fs_in;
|
||||
d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples
|
||||
d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample
|
||||
|
||||
@ -452,12 +453,11 @@ int Gps_L1_Ca_Dll_Pll_Optim_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
{
|
||||
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
|
||||
LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
|
||||
ControlMessageFactory* cmf = new ControlMessageFactory();
|
||||
std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
|
||||
if (d_queue != gr::msg_queue::sptr())
|
||||
{
|
||||
d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
|
||||
}
|
||||
delete cmf;
|
||||
d_carrier_lock_fail_counter = 0;
|
||||
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
|
||||
}
|
||||
@ -499,24 +499,23 @@ int Gps_L1_Ca_Dll_Pll_Optim_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
}
|
||||
else
|
||||
{
|
||||
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
|
||||
/*!
|
||||
* \todo The stop timer has to be moved to the signal source!
|
||||
*/
|
||||
// stream to collect cout calls to improve thread safety
|
||||
std::stringstream tmp_str_stream;
|
||||
if (floor(d_sample_counter / d_fs_in) != d_last_seg)
|
||||
{
|
||||
d_last_seg = floor(d_sample_counter / d_fs_in);
|
||||
|
||||
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
|
||||
/*!
|
||||
* \todo The stop timer has to be moved to the signal source!
|
||||
*/
|
||||
// stream to collect cout calls to improve thread safety
|
||||
std::stringstream tmp_str_stream;
|
||||
if (floor(d_sample_counter / d_fs_in) != d_last_seg)
|
||||
{
|
||||
d_last_seg = floor(d_sample_counter / d_fs_in);
|
||||
|
||||
if (d_channel == 0)
|
||||
{
|
||||
// debug: Second counter in channel 0
|
||||
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
|
||||
std::cout << tmp_str_stream.rdbuf() << std::flush;
|
||||
}
|
||||
}
|
||||
if (d_channel == 0)
|
||||
{
|
||||
// debug: Second counter in channel 0
|
||||
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
|
||||
std::cout << tmp_str_stream.rdbuf() << std::flush;
|
||||
}
|
||||
}
|
||||
*d_Early = gr_complex(0,0);
|
||||
*d_Prompt = gr_complex(0,0);
|
||||
*d_Late = gr_complex(0,0);
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -134,7 +134,7 @@ private:
|
||||
gr_complex *d_Late;
|
||||
|
||||
// remaining code phase and carrier phase between tracking loops
|
||||
float d_rem_code_phase_samples;
|
||||
double d_rem_code_phase_samples;
|
||||
float d_rem_carr_phase_rad;
|
||||
|
||||
// PLL and DLL filter library
|
||||
@ -148,7 +148,7 @@ private:
|
||||
Correlator d_correlator;
|
||||
|
||||
// tracking vars
|
||||
float d_code_freq_chips;
|
||||
double d_code_freq_chips;
|
||||
float d_carrier_doppler_hz;
|
||||
float d_acc_carrier_phase_rad;
|
||||
float d_code_phase_samples;
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -37,6 +37,7 @@
|
||||
#include "gps_l1_ca_dll_pll_tracking_cc.h"
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <gnuradio/io_signature.h>
|
||||
@ -408,9 +409,9 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
|
||||
// New code Doppler 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);
|
||||
//carrier phase accumulator for (K) doppler estimation
|
||||
d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + GPS_TWO_PI*d_carrier_doppler_hz*GPS_L1_CA_CODE_PERIOD;
|
||||
d_acc_carrier_phase_rad = d_acc_carrier_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * GPS_L1_CA_CODE_PERIOD;
|
||||
//remanent carrier phase to prevent overflow in the code NCO
|
||||
d_rem_carr_phase_rad = d_rem_carr_phase_rad+GPS_TWO_PI*d_carrier_doppler_hz*GPS_L1_CA_CODE_PERIOD;
|
||||
d_rem_carr_phase_rad = d_rem_carr_phase_rad + GPS_TWO_PI * d_carrier_doppler_hz * GPS_L1_CA_CODE_PERIOD;
|
||||
d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, GPS_TWO_PI);
|
||||
|
||||
// ################## DLL ##########################################################
|
||||
@ -420,20 +421,20 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
|
||||
code_error_filt_chips = d_code_loop_filter.get_code_nco(code_error_chips); //[chips/second]
|
||||
//Code phase accumulator
|
||||
float code_error_filt_secs;
|
||||
code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD*code_error_filt_chips)/GPS_L1_CA_CODE_RATE_HZ; //[seconds]
|
||||
code_error_filt_secs = (GPS_L1_CA_CODE_PERIOD * code_error_filt_chips) / GPS_L1_CA_CODE_RATE_HZ; //[seconds]
|
||||
d_acc_code_phase_secs = d_acc_code_phase_secs + code_error_filt_secs;
|
||||
|
||||
// ################## CARRIER AND CODE NCO BUFFER ALIGNEMENT #######################
|
||||
// keep alignment parameters for the next input buffer
|
||||
float T_chip_seconds;
|
||||
float T_prn_seconds;
|
||||
float T_prn_samples;
|
||||
float K_blk_samples;
|
||||
double T_chip_seconds;
|
||||
double T_prn_seconds;
|
||||
double T_prn_samples;
|
||||
double K_blk_samples;
|
||||
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
|
||||
T_chip_seconds = 1 / d_code_freq_chips;
|
||||
T_chip_seconds = 1 / (double)d_code_freq_chips;
|
||||
T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
|
||||
T_prn_samples = T_prn_seconds * (float)d_fs_in;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs*(float)d_fs_in;
|
||||
T_prn_samples = T_prn_seconds * (double)d_fs_in;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * (double)d_fs_in;
|
||||
d_current_prn_length_samples = round(K_blk_samples); //round to a discrete samples
|
||||
//d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample
|
||||
|
||||
@ -464,12 +465,11 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
|
||||
{
|
||||
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
|
||||
LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
|
||||
ControlMessageFactory* cmf = new ControlMessageFactory();
|
||||
std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
|
||||
if (d_queue != gr::msg_queue::sptr())
|
||||
{
|
||||
d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
|
||||
}
|
||||
delete cmf;
|
||||
d_carrier_lock_fail_counter = 0;
|
||||
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
|
||||
}
|
||||
@ -525,23 +525,23 @@ int Gps_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items, gr_vector_in
|
||||
}
|
||||
else
|
||||
{
|
||||
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
|
||||
/*!
|
||||
* \todo The stop timer has to be moved to the signal source!
|
||||
*/
|
||||
// stream to collect cout calls to improve thread safety
|
||||
std::stringstream tmp_str_stream;
|
||||
if (floor(d_sample_counter / d_fs_in) != d_last_seg)
|
||||
{
|
||||
d_last_seg = floor(d_sample_counter / d_fs_in);
|
||||
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
|
||||
/*!
|
||||
* \todo The stop timer has to be moved to the signal source!
|
||||
*/
|
||||
// stream to collect cout calls to improve thread safety
|
||||
std::stringstream tmp_str_stream;
|
||||
if (floor(d_sample_counter / d_fs_in) != d_last_seg)
|
||||
{
|
||||
d_last_seg = floor(d_sample_counter / d_fs_in);
|
||||
|
||||
if (d_channel == 0)
|
||||
{
|
||||
// debug: Second counter in channel 0
|
||||
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
|
||||
std::cout << tmp_str_stream.rdbuf() << std::flush;
|
||||
}
|
||||
}
|
||||
if (d_channel == 0)
|
||||
{
|
||||
// debug: Second counter in channel 0
|
||||
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
|
||||
std::cout << tmp_str_stream.rdbuf() << std::flush;
|
||||
}
|
||||
}
|
||||
*d_Early = gr_complex(0,0);
|
||||
*d_Prompt = gr_complex(0,0);
|
||||
*d_Late = gr_complex(0,0);
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -138,7 +138,7 @@ private:
|
||||
gr_complex *d_Late;
|
||||
|
||||
// remaining code phase and carrier phase between tracking loops
|
||||
float d_rem_code_phase_samples;
|
||||
double d_rem_code_phase_samples;
|
||||
float d_rem_carr_phase_rad;
|
||||
|
||||
// PLL and DLL filter library
|
||||
@ -152,7 +152,7 @@ private:
|
||||
Correlator d_correlator;
|
||||
|
||||
// tracking vars
|
||||
float d_code_freq_chips;
|
||||
double d_code_freq_chips;
|
||||
float d_carrier_doppler_hz;
|
||||
float d_acc_carrier_phase_rad;
|
||||
float d_code_phase_samples;
|
||||
|
@ -457,19 +457,19 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
// sampling frequency (fixed)
|
||||
d_code_phase_step_chips = d_code_freq_hz / (float)d_fs_in; //[chips]
|
||||
// variable code PRN sample block size
|
||||
float T_chip_seconds;
|
||||
float T_prn_seconds;
|
||||
float T_prn_samples;
|
||||
float K_blk_samples;
|
||||
T_chip_seconds = 1 / d_code_freq_hz;
|
||||
double T_chip_seconds;
|
||||
double T_prn_seconds;
|
||||
double T_prn_samples;
|
||||
double K_blk_samples;
|
||||
T_chip_seconds = 1 / (double)d_code_freq_hz;
|
||||
T_prn_seconds = T_chip_seconds * GPS_L1_CA_CODE_LENGTH_CHIPS;
|
||||
T_prn_samples = T_prn_seconds * d_fs_in;
|
||||
T_prn_samples = T_prn_seconds * (double)d_fs_in;
|
||||
d_rem_code_phase_samples = d_next_rem_code_phase_samples;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples;//-code_error*(float)d_fs_in;
|
||||
K_blk_samples = T_prn_samples + d_rem_code_phase_samples;//-code_error*(double)d_fs_in;
|
||||
|
||||
// Update the current PRN delay (code phase in samples)
|
||||
float T_prn_true_seconds = GPS_L1_CA_CODE_LENGTH_CHIPS / GPS_L1_CA_CODE_RATE_HZ;
|
||||
float T_prn_true_samples = T_prn_true_seconds * (float)d_fs_in;
|
||||
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 * (double)d_fs_in;
|
||||
d_code_phase_samples = d_code_phase_samples + T_prn_samples - T_prn_true_samples;
|
||||
if (d_code_phase_samples < 0)
|
||||
{
|
||||
@ -509,11 +509,10 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
{
|
||||
std::cout << "Loss of lock in channel " << d_channel << "!" << std::endl;
|
||||
LOG(INFO) << "Loss of lock in channel " << d_channel << "!";
|
||||
ControlMessageFactory* cmf = new ControlMessageFactory();
|
||||
std::unique_ptr<ControlMessageFactory> cmf(new ControlMessageFactory());
|
||||
if (d_queue != gr::msg_queue::sptr()) {
|
||||
d_queue->handle(cmf->GetQueueMessage(d_channel, 2));
|
||||
}
|
||||
delete cmf;
|
||||
d_carrier_lock_fail_counter = 0;
|
||||
d_enable_tracking = false; // TODO: check if disabling tracking is consistent with the channel state machine
|
||||
|
||||
@ -558,23 +557,23 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work (int noutput_items, gr_vec
|
||||
}
|
||||
else
|
||||
{
|
||||
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
|
||||
/*!
|
||||
* \todo The stop timer has to be moved to the signal source!
|
||||
*/
|
||||
// stream to collect cout calls to improve thread safety
|
||||
std::stringstream tmp_str_stream;
|
||||
if (floor(d_sample_counter / d_fs_in) != d_last_seg)
|
||||
{
|
||||
d_last_seg = floor(d_sample_counter / d_fs_in);
|
||||
// ########## DEBUG OUTPUT (TIME ONLY for channel 0 when tracking is disabled)
|
||||
/*!
|
||||
* \todo The stop timer has to be moved to the signal source!
|
||||
*/
|
||||
// stream to collect cout calls to improve thread safety
|
||||
std::stringstream tmp_str_stream;
|
||||
if (floor(d_sample_counter / d_fs_in) != d_last_seg)
|
||||
{
|
||||
d_last_seg = floor(d_sample_counter / d_fs_in);
|
||||
|
||||
if (d_channel == 0)
|
||||
{
|
||||
// debug: Second counter in channel 0
|
||||
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
|
||||
std::cout << tmp_str_stream.rdbuf() << std::flush;
|
||||
}
|
||||
}
|
||||
if (d_channel == 0)
|
||||
{
|
||||
// debug: Second counter in channel 0
|
||||
tmp_str_stream << "Current input signal time = " << d_last_seg << " [s]" << std::endl << std::flush;
|
||||
std::cout << tmp_str_stream.rdbuf() << std::flush;
|
||||
}
|
||||
}
|
||||
*d_Early = gr_complex(0,0);
|
||||
*d_Prompt = gr_complex(0,0);
|
||||
*d_Late = gr_complex(0,0);
|
||||
|
@ -21,7 +21,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -132,9 +132,9 @@ private:
|
||||
long d_if_freq;
|
||||
long d_fs_in;
|
||||
|
||||
float d_early_late_spc_chips;
|
||||
double d_early_late_spc_chips;
|
||||
|
||||
float d_code_phase_step_chips;
|
||||
double d_code_phase_step_chips;
|
||||
|
||||
gr_complex* d_ca_code;
|
||||
|
||||
@ -148,8 +148,8 @@ private:
|
||||
gr_complex *d_Late;
|
||||
|
||||
// remaining code phase and carrier phase between tracking loops
|
||||
float d_rem_code_phase_samples;
|
||||
float d_next_rem_code_phase_samples;
|
||||
double d_rem_code_phase_samples;
|
||||
double d_next_rem_code_phase_samples;
|
||||
float d_rem_carr_phase_rad;
|
||||
|
||||
// PLL and DLL filter library
|
||||
@ -163,10 +163,10 @@ private:
|
||||
Correlator d_correlator;
|
||||
|
||||
// tracking vars
|
||||
float d_code_freq_hz;
|
||||
float d_carrier_doppler_hz;
|
||||
float d_acc_carrier_phase_rad;
|
||||
float d_code_phase_samples;
|
||||
double d_code_freq_hz;
|
||||
double d_carrier_doppler_hz;
|
||||
double d_acc_carrier_phase_rad;
|
||||
double d_code_phase_samples;
|
||||
size_t d_port_ch0;
|
||||
size_t d_port;
|
||||
int d_listen_connection;
|
||||
|
@ -65,37 +65,17 @@ include_directories(
|
||||
)
|
||||
|
||||
|
||||
#Enable GN3S module if the flag is present
|
||||
if( $ENV{GN3S_DRIVER} )
|
||||
message(STATUS "Support for RF front-end GN3S v2 enabled" )
|
||||
if(ENABLE_GN3S)
|
||||
add_definitions(-DGN3S_DRIVER=1)
|
||||
endif( $ENV{GN3S_DRIVER} )
|
||||
if( GN3S_DRIVER )
|
||||
message(STATUS "Support for RF front-end GN3S v2 enabled" )
|
||||
add_definitions(-DGN3S_DRIVER=1)
|
||||
endif( GN3S_DRIVER )
|
||||
endif(ENABLE_GN3S)
|
||||
|
||||
|
||||
if( $ENV{RAW_ARRAY_DRIVER} )
|
||||
message(STATUS "Support for CTTC RAW ARRAY enabled" )
|
||||
if(ENABLE_ARRAY)
|
||||
add_definitions(-DRAW_ARRAY_DRIVER=1)
|
||||
endif( $ENV{RAW_ARRAY_DRIVER} )
|
||||
endif(ENABLE_ARRAY)
|
||||
|
||||
if( RAW_ARRAY_DRIVER )
|
||||
message(STATUS "Support for CTTC RAW ARRAY enabled" )
|
||||
add_definitions(-DRAW_ARRAY_DRIVER=1)
|
||||
endif( RAW_ARRAY_DRIVER )
|
||||
|
||||
#Enable RTL-SDR module if the flag is present
|
||||
if( $ENV{RTLSDR_DRIVER} )
|
||||
message(STATUS "Support for RF front-end based on RTL dongle enabled" )
|
||||
if(ENABLE_RTLSDR)
|
||||
add_definitions(-DRTLSDR_DRIVER=1)
|
||||
endif( $ENV{RTLSDR_DRIVER} )
|
||||
|
||||
if( RTLSDR_DRIVER )
|
||||
message(STATUS "Support for RF front-end based on RTL dongle enabled" )
|
||||
add_definitions(-DRTLSDR_DRIVER=1)
|
||||
endif( RTLSDR_DRIVER )
|
||||
endif(ENABLE_RTLSDR)
|
||||
|
||||
#Enable OpenCL if found in the system
|
||||
if(OPENCL_FOUND)
|
||||
|
@ -61,10 +61,12 @@
|
||||
#include "gps_l1_ca_pcps_tong_acquisition.h"
|
||||
#include "gps_l1_ca_pcps_assisted_acquisition.h"
|
||||
#include "gps_l1_ca_pcps_acquisition_fine_doppler.h"
|
||||
#include "gps_l1_ca_pcps_quicksync_acquisition.h"
|
||||
#include "galileo_e1_pcps_ambiguous_acquisition.h"
|
||||
#include "galileo_e1_pcps_8ms_ambiguous_acquisition.h"
|
||||
#include "galileo_e1_pcps_tong_ambiguous_acquisition.h"
|
||||
#include "galileo_e1_pcps_cccwsr_ambiguous_acquisition.h"
|
||||
#include "galileo_e1_pcps_quicksync_ambiguous_acquisition.h"
|
||||
#include "gps_l1_ca_dll_pll_tracking.h"
|
||||
#include "gps_l1_ca_dll_pll_optim_tracking.h"
|
||||
#include "gps_l1_ca_dll_fll_pll_tracking.h"
|
||||
@ -494,6 +496,12 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
out_streams, queue));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation.compare("GPS_L1_CA_PCPS_QuickSync_Acquisition") == 0)
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_( new GpsL1CaPcpsQuickSyncAcquisition(configuration.get(), role, in_streams,
|
||||
out_streams, queue));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0)
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_(new GalileoE1PcpsAmbiguousAcquisition(configuration.get(), role, in_streams,
|
||||
@ -518,6 +526,12 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
out_streams, queue));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation.compare("Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition") == 0)
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_( new GalileoE1PcpsQuickSyncAmbiguousAcquisition(configuration.get(), role, in_streams,
|
||||
out_streams, queue));
|
||||
block = std::move(block_);
|
||||
}
|
||||
|
||||
// TRACKING BLOCKS -------------------------------------------------------------
|
||||
else if (implementation.compare("GPS_L1_CA_DLL_PLL_Tracking") == 0)
|
||||
@ -694,6 +708,12 @@ std::unique_ptr<AcquisitionInterface> GNSSBlockFactory::GetAcqBlock(
|
||||
out_streams, queue));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation.compare("GPS_L1_CA_PCPS_QuickSync_Acquisition") == 0)
|
||||
{
|
||||
std::unique_ptr<AcquisitionInterface> block_( new GpsL1CaPcpsQuickSyncAcquisition(configuration.get(), role, in_streams,
|
||||
out_streams, queue));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation.compare("Galileo_E1_PCPS_Ambiguous_Acquisition") == 0)
|
||||
{
|
||||
std::unique_ptr<AcquisitionInterface> block_(new GalileoE1PcpsAmbiguousAcquisition(configuration.get(), role, in_streams,
|
||||
@ -718,6 +738,12 @@ std::unique_ptr<AcquisitionInterface> GNSSBlockFactory::GetAcqBlock(
|
||||
out_streams, queue));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else if (implementation.compare("Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition") == 0)
|
||||
{
|
||||
std::unique_ptr<AcquisitionInterface> block_( new GalileoE1PcpsQuickSyncAmbiguousAcquisition(configuration.get(), role, in_streams,
|
||||
out_streams, queue));
|
||||
block = std::move(block_);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Log fatal. This causes execution to stop.
|
||||
|
@ -46,7 +46,7 @@ const double GALILEO_GM = 3.986004418e14; //!< Geocentric gravitational constan
|
||||
const double GALILEO_OMEGA_EARTH_DOT = 7.2921151467e-5; //!< Mean angular velocity of the Earth [rad/s]
|
||||
const double GALILEO_C_m_s = 299792458.0; //!< The speed of light, [m/s]
|
||||
const double GALILEO_C_m_ms = 299792.4580; //!< The speed of light, [m/ms]
|
||||
const double GALILEO_F = -4.442807633e-10; //!< Constant, [s/(m)^(1/2)]
|
||||
const double GALILEO_F = -4.442807309e-10; //!< Constant, [s/(m)^(1/2)]
|
||||
|
||||
// carrier and code frequencies
|
||||
const double Galileo_E1_FREQ_HZ = 1.57542e9; //!< Galileo E1 carrier frequency [Hz]
|
||||
|
@ -106,7 +106,7 @@ double Galileo_Ephemeris::sv_clock_drift(double transmitTime)
|
||||
// Satellite Time Correction Algorithm, ICD 5.1.4
|
||||
double dt;
|
||||
dt = transmitTime - t0c_4;
|
||||
Galileo_satClkDrift = af0_4 + af1_4*dt + (af2_4 * dt)*(af2_4 * dt) + Galileo_dtr;
|
||||
Galileo_satClkDrift = af0_4 + af1_4 * dt + af2_4 * (dt * dt) + sv_clock_relativistic_term(transmitTime); //+Galileo_dtr;
|
||||
return Galileo_satClkDrift;
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ double Gps_Ephemeris::sv_clock_drift(double transmitTime)
|
||||
{
|
||||
double dt;
|
||||
dt = check_t(transmitTime - d_Toc);
|
||||
d_satClkDrift = d_A_f0 + d_A_f1*dt + (d_A_f2 * dt)*(d_A_f2 * dt);
|
||||
d_satClkDrift = d_A_f0 + d_A_f1 * dt + d_A_f2 * (dt * dt) + sv_clock_relativistic_term(transmitTime);
|
||||
return d_satClkDrift;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
# Copyright (C) 2012-2013 (see AUTHORS file for a list of contributors)
|
||||
# Copyright (C) 2012-2014 (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.
|
||||
# (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
|
||||
@ -16,6 +16,16 @@
|
||||
# along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
set(GNSS_SDR_OPTIONAL_LIBS "")
|
||||
set(GNSS_SDR_OPTIONAL_HEADERS "")
|
||||
|
||||
if(ENABLE_GPERFTOOLS)
|
||||
if(GPERFTOOLS_FOUND)
|
||||
#set(GNSS_SDR_OPTIONAL_LIBS "${GNSS_SDR_OPTIONAL_LIBS};${GPERFTOOLS_LIBRARIES}")
|
||||
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)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src/core/system_parameters
|
||||
@ -30,6 +40,7 @@ include_directories(
|
||||
${ARMADILLO_INCLUDE_DIRS}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${GNURADIO_RUNTIME_INCLUDE_DIRS}
|
||||
${GNSS_SDR_OPTIONAL_HEADERS}
|
||||
)
|
||||
|
||||
add_definitions( -DGNSS_SDR_VERSION="${VERSION}" )
|
||||
@ -57,6 +68,7 @@ target_link_libraries(gnss-sdr ${MAC_LIBRARIES}
|
||||
${UHD_LIBRARIES}
|
||||
gnss_sp_libs
|
||||
gnss_rx
|
||||
${GNSS_SDR_OPTIONAL_LIBS}
|
||||
)
|
||||
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
# Copyright (C) 2010-2013 (see AUTHORS file for a list of contributors)
|
||||
# Copyright (C) 2010-2014 (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.
|
||||
# (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
|
||||
@ -89,6 +89,16 @@ else(NOT GTEST_DIR_LOCAL)
|
||||
endif(NOT GTEST_DIR_LOCAL)
|
||||
|
||||
|
||||
set(GNSS_SDR_TEST_OPTIONAL_LIBS "")
|
||||
set(GNSS_SDR_TEST_OPTIONAL_HEADERS "")
|
||||
|
||||
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)
|
||||
|
||||
|
||||
include_directories(
|
||||
${GTEST_INCLUDE_DIRECTORIES}
|
||||
@ -120,6 +130,7 @@ include_directories(
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${ARMADILLO_INCLUDE_DIRS}
|
||||
${VOLK_INCLUDE_DIRS}
|
||||
${GNSS_SDR_TEST_OPTIONAL_HEADERS}
|
||||
)
|
||||
|
||||
|
||||
@ -158,6 +169,7 @@ target_link_libraries(run_tests ${MAC_LIBRARIES}
|
||||
signal_generator_adapters
|
||||
out_adapters
|
||||
pvt_gr_blocks
|
||||
${GNSS_SDR_TEST_OPTIONAL_LIBS}
|
||||
)
|
||||
|
||||
install(TARGETS run_tests DESTINATION ${CMAKE_SOURCE_DIR}/install)
|
||||
@ -193,11 +205,13 @@ add_executable(gnss_block_test EXCLUDE_FROM_ALL
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/gps_l1_ca_pcps_multithread_acquisition_gsoc2013_test.cc
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/galileo_e1_pcps_ambiguous_acquisition_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc
|
||||
#${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/galileo_e1_dll_pll_veml_tracking_test.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gnss_block/file_output_filter_test.cc
|
||||
|
@ -0,0 +1,818 @@
|
||||
/*!
|
||||
* \file galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc
|
||||
* \brief This class implements an acquisition test for
|
||||
* GalileoE1PcpsQuickSyncAmbiguousAcquisition class.
|
||||
* \author Damian Miralles, 2014. dmiralles2009@gmail.com
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/top_block.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/analog/sig_source_waveform.h>
|
||||
#include <gnuradio/analog/sig_source_c.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/blocks/null_sink.h>
|
||||
#include "gnss_block_interface.h"
|
||||
#include "in_memory_configuration.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "signal_generator.h"
|
||||
#include "signal_generator_c.h"
|
||||
#include "fir_filter.h"
|
||||
#include "gen_signal_source.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include "galileo_e1_pcps_quicksync_ambiguous_acquisition.h"
|
||||
|
||||
DEFINE_double(e1_value_threshold, 0.3, "Value of the threshold for the acquisition");
|
||||
DEFINE_int32(e1_value_CN0_dB_0, 44, "Value for the CN0_dB_0 in channel 0");
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
class GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test()
|
||||
{
|
||||
queue = gr::msg_queue::make(0);
|
||||
top_block = gr::make_top_block("Acquisition test");
|
||||
factory = std::make_shared<GNSSBlockFactory>();
|
||||
item_size = sizeof(gr_complex);
|
||||
stop = false;
|
||||
message = 0;
|
||||
}
|
||||
|
||||
~GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test()
|
||||
{
|
||||
}
|
||||
|
||||
void init();
|
||||
void config_1();
|
||||
void config_2();
|
||||
void config_3();
|
||||
void start_queue();
|
||||
void wait_message();
|
||||
void process_message();
|
||||
void stop_queue();
|
||||
|
||||
gr::msg_queue::sptr queue;
|
||||
gr::top_block_sptr top_block;
|
||||
std::shared_ptr<GalileoE1PcpsQuickSyncAmbiguousAcquisition> acquisition;
|
||||
std::shared_ptr<GNSSBlockFactory> factory;
|
||||
std::shared_ptr<InMemoryConfiguration> config;
|
||||
Gnss_Synchro gnss_synchro;
|
||||
size_t item_size;
|
||||
concurrent_queue<int> channel_internal_queue;
|
||||
bool stop;
|
||||
int message;
|
||||
boost::thread ch_thread;
|
||||
|
||||
unsigned int integration_time_ms;
|
||||
unsigned int fs_in;
|
||||
unsigned int folding_factor;
|
||||
|
||||
double expected_delay_chips;
|
||||
double expected_doppler_hz;
|
||||
float max_doppler_error_hz;
|
||||
float max_delay_error_chips;
|
||||
|
||||
unsigned int num_of_realizations;
|
||||
unsigned int realization_counter;
|
||||
unsigned int detection_counter;
|
||||
unsigned int correct_estimation_counter;
|
||||
unsigned int acquired_samples;
|
||||
unsigned int mean_acq_time_us;
|
||||
|
||||
double mse_doppler;
|
||||
double mse_delay;
|
||||
|
||||
double Pd; // Probability of detection
|
||||
double Pfa_p; // Probability of false alarm on present satellite
|
||||
double Pfa_a; // Probability of false alarm on absent satellite
|
||||
double Pmd; // Probability of miss detection
|
||||
|
||||
std::ofstream pdpfafile;
|
||||
unsigned int miss_detection_counter;
|
||||
bool dump_test_results;
|
||||
};
|
||||
|
||||
|
||||
void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::init()
|
||||
{
|
||||
message = 0;
|
||||
realization_counter = 0;
|
||||
detection_counter = 0;
|
||||
correct_estimation_counter = 0;
|
||||
acquired_samples = 0;
|
||||
mse_doppler = 0;
|
||||
mse_delay = 0;
|
||||
mean_acq_time_us = 0;
|
||||
Pd = 0;
|
||||
Pfa_p = 0;
|
||||
Pfa_a = 0;
|
||||
|
||||
miss_detection_counter = 0;
|
||||
Pmd = 0;
|
||||
}
|
||||
|
||||
void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::config_1()
|
||||
{
|
||||
gnss_synchro.Channel_ID = 0;
|
||||
gnss_synchro.System = 'E';
|
||||
std::string signal = "1C";
|
||||
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||
|
||||
integration_time_ms = 8;
|
||||
fs_in = 4e6;
|
||||
|
||||
expected_delay_chips = 600;
|
||||
expected_doppler_hz = 750;
|
||||
max_doppler_error_hz = 2/(3*integration_time_ms*1e-3);
|
||||
max_delay_error_chips = 0.50;
|
||||
|
||||
num_of_realizations = 1;
|
||||
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
|
||||
config->set_property("GNSS-SDR.internal_fs_hz", std::to_string(fs_in));
|
||||
|
||||
config->set_property("SignalSource.fs_hz", std::to_string(fs_in));
|
||||
|
||||
config->set_property("SignalSource.item_type", "gr_complex");
|
||||
|
||||
config->set_property("SignalSource.num_satellites", "1");
|
||||
|
||||
config->set_property("SignalSource.system_0", "E");
|
||||
config->set_property("SignalSource.PRN_0", "10");
|
||||
config->set_property("SignalSource.CN0_dB_0", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_0",
|
||||
std::to_string(expected_doppler_hz));
|
||||
config->set_property("SignalSource.delay_chips_0",
|
||||
std::to_string(expected_delay_chips));
|
||||
|
||||
config->set_property("SignalSource.noise_flag", "false");
|
||||
config->set_property("SignalSource.data_flag", "false");
|
||||
config->set_property("SignalSource.BW_BB", "0.97");
|
||||
|
||||
config->set_property("InputFilter.implementation", "Fir_Filter");
|
||||
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", "11");
|
||||
config->set_property("InputFilter.number_of_bands", "2");
|
||||
config->set_property("InputFilter.band1_begin", "0.0");
|
||||
config->set_property("InputFilter.band1_end", "0.97");
|
||||
config->set_property("InputFilter.band2_begin", "0.98");
|
||||
config->set_property("InputFilter.band2_end", "1.0");
|
||||
config->set_property("InputFilter.ampl1_begin", "1.0");
|
||||
config->set_property("InputFilter.ampl1_end", "1.0");
|
||||
config->set_property("InputFilter.ampl2_begin", "0.0");
|
||||
config->set_property("InputFilter.ampl2_end", "0.0");
|
||||
config->set_property("InputFilter.band1_error", "1.0");
|
||||
config->set_property("InputFilter.band2_error", "1.0");
|
||||
config->set_property("InputFilter.filter_type", "bandpass");
|
||||
config->set_property("InputFilter.grid_density", "16");
|
||||
|
||||
config->set_property("Acquisition.item_type", "gr_complex");
|
||||
config->set_property("Acquisition.if", "0");
|
||||
config->set_property("Acquisition.coherent_integration_time_ms",
|
||||
std::to_string(integration_time_ms));
|
||||
config->set_property("Acquisition.max_dwells", "1");
|
||||
config->set_property("Acquisition.bit_transition_flag","false");
|
||||
config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition");
|
||||
config->set_property("Acquisition.threshold", "1");
|
||||
config->set_property("Acquisition.doppler_max", "10000");
|
||||
config->set_property("Acquisition.doppler_step", "250");
|
||||
config->set_property("Acquisition.folding_factor", "2");
|
||||
config->set_property("Acquisition.dump", "true");
|
||||
}
|
||||
|
||||
void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::config_2()
|
||||
{
|
||||
gnss_synchro.Channel_ID = 0;
|
||||
gnss_synchro.System = 'E';
|
||||
std::string signal = "1C";
|
||||
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||
|
||||
integration_time_ms = 8;
|
||||
fs_in = 4e6;
|
||||
|
||||
expected_delay_chips = 600;
|
||||
expected_doppler_hz = 750;
|
||||
max_doppler_error_hz = 2 / (3 * integration_time_ms * 1e-3);
|
||||
max_delay_error_chips = 0.50;
|
||||
|
||||
/*Unset this flag to eliminates data logging for the Validation of results
|
||||
probabilities test*/
|
||||
dump_test_results = true;
|
||||
|
||||
num_of_realizations = 100;
|
||||
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
|
||||
config->set_property("GNSS-SDR.internal_fs_hz", std::to_string(fs_in));
|
||||
|
||||
config->set_property("SignalSource.fs_hz", std::to_string(fs_in));
|
||||
|
||||
config->set_property("SignalSource.item_type", "gr_complex");
|
||||
|
||||
config->set_property("SignalSource.num_satellites", "4");
|
||||
|
||||
config->set_property("SignalSource.system_0", "E");
|
||||
config->set_property("SignalSource.PRN_0", "10");
|
||||
config->set_property("SignalSource.CN0_dB_0", std::to_string(FLAGS_e1_value_CN0_dB_0));
|
||||
config->set_property("SignalSource.doppler_Hz_0",
|
||||
std::to_string(expected_doppler_hz));
|
||||
config->set_property("SignalSource.delay_chips_0",
|
||||
std::to_string(expected_delay_chips));
|
||||
|
||||
config->set_property("SignalSource.system_1", "E");
|
||||
config->set_property("SignalSource.PRN_1", "15");
|
||||
config->set_property("SignalSource.CN0_dB_1", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_1", "1000");
|
||||
config->set_property("SignalSource.delay_chips_1", "100");
|
||||
|
||||
config->set_property("SignalSource.system_2", "E");
|
||||
config->set_property("SignalSource.PRN_2", "21");
|
||||
config->set_property("SignalSource.CN0_dB_2", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_2", "2000");
|
||||
config->set_property("SignalSource.delay_chips_2", "200");
|
||||
|
||||
config->set_property("SignalSource.system_3", "E");
|
||||
config->set_property("SignalSource.PRN_3", "22");
|
||||
config->set_property("SignalSource.CN0_dB_3", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_3", "3000");
|
||||
config->set_property("SignalSource.delay_chips_3", "300");
|
||||
|
||||
config->set_property("SignalSource.noise_flag", "true");
|
||||
config->set_property("SignalSource.data_flag", "true");
|
||||
config->set_property("SignalSource.BW_BB", "0.97");
|
||||
|
||||
config->set_property("InputFilter.implementation", "Fir_Filter");
|
||||
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", "11");
|
||||
config->set_property("InputFilter.number_of_bands", "2");
|
||||
config->set_property("InputFilter.band1_begin", "0.0");
|
||||
config->set_property("InputFilter.band1_end", "0.97");
|
||||
config->set_property("InputFilter.band2_begin", "0.98");
|
||||
config->set_property("InputFilter.band2_end", "1.0");
|
||||
config->set_property("InputFilter.ampl1_begin", "1.0");
|
||||
config->set_property("InputFilter.ampl1_end", "1.0");
|
||||
config->set_property("InputFilter.ampl2_begin", "0.0");
|
||||
config->set_property("InputFilter.ampl2_end", "0.0");
|
||||
config->set_property("InputFilter.band1_error", "1.0");
|
||||
config->set_property("InputFilter.band2_error", "1.0");
|
||||
config->set_property("InputFilter.filter_type", "bandpass");
|
||||
config->set_property("InputFilter.grid_density", "16");
|
||||
|
||||
config->set_property("Acquisition.item_type", "gr_complex");
|
||||
config->set_property("Acquisition.if", "0");
|
||||
config->set_property("Acquisition.coherent_integration_time_ms",
|
||||
std::to_string(integration_time_ms));
|
||||
config->set_property("Acquisition.max_dwells", "1");
|
||||
config->set_property("Acquisition.bit_transition_flag","false");
|
||||
config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition");
|
||||
config->set_property("Acquisition.threshold", std::to_string(FLAGS_e1_value_threshold));
|
||||
config->set_property("Acquisition.doppler_max", "10000");
|
||||
config->set_property("Acquisition.doppler_step", "125");
|
||||
config->set_property("Acquisition.folding_factor", "2");
|
||||
config->set_property("Acquisition.dump", "false");
|
||||
}
|
||||
|
||||
|
||||
void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::config_3()
|
||||
{
|
||||
gnss_synchro.Channel_ID = 0;
|
||||
gnss_synchro.System = 'E';
|
||||
std::string signal = "1C";
|
||||
signal.copy(gnss_synchro.Signal, 2, 0);
|
||||
|
||||
integration_time_ms = 16;
|
||||
fs_in = 4e6;
|
||||
|
||||
expected_delay_chips = 600;
|
||||
expected_doppler_hz = 750;
|
||||
max_doppler_error_hz = 2 / (3 * integration_time_ms * 1e-3);
|
||||
max_delay_error_chips = 0.50;
|
||||
|
||||
num_of_realizations = 1;
|
||||
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
|
||||
config->set_property("GNSS-SDR.internal_fs_hz", std::to_string(fs_in));
|
||||
|
||||
config->set_property("SignalSource.fs_hz", std::to_string(fs_in));
|
||||
|
||||
config->set_property("SignalSource.item_type", "gr_complex");
|
||||
|
||||
config->set_property("SignalSource.num_satellites", "4");
|
||||
|
||||
config->set_property("SignalSource.system_0", "E");
|
||||
config->set_property("SignalSource.PRN_0", "10");
|
||||
config->set_property("SignalSource.CN0_dB_0", std::to_string(FLAGS_e1_value_CN0_dB_0));
|
||||
config->set_property("SignalSource.doppler_Hz_0",
|
||||
std::to_string(expected_doppler_hz));
|
||||
config->set_property("SignalSource.delay_chips_0",
|
||||
std::to_string(expected_delay_chips));
|
||||
|
||||
config->set_property("SignalSource.system_1", "E");
|
||||
config->set_property("SignalSource.PRN_1", "15");
|
||||
config->set_property("SignalSource.CN0_dB_1", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_1", "1000");
|
||||
config->set_property("SignalSource.delay_chips_1", "100");
|
||||
|
||||
config->set_property("SignalSource.system_2", "E");
|
||||
config->set_property("SignalSource.PRN_2", "21");
|
||||
config->set_property("SignalSource.CN0_dB_2", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_2", "2000");
|
||||
config->set_property("SignalSource.delay_chips_2", "200");
|
||||
|
||||
config->set_property("SignalSource.system_3", "E");
|
||||
config->set_property("SignalSource.PRN_3", "22");
|
||||
config->set_property("SignalSource.CN0_dB_3", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_3", "3000");
|
||||
config->set_property("SignalSource.delay_chips_3", "300");
|
||||
|
||||
config->set_property("SignalSource.noise_flag", "true");
|
||||
config->set_property("SignalSource.data_flag", "true");
|
||||
config->set_property("SignalSource.BW_BB", "0.97");
|
||||
|
||||
config->set_property("InputFilter.implementation", "Fir_Filter");
|
||||
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", "11");
|
||||
config->set_property("InputFilter.number_of_bands", "2");
|
||||
config->set_property("InputFilter.band1_begin", "0.0");
|
||||
config->set_property("InputFilter.band1_end", "0.97");
|
||||
config->set_property("InputFilter.band2_begin", "0.98");
|
||||
config->set_property("InputFilter.band2_end", "1.0");
|
||||
config->set_property("InputFilter.ampl1_begin", "1.0");
|
||||
config->set_property("InputFilter.ampl1_end", "1.0");
|
||||
config->set_property("InputFilter.ampl2_begin", "0.0");
|
||||
config->set_property("InputFilter.ampl2_end", "0.0");
|
||||
config->set_property("InputFilter.band1_error", "1.0");
|
||||
config->set_property("InputFilter.band2_error", "1.0");
|
||||
config->set_property("InputFilter.filter_type", "bandpass");
|
||||
config->set_property("InputFilter.grid_density", "16");
|
||||
|
||||
config->set_property("Acquisition.item_type", "gr_complex");
|
||||
config->set_property("Acquisition.if", "0");
|
||||
config->set_property("Acquisition.coherent_integration_time_ms",
|
||||
std::to_string(integration_time_ms));
|
||||
config->set_property("Acquisition.max_dwells", "1");
|
||||
config->set_property("Acquisition.bit_transition_flag","false");
|
||||
config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition");
|
||||
config->set_property("Acquisition.threshold", "0.2");
|
||||
config->set_property("Acquisition.doppler_max", "10000");
|
||||
config->set_property("Acquisition.doppler_step", "125");
|
||||
config->set_property("Acquisition.folding_factor", "4");
|
||||
config->set_property("Acquisition.dump", "true");
|
||||
}
|
||||
|
||||
void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::start_queue()
|
||||
{
|
||||
stop = false;
|
||||
ch_thread = boost::thread(&GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::wait_message, this);
|
||||
}
|
||||
|
||||
void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::wait_message()
|
||||
{
|
||||
struct timeval tv;
|
||||
long long int begin = 0;
|
||||
long long int end = 0;
|
||||
|
||||
while (!stop)
|
||||
{
|
||||
acquisition->reset();
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
begin = tv.tv_sec*1e6 + tv.tv_usec;
|
||||
|
||||
channel_internal_queue.wait_and_pop(message);
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
end = tv.tv_sec*1e6 + tv.tv_usec;
|
||||
|
||||
mean_acq_time_us += (end - begin);
|
||||
|
||||
process_message();
|
||||
}
|
||||
}
|
||||
|
||||
void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::process_message()
|
||||
{
|
||||
if (message == 1)
|
||||
{
|
||||
detection_counter++;
|
||||
|
||||
// The term -5 is here to correct the additional delay introduced by the FIR filter
|
||||
double delay_error_chips = abs((double)expected_delay_chips - (double)(gnss_synchro.Acq_delay_samples - 5) * 1023.0 / ((double)fs_in * 1e-3));
|
||||
double doppler_error_hz = abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz);
|
||||
|
||||
mse_delay += std::pow(delay_error_chips, 2);
|
||||
mse_doppler += std::pow(doppler_error_hz, 2);
|
||||
|
||||
if ((delay_error_chips < max_delay_error_chips) && (doppler_error_hz < max_doppler_error_hz))
|
||||
{
|
||||
correct_estimation_counter++;
|
||||
}
|
||||
|
||||
}
|
||||
else if(message == 2 && gnss_synchro.PRN == 10)
|
||||
{
|
||||
/*
|
||||
if ((delay_error_chips < max_delay_error_chips) && (doppler_error_hz < max_doppler_error_hz))
|
||||
{
|
||||
miss_detection_counter++;
|
||||
}
|
||||
*/
|
||||
miss_detection_counter++;
|
||||
}
|
||||
|
||||
realization_counter++;
|
||||
|
||||
std::cout << "Progress: " << round((float)realization_counter / num_of_realizations * 100) << "% \r" << std::flush;
|
||||
|
||||
if (realization_counter == num_of_realizations)
|
||||
{
|
||||
mse_delay /= (double)num_of_realizations;
|
||||
mse_doppler /= (double)num_of_realizations;
|
||||
|
||||
Pd = (double)correct_estimation_counter / (double)num_of_realizations;
|
||||
Pfa_a = (double)detection_counter / (double)num_of_realizations;
|
||||
Pfa_p = (double)(detection_counter - correct_estimation_counter) / (double)num_of_realizations;
|
||||
Pmd = (double)miss_detection_counter / (double)num_of_realizations;
|
||||
|
||||
mean_acq_time_us /= (double)num_of_realizations;
|
||||
|
||||
stop_queue();
|
||||
top_block->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::stop_queue()
|
||||
{
|
||||
stop = true;
|
||||
}
|
||||
|
||||
|
||||
TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, Instantiate)
|
||||
{
|
||||
config_1();
|
||||
std::shared_ptr<GNSSBlockInterface> acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1, queue);
|
||||
acquisition = std::dynamic_pointer_cast<GalileoE1PcpsQuickSyncAmbiguousAcquisition>(acq_);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ConnectAndRun)
|
||||
{
|
||||
LOG(INFO) << "**Start connect and run test";
|
||||
int nsamples = floor(fs_in*integration_time_ms*1e-3);
|
||||
struct timeval tv;
|
||||
long long int begin = 0;
|
||||
long long int end = 0;
|
||||
|
||||
config_1();
|
||||
|
||||
std::shared_ptr<GNSSBlockInterface> acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1, queue);
|
||||
acquisition = std::dynamic_pointer_cast<GalileoE1PcpsQuickSyncAmbiguousAcquisition>(acq_);
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->connect(top_block);
|
||||
boost::shared_ptr<gr::analog::sig_source_c> source =
|
||||
gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0));
|
||||
boost::shared_ptr<gr::block> valve =
|
||||
gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue);
|
||||
top_block->connect(source, 0, valve, 0);
|
||||
top_block->connect(valve, 0, acquisition->get_left_block(), 0);
|
||||
|
||||
}) << "Failure connecting the blocks of acquisition test."<< std::endl;
|
||||
|
||||
EXPECT_NO_THROW( {
|
||||
gettimeofday(&tv, NULL);
|
||||
begin = tv.tv_sec * 1e6 + tv.tv_usec;
|
||||
top_block->run(); // Start threads and wait
|
||||
gettimeofday(&tv, NULL);
|
||||
end = tv.tv_sec * 1e6 + tv.tv_usec;
|
||||
}) << "Failure running the top_block."<< std::endl;
|
||||
|
||||
std::cout << "Processed " << nsamples << " samples in " << (end - begin) << " microseconds" << std::endl;
|
||||
LOG(INFO) << "----end connect and run test-----";
|
||||
LOG(INFO) << "**End connect and run test";
|
||||
}
|
||||
|
||||
TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResults)
|
||||
{
|
||||
LOG(INFO) << "Start validation of results test";
|
||||
config_1();
|
||||
|
||||
std::shared_ptr<GNSSBlockInterface> acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1, queue);
|
||||
acquisition = std::dynamic_pointer_cast<GalileoE1PcpsQuickSyncAmbiguousAcquisition>(acq_);
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel(1);
|
||||
}) << "Failure setting channel."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_gnss_synchro(&gnss_synchro);
|
||||
}) << "Failure setting gnss_synchro."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel_queue(&channel_internal_queue);
|
||||
}) << "Failure setting channel_internal_queue."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000));
|
||||
}) << "Failure setting doppler_max."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 125));
|
||||
}) << "Failure setting doppler_step."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_threshold(config->property("Acquisition.threshold", 0.0));
|
||||
}) << "Failure setting threshold."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->connect(top_block);
|
||||
}) << "Failure connecting acquisition to the top_block." << std::endl;
|
||||
|
||||
acquisition->init();
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
boost::shared_ptr<GenSignalSource> signal_source;
|
||||
SignalGenerator* signal_generator = new SignalGenerator(config.get(), "SignalSource", 0, 1, queue);
|
||||
FirFilter* filter = new FirFilter(config.get(), "InputFilter", 1, 1, queue);
|
||||
signal_source.reset(new GenSignalSource(config.get(), signal_generator, filter, "SignalSource", queue));
|
||||
signal_source->connect(top_block);
|
||||
top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0);
|
||||
}) << "Failure connecting the blocks of acquisition test." << std::endl;
|
||||
|
||||
// i = 0 --> satellite in acquisition is visible
|
||||
// i = 1 --> satellite in acquisition is not visible
|
||||
for (unsigned int i = 0; i < 2; i++)
|
||||
{
|
||||
init();
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
gnss_synchro.PRN = 10; // This satellite is visible
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
gnss_synchro.PRN = 20; // This satellite is not visible
|
||||
}
|
||||
|
||||
acquisition->set_local_code();
|
||||
start_queue();
|
||||
|
||||
EXPECT_NO_THROW( {
|
||||
top_block->run(); // Start threads and wait
|
||||
}) << "Failure running the top_block."<< std::endl;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
EXPECT_EQ(1, message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS.";
|
||||
if (message == 1)
|
||||
{
|
||||
EXPECT_EQ((unsigned int)1, correct_estimation_counter) << "Acquisition failure. Incorrect parameters estimation.";
|
||||
}
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
EXPECT_EQ(2, message) << "Acquisition failure. Expected message: 2=ACQ FAIL.";
|
||||
}
|
||||
}
|
||||
LOG(INFO) << "End validation of results test";
|
||||
}
|
||||
|
||||
|
||||
TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResultsWithNoise)
|
||||
{
|
||||
LOG(INFO) << "Start validation of results with noise+interference test";
|
||||
config_3();
|
||||
|
||||
std::shared_ptr<GNSSBlockInterface> acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1, queue);
|
||||
acquisition = std::dynamic_pointer_cast<GalileoE1PcpsQuickSyncAmbiguousAcquisition>(acq_);
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel(1);
|
||||
}) << "Failure setting channel."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_gnss_synchro(&gnss_synchro);
|
||||
}) << "Failure setting gnss_synchro."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel_queue(&channel_internal_queue);
|
||||
}) << "Failure setting channel_internal_queue."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000));
|
||||
}) << "Failure setting doppler_max."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 125));
|
||||
}) << "Failure setting doppler_step."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_threshold(config->property("Acquisition.threshold", 0.0));
|
||||
}) << "Failure setting threshold."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->connect(top_block);
|
||||
}) << "Failure connecting acquisition to the top_block." << std::endl;
|
||||
|
||||
acquisition->init();
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
boost::shared_ptr<GenSignalSource> signal_source;
|
||||
SignalGenerator* signal_generator = new SignalGenerator(config.get(), "SignalSource", 0, 1, queue);
|
||||
FirFilter* filter = new FirFilter(config.get(), "InputFilter", 1, 1, queue);
|
||||
signal_source.reset(new GenSignalSource(config.get(), signal_generator, filter, "SignalSource", queue));
|
||||
signal_source->connect(top_block);
|
||||
top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0);
|
||||
}) << "Failure connecting the blocks of acquisition test." << std::endl;
|
||||
|
||||
// i = 0 --> satellite in acquisition is visible
|
||||
// i = 1 --> satellite in acquisition is not visible
|
||||
for (unsigned int i = 0; i < 2; i++)
|
||||
{
|
||||
init();
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
gnss_synchro.PRN = 10; // This satellite is visible
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
gnss_synchro.PRN = 20; // This satellite is not visible
|
||||
}
|
||||
|
||||
acquisition->set_local_code();
|
||||
start_queue();
|
||||
|
||||
EXPECT_NO_THROW( {
|
||||
top_block->run(); // Start threads and wait
|
||||
}) << "Failure running the top_block."<< std::endl;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
EXPECT_EQ(1, message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS.";
|
||||
if (message == 1)
|
||||
{
|
||||
EXPECT_EQ((unsigned int)1, correct_estimation_counter) << "Acquisition failure. Incorrect parameters estimation.";
|
||||
}
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
EXPECT_EQ(2, message) << "Acquisition failure. Expected message: 2=ACQ FAIL.";
|
||||
}
|
||||
}
|
||||
LOG(INFO) << "End validation of results with noise+interference test";
|
||||
}
|
||||
|
||||
TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResultsProbabilities)
|
||||
{
|
||||
config_2();
|
||||
|
||||
std::shared_ptr<GNSSBlockInterface> acq_ = factory->GetBlock(config, "Acquisition", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1, queue);
|
||||
acquisition = std::dynamic_pointer_cast<GalileoE1PcpsQuickSyncAmbiguousAcquisition>(acq_);
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel(1);
|
||||
}) << "Failure setting channel."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_gnss_synchro(&gnss_synchro);
|
||||
}) << "Failure setting gnss_synchro."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel_queue(&channel_internal_queue);
|
||||
}) << "Failure setting channel_internal_queue."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000));
|
||||
}) << "Failure setting doppler_max."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500));
|
||||
}) << "Failure setting doppler_step."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_threshold(config->property("Acquisition.threshold", 0.0));
|
||||
}) << "Failure setting threshold."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->connect(top_block);
|
||||
}) << "Failure connecting acquisition to the top_block." << std::endl;
|
||||
|
||||
acquisition->init();
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
boost::shared_ptr<GenSignalSource> signal_source;
|
||||
SignalGenerator* signal_generator = new SignalGenerator(config.get(), "SignalSource", 0, 1, queue);
|
||||
FirFilter* filter = new FirFilter(config.get(), "InputFilter", 1, 1, queue);
|
||||
signal_source.reset(new GenSignalSource(config.get(), signal_generator, filter, "SignalSource", queue));
|
||||
signal_source->connect(top_block);
|
||||
top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0);
|
||||
}) << "Failure connecting the blocks of acquisition test." << std::endl;
|
||||
|
||||
std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl;
|
||||
|
||||
// i = 0 --> satellite in acquisition is visible (prob of detection and prob of detection with wrong estimation)
|
||||
// i = 1 --> satellite in acquisition is not visible (prob of false detection)
|
||||
for (unsigned int i = 0; i < 2; i++)
|
||||
{
|
||||
init();
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
gnss_synchro.PRN = 10; // This satellite is visible
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
gnss_synchro.PRN = 20; // This satellite is not visible
|
||||
}
|
||||
|
||||
acquisition->set_local_code();
|
||||
start_queue();
|
||||
|
||||
EXPECT_NO_THROW( {
|
||||
top_block->run(); // Start threads and wait
|
||||
}) << "Failure running the top_block." << std::endl;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
std::cout << "Estimated probability of detection = " << Pd << std::endl;
|
||||
std::cout << "Estimated probability of false alarm (satellite present) = " << Pfa_p << std::endl;
|
||||
std::cout << "Estimated probability of miss detection (satellite present) = " << Pmd << std::endl;
|
||||
std::cout << "Mean acq time = " << mean_acq_time_us << " microseconds." << std::endl;
|
||||
|
||||
if(dump_test_results)
|
||||
{
|
||||
std::stringstream filenamepd;
|
||||
filenamepd.str("");
|
||||
filenamepd << "../data/test_statistics_" << gnss_synchro.System
|
||||
<< "_" << gnss_synchro.Signal << "_sat_"
|
||||
<< gnss_synchro.PRN << "CN0_dB_0_" << FLAGS_e1_value_CN0_dB_0 << "_dBHz.csv";
|
||||
|
||||
pdpfafile.open(filenamepd.str().c_str(), std::ios::app | std::ios::out);
|
||||
pdpfafile << FLAGS_e1_value_threshold << "," << Pd << "," << Pfa_p << "," << Pmd << std::endl;
|
||||
pdpfafile.close();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
std::cout << "Estimated probability of false alarm (satellite absent) = " << Pfa_a << std::endl;
|
||||
std::cout << "Mean acq time = " << mean_acq_time_us << " microseconds." << std::endl;
|
||||
|
||||
if(dump_test_results)
|
||||
{
|
||||
std::stringstream filenamepf;
|
||||
filenamepf.str("");
|
||||
filenamepf << "../data/test_statistics_" << gnss_synchro.System
|
||||
<< "_" << gnss_synchro.Signal << "_sat_"
|
||||
<< gnss_synchro.PRN << "CN0_dB_0_" << FLAGS_e1_value_CN0_dB_0 << "_dBHz.csv";
|
||||
|
||||
pdpfafile.open(filenamepf.str().c_str(), std::ios::app | std::ios::out);
|
||||
pdpfafile << FLAGS_e1_value_threshold << "," << Pfa_a << std::endl;
|
||||
pdpfafile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@
|
||||
* 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.
|
||||
* (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
|
||||
@ -194,6 +194,31 @@ TEST(GNSS_Block_Factory_Test, InstantiateGpsL1CaPcpsAcquisition)
|
||||
}
|
||||
|
||||
|
||||
TEST(GNSS_Block_Factory_Test, InstantiateGpsL1CaPcpsQuickSyncAcquisition)
|
||||
{
|
||||
std::shared_ptr<InMemoryConfiguration> configuration = std::make_shared<InMemoryConfiguration>();
|
||||
configuration->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_QuickSync_Acquisition");
|
||||
gr::msg_queue::sptr queue = gr::msg_queue::make(0);
|
||||
std::shared_ptr<GNSSBlockFactory> factory = std::make_shared<GNSSBlockFactory>();
|
||||
std::shared_ptr<GNSSBlockInterface> acq_ = factory->GetBlock(configuration, "Acquisition", "GPS_L1_CA_PCPS_QuickSync_Acquisition", 1, 1, queue);
|
||||
std::shared_ptr<AcquisitionInterface> acquisition = std::dynamic_pointer_cast<AcquisitionInterface>(acq_);
|
||||
EXPECT_STREQ("Acquisition", acquisition->role().c_str());
|
||||
EXPECT_STREQ("GPS_L1_CA_PCPS_QuickSync_Acquisition", acquisition->implementation().c_str());
|
||||
}
|
||||
|
||||
TEST(GNSS_Block_Factory_Test, InstantiateGalileoE1PcpsQuickSyncAmbiguousAcquisition)
|
||||
{
|
||||
std::shared_ptr<InMemoryConfiguration> configuration = std::make_shared<InMemoryConfiguration>();
|
||||
configuration->set_property("Acquisition.implementation", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition");
|
||||
gr::msg_queue::sptr queue = gr::msg_queue::make(0);
|
||||
std::shared_ptr<GNSSBlockFactory> factory = std::make_shared<GNSSBlockFactory>();
|
||||
std::shared_ptr<GNSSBlockInterface> acq_ = factory->GetBlock(configuration, "Acquisition", "Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", 1, 1, queue);
|
||||
std::shared_ptr<AcquisitionInterface> acquisition = std::dynamic_pointer_cast<AcquisitionInterface>(acq_);
|
||||
EXPECT_STREQ("Acquisition", acquisition->role().c_str());
|
||||
EXPECT_STREQ("Galileo_E1_PCPS_QuickSync_Ambiguous_Acquisition", acquisition->implementation().c_str());
|
||||
}
|
||||
|
||||
|
||||
TEST(GNSS_Block_Factory_Test, InstantiateGalileoE1PcpsAmbiguousAcquisition)
|
||||
{
|
||||
std::shared_ptr<InMemoryConfiguration> configuration = std::make_shared<InMemoryConfiguration>();
|
||||
|
@ -0,0 +1,804 @@
|
||||
/*!
|
||||
* \file gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc
|
||||
* \brief This class implements an acquisition test for
|
||||
* GpsL1CaPcpsQuickSyncAcquisition class based on some input parameters.
|
||||
* \author Damian Miralles Sanchez, 2014. dmiralles2009(at)gmail.com
|
||||
*
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2014 (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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/top_block.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/analog/sig_source_waveform.h>
|
||||
#include <gnuradio/analog/sig_source_c.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/blocks/null_sink.h>
|
||||
#include "gnss_block_factory.h"
|
||||
#include "gnss_block_interface.h"
|
||||
#include "in_memory_configuration.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include "gnss_synchro.h"
|
||||
#include "gps_l1_ca_pcps_quicksync_acquisition.h"
|
||||
|
||||
DEFINE_double(value_threshold, 0.3, "Value of the threshold for the acquisition");
|
||||
DEFINE_int32(value_CN0_dB_0, 44, "Value for the CN0_dB_0 in channel 0");
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
class GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test()
|
||||
{
|
||||
queue = gr::msg_queue::make(0);
|
||||
top_block = gr::make_top_block("Acquisition test");
|
||||
factory = std::make_shared<GNSSBlockFactory>();
|
||||
item_size = sizeof(gr_complex);
|
||||
stop = false;
|
||||
message = 0;
|
||||
}
|
||||
|
||||
~GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test()
|
||||
{}
|
||||
|
||||
void init();
|
||||
void config_1();
|
||||
void config_2();
|
||||
void config_3();
|
||||
void start_queue();
|
||||
void wait_message();
|
||||
void process_message();
|
||||
void stop_queue();
|
||||
|
||||
gr::msg_queue::sptr queue;
|
||||
gr::top_block_sptr top_block;
|
||||
std::shared_ptr<GNSSBlockFactory> factory;
|
||||
std::shared_ptr<GpsL1CaPcpsQuickSyncAcquisition> acquisition;
|
||||
std::shared_ptr<InMemoryConfiguration> config;
|
||||
Gnss_Synchro gnss_synchro;
|
||||
size_t item_size;
|
||||
concurrent_queue<int> channel_internal_queue;
|
||||
bool stop;
|
||||
int message;
|
||||
boost::thread ch_thread;
|
||||
|
||||
unsigned int integration_time_ms;
|
||||
unsigned int fs_in;
|
||||
unsigned int folding_factor;
|
||||
|
||||
double expected_delay_chips;
|
||||
double expected_doppler_hz;
|
||||
float max_doppler_error_hz;
|
||||
float max_delay_error_chips;
|
||||
|
||||
unsigned int num_of_realizations;
|
||||
unsigned int realization_counter;
|
||||
unsigned int detection_counter;
|
||||
unsigned int correct_estimation_counter;
|
||||
unsigned int acquired_samples;
|
||||
unsigned int mean_acq_time_us;
|
||||
|
||||
double mse_doppler;
|
||||
double mse_delay;
|
||||
|
||||
double Pd;
|
||||
double Pfa_p;
|
||||
double Pfa_a;
|
||||
double Pmd;
|
||||
|
||||
std::ofstream pdpfafile;
|
||||
unsigned int miss_detection_counter;
|
||||
bool dump_test_results;
|
||||
};
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::init()
|
||||
{
|
||||
message = 0;
|
||||
realization_counter = 0;
|
||||
detection_counter = 0;
|
||||
correct_estimation_counter = 0;
|
||||
acquired_samples = 0;
|
||||
mse_doppler = 0;
|
||||
mse_delay = 0;
|
||||
mean_acq_time_us = 0;
|
||||
Pd = 0;
|
||||
Pfa_p = 0;
|
||||
Pfa_a = 0;
|
||||
|
||||
miss_detection_counter = 0;
|
||||
Pmd = 0;
|
||||
|
||||
}
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::config_1()
|
||||
{
|
||||
gnss_synchro.Channel_ID = 0;
|
||||
gnss_synchro.System = 'G';
|
||||
std::string signal = "1C";
|
||||
signal.copy(gnss_synchro.Signal,2,0);
|
||||
|
||||
integration_time_ms = 4;
|
||||
fs_in = 8e6;
|
||||
|
||||
expected_delay_chips = 600;
|
||||
expected_doppler_hz = 750;
|
||||
max_doppler_error_hz = 2/(3*integration_time_ms*1e-3);
|
||||
max_delay_error_chips = 0.50;
|
||||
|
||||
num_of_realizations = 1;
|
||||
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
|
||||
config->set_property("GNSS-SDR.internal_fs_hz", std::to_string(fs_in));
|
||||
|
||||
config->set_property("SignalSource.fs_hz", std::to_string(fs_in));
|
||||
config->set_property("SignalSource.item_type", "gr_complex");
|
||||
config->set_property("SignalSource.num_satellites", "1");
|
||||
config->set_property("SignalSource.repeat", "true");
|
||||
|
||||
config->set_property("SignalSource.system_0", "G");
|
||||
config->set_property("SignalSource.PRN_0", "10");
|
||||
config->set_property("SignalSource.CN0_dB_0", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_0", std::to_string(expected_doppler_hz));
|
||||
config->set_property("SignalSource.delay_chips_0", std::to_string(expected_delay_chips));
|
||||
|
||||
config->set_property("SignalSource.noise_flag", "false");
|
||||
config->set_property("SignalSource.data_flag", "false");
|
||||
config->set_property("SignalSource.BW_BB", "0.97");
|
||||
|
||||
config->set_property("InputFilter.implementation", "Fir_Filter");
|
||||
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", "11");
|
||||
config->set_property("InputFilter.number_of_bands", "2");
|
||||
config->set_property("InputFilter.band1_begin", "0.0");
|
||||
config->set_property("InputFilter.band1_end", "0.97");
|
||||
config->set_property("InputFilter.band2_begin", "0.98");
|
||||
config->set_property("InputFilter.band2_end", "1.0");
|
||||
config->set_property("InputFilter.ampl1_begin", "1.0");
|
||||
config->set_property("InputFilter.ampl1_end", "1.0");
|
||||
config->set_property("InputFilter.ampl2_begin", "0.0");
|
||||
config->set_property("InputFilter.ampl2_end", "0.0");
|
||||
config->set_property("InputFilter.band1_error", "1.0");
|
||||
config->set_property("InputFilter.band2_error", "1.0");
|
||||
config->set_property("InputFilter.filter_type", "bandpass");
|
||||
config->set_property("InputFilter.grid_density", "16");
|
||||
|
||||
config->set_property("Acquisition.item_type", "gr_complex");
|
||||
config->set_property("Acquisition.if", "0");
|
||||
config->set_property("Acquisition.coherent_integration_time_ms",
|
||||
std::to_string(integration_time_ms));
|
||||
config->set_property("Acquisition.max_dwells", "1");
|
||||
config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_QuickSync_Acquisition");
|
||||
config->set_property("Acquisition.threshold", "100");
|
||||
config->set_property("Acquisition.doppler_max", "10000");
|
||||
config->set_property("Acquisition.doppler_step", "250");
|
||||
config->set_property("Acquisition.bit_transition_flag", "false");
|
||||
config->set_property("Acquisition.dump", "true");
|
||||
}
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::config_2()
|
||||
{
|
||||
gnss_synchro.Channel_ID = 0;
|
||||
gnss_synchro.System = 'G';
|
||||
std::string signal = "1C";
|
||||
signal.copy(gnss_synchro.Signal,2,0);
|
||||
|
||||
integration_time_ms = 4;
|
||||
fs_in = 8e6;
|
||||
|
||||
expected_delay_chips = 600;
|
||||
expected_doppler_hz = 750;
|
||||
max_doppler_error_hz = 2/(3*integration_time_ms*1e-3);
|
||||
max_delay_error_chips = 0.50;
|
||||
|
||||
/*Unset this flag to eliminates data logging for the Validation of results
|
||||
probabilities test*/
|
||||
dump_test_results = true;
|
||||
|
||||
num_of_realizations = 100;
|
||||
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
|
||||
config->set_property("GNSS-SDR.internal_fs_hz", std::to_string(fs_in));
|
||||
|
||||
config->set_property("SignalSource.fs_hz", std::to_string(fs_in));
|
||||
|
||||
config->set_property("SignalSource.item_type", "gr_complex");
|
||||
|
||||
config->set_property("SignalSource.num_satellites", "4");
|
||||
|
||||
config->set_property("SignalSource.system_0", "G");
|
||||
config->set_property("SignalSource.PRN_0", "10");
|
||||
config->set_property("SignalSource.CN0_dB_0", std::to_string(FLAGS_value_CN0_dB_0));
|
||||
config->set_property("SignalSource.doppler_Hz_0", std::to_string(expected_doppler_hz));
|
||||
config->set_property("SignalSource.delay_chips_0", std::to_string(expected_delay_chips));
|
||||
|
||||
config->set_property("SignalSource.system_1", "G");
|
||||
config->set_property("SignalSource.PRN_1", "15");
|
||||
config->set_property("SignalSource.CN0_dB_1", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_1", "1000");
|
||||
config->set_property("SignalSource.delay_chips_1", "100");
|
||||
|
||||
config->set_property("SignalSource.system_2", "G");
|
||||
config->set_property("SignalSource.PRN_2", "21");
|
||||
config->set_property("SignalSource.CN0_dB_2", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_2", "2000");
|
||||
config->set_property("SignalSource.delay_chips_2", "200");
|
||||
|
||||
config->set_property("SignalSource.system_3", "G");
|
||||
config->set_property("SignalSource.PRN_3", "22");
|
||||
config->set_property("SignalSource.CN0_dB_3", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_3", "3000");
|
||||
config->set_property("SignalSource.delay_chips_3", "300");
|
||||
|
||||
config->set_property("SignalSource.noise_flag", "true");
|
||||
config->set_property("SignalSource.data_flag", "true");
|
||||
config->set_property("SignalSource.BW_BB", "0.97");
|
||||
|
||||
config->set_property("InputFilter.implementation", "Fir_Filter");
|
||||
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", "11");
|
||||
config->set_property("InputFilter.number_of_bands", "2");
|
||||
config->set_property("InputFilter.band1_begin", "0.0");
|
||||
config->set_property("InputFilter.band1_end", "0.97");
|
||||
config->set_property("InputFilter.band2_begin", "0.98");
|
||||
config->set_property("InputFilter.band2_end", "1.0");
|
||||
config->set_property("InputFilter.ampl1_begin", "1.0");
|
||||
config->set_property("InputFilter.ampl1_end", "1.0");
|
||||
config->set_property("InputFilter.ampl2_begin", "0.0");
|
||||
config->set_property("InputFilter.ampl2_end", "0.0");
|
||||
config->set_property("InputFilter.band1_error", "1.0");
|
||||
config->set_property("InputFilter.band2_error", "1.0");
|
||||
config->set_property("InputFilter.filter_type", "bandpass");
|
||||
config->set_property("InputFilter.grid_density", "16");
|
||||
|
||||
config->set_property("Acquisition.item_type", "gr_complex");
|
||||
config->set_property("Acquisition.if", "0");
|
||||
config->set_property("Acquisition.coherent_integration_time_ms",
|
||||
std::to_string(integration_time_ms));
|
||||
config->set_property("Acquisition.max_dwells", "1");
|
||||
config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_QuickSync_Acquisition");
|
||||
config->set_property("Acquisition.threshold", std::to_string(FLAGS_value_threshold));
|
||||
config->set_property("Acquisition.doppler_max", "10000");
|
||||
config->set_property("Acquisition.doppler_step", "250");
|
||||
config->set_property("Acquisition.bit_transition_flag", "false");
|
||||
config->set_property("Acquisition.dump", "false");
|
||||
}
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::config_3()
|
||||
{
|
||||
gnss_synchro.Channel_ID = 0;
|
||||
gnss_synchro.System = 'G';
|
||||
std::string signal = "1C";
|
||||
signal.copy(gnss_synchro.Signal,2,0);
|
||||
|
||||
integration_time_ms = 4;
|
||||
fs_in = 4e6;
|
||||
|
||||
expected_delay_chips = 600;
|
||||
expected_doppler_hz = 750;
|
||||
max_doppler_error_hz = 2/(3*integration_time_ms*1e-3);
|
||||
max_delay_error_chips = 0.50;
|
||||
|
||||
/*Unset this flag to eliminates data logging for the Validation of results
|
||||
probabilities test*/
|
||||
dump_test_results = true;
|
||||
|
||||
num_of_realizations = 1;
|
||||
|
||||
config = std::make_shared<InMemoryConfiguration>();
|
||||
|
||||
config->set_property("GNSS-SDR.internal_fs_hz", std::to_string(fs_in));
|
||||
|
||||
config->set_property("SignalSource.fs_hz", std::to_string(fs_in));
|
||||
|
||||
config->set_property("SignalSource.item_type", "gr_complex");
|
||||
|
||||
config->set_property("SignalSource.num_satellites", "4");
|
||||
|
||||
config->set_property("SignalSource.system_0", "G");
|
||||
config->set_property("SignalSource.PRN_0", "10");
|
||||
config->set_property("SignalSource.CN0_dB_0", std::to_string(FLAGS_value_CN0_dB_0));
|
||||
config->set_property("SignalSource.doppler_Hz_0", std::to_string(expected_doppler_hz));
|
||||
config->set_property("SignalSource.delay_chips_0", std::to_string(expected_delay_chips));
|
||||
|
||||
config->set_property("SignalSource.system_1", "G");
|
||||
config->set_property("SignalSource.PRN_1", "15");
|
||||
config->set_property("SignalSource.CN0_dB_1", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_1", "1000");
|
||||
config->set_property("SignalSource.delay_chips_1", "100");
|
||||
|
||||
config->set_property("SignalSource.system_2", "G");
|
||||
config->set_property("SignalSource.PRN_2", "21");
|
||||
config->set_property("SignalSource.CN0_dB_2", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_2", "2000");
|
||||
config->set_property("SignalSource.delay_chips_2", "200");
|
||||
|
||||
config->set_property("SignalSource.system_3", "G");
|
||||
config->set_property("SignalSource.PRN_3", "22");
|
||||
config->set_property("SignalSource.CN0_dB_3", "44");
|
||||
config->set_property("SignalSource.doppler_Hz_3", "3000");
|
||||
config->set_property("SignalSource.delay_chips_3", "300");
|
||||
|
||||
config->set_property("SignalSource.noise_flag", "true");
|
||||
config->set_property("SignalSource.data_flag", "true");
|
||||
config->set_property("SignalSource.BW_BB", "0.97");
|
||||
|
||||
config->set_property("InputFilter.implementation", "Fir_Filter");
|
||||
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", "11");
|
||||
config->set_property("InputFilter.number_of_bands", "2");
|
||||
config->set_property("InputFilter.band1_begin", "0.0");
|
||||
config->set_property("InputFilter.band1_end", "0.97");
|
||||
config->set_property("InputFilter.band2_begin", "0.98");
|
||||
config->set_property("InputFilter.band2_end", "1.0");
|
||||
config->set_property("InputFilter.ampl1_begin", "1.0");
|
||||
config->set_property("InputFilter.ampl1_end", "1.0");
|
||||
config->set_property("InputFilter.ampl2_begin", "0.0");
|
||||
config->set_property("InputFilter.ampl2_end", "0.0");
|
||||
config->set_property("InputFilter.band1_error", "1.0");
|
||||
config->set_property("InputFilter.band2_error", "1.0");
|
||||
config->set_property("InputFilter.filter_type", "bandpass");
|
||||
config->set_property("InputFilter.grid_density", "16");
|
||||
|
||||
config->set_property("Acquisition.item_type", "gr_complex");
|
||||
config->set_property("Acquisition.if", "0");
|
||||
config->set_property("Acquisition.coherent_integration_time_ms",
|
||||
std::to_string(integration_time_ms));
|
||||
config->set_property("Acquisition.max_dwells", "1");
|
||||
config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_QuickSync_Acquisition");
|
||||
config->set_property("Acquisition.threshold", "1.2");
|
||||
config->set_property("Acquisition.doppler_max", "10000");
|
||||
config->set_property("Acquisition.doppler_step", "250");
|
||||
config->set_property("Acquisition.bit_transition_flag", "false");
|
||||
config->set_property("Acquisition.dump", "true");
|
||||
}
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::start_queue()
|
||||
{
|
||||
stop = false;
|
||||
ch_thread = boost::thread(&GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::wait_message, this);
|
||||
}
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::wait_message()
|
||||
{
|
||||
struct timeval tv;
|
||||
long long int begin = 0;
|
||||
long long int end = 0;
|
||||
|
||||
while (!stop)
|
||||
{
|
||||
acquisition->reset();
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
begin = tv.tv_sec * 1e6 + tv.tv_usec;
|
||||
|
||||
channel_internal_queue.wait_and_pop(message);
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
end = tv.tv_sec * 1e6 + tv.tv_usec;
|
||||
|
||||
mean_acq_time_us += (end - begin);
|
||||
|
||||
process_message();
|
||||
}
|
||||
}
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::process_message()
|
||||
{
|
||||
|
||||
if (message == 1)
|
||||
{
|
||||
detection_counter++;
|
||||
|
||||
// The term -5 is here to correct the additional delay introduced by the FIR filter
|
||||
double delay_error_chips = abs((double)expected_delay_chips - (double)(gnss_synchro.Acq_delay_samples - 5) * 1023.0/ ((double)fs_in * 1e-3));
|
||||
double doppler_error_hz = abs(expected_doppler_hz - gnss_synchro.Acq_doppler_hz);
|
||||
|
||||
mse_delay += std::pow(delay_error_chips, 2);
|
||||
mse_doppler += std::pow(doppler_error_hz, 2);
|
||||
|
||||
if ((delay_error_chips < max_delay_error_chips) && (doppler_error_hz < max_doppler_error_hz))
|
||||
{
|
||||
correct_estimation_counter++;
|
||||
}
|
||||
}
|
||||
else if(message == 2 && gnss_synchro.PRN == 10)
|
||||
{
|
||||
miss_detection_counter++;
|
||||
}
|
||||
|
||||
realization_counter++;
|
||||
|
||||
std::cout << "Progress: " << round((float)realization_counter/num_of_realizations*100) << "% \r" << std::flush;
|
||||
|
||||
if (realization_counter == num_of_realizations)
|
||||
{
|
||||
mse_delay /= num_of_realizations;
|
||||
mse_doppler /= num_of_realizations;
|
||||
|
||||
Pd = (double)correct_estimation_counter / (double)num_of_realizations;
|
||||
Pfa_a = (double)detection_counter / (double)num_of_realizations;
|
||||
Pfa_p = (double)(detection_counter-correct_estimation_counter) / (double)num_of_realizations;
|
||||
Pmd = (double)miss_detection_counter / (double)num_of_realizations;
|
||||
|
||||
mean_acq_time_us /= num_of_realizations;
|
||||
|
||||
stop_queue();
|
||||
top_block->stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::stop_queue()
|
||||
{
|
||||
stop = true;
|
||||
}
|
||||
|
||||
|
||||
TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, Instantiate)
|
||||
{
|
||||
config_1();
|
||||
acquisition = std::make_shared<GpsL1CaPcpsQuickSyncAcquisition>(config.get(), "Acquisition", 1, 1, queue);
|
||||
}
|
||||
|
||||
TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ConnectAndRun)
|
||||
{
|
||||
int nsamples = floor(fs_in*integration_time_ms*1e-3);
|
||||
struct timeval tv;
|
||||
long long int begin = 0;
|
||||
long long int end = 0;
|
||||
|
||||
config_1();
|
||||
acquisition = std::make_shared<GpsL1CaPcpsQuickSyncAcquisition>(config.get(), "Acquisition", 1, 1, queue);
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->connect(top_block);
|
||||
boost::shared_ptr<gr::analog::sig_source_c> source = gr::analog::sig_source_c::make(fs_in, gr::analog::GR_SIN_WAVE, 1000, 1, gr_complex(0));
|
||||
boost::shared_ptr<gr::block> valve = gnss_sdr_make_valve(sizeof(gr_complex), nsamples, queue);
|
||||
top_block->connect(source, 0, valve, 0);
|
||||
top_block->connect(valve, 0, acquisition->get_left_block(), 0);
|
||||
}) << "Failure connecting the blocks of acquisition test."<< std::endl;
|
||||
|
||||
EXPECT_NO_THROW( {
|
||||
gettimeofday(&tv, NULL);
|
||||
begin = tv.tv_sec *1e6 + tv.tv_usec;
|
||||
top_block->run(); // Start threads and wait
|
||||
gettimeofday(&tv, NULL);
|
||||
end = tv.tv_sec *1e6 + tv.tv_usec;
|
||||
}) << "Failure running the top_block."<< std::endl;
|
||||
|
||||
std::cout << "Processed " << nsamples << " samples in " << (end-begin) << " microseconds" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResults)
|
||||
{
|
||||
config_1();
|
||||
|
||||
acquisition = std::make_shared<GpsL1CaPcpsQuickSyncAcquisition>(config.get(), "Acquisition", 1, 1, queue);
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel(1);
|
||||
}) << "Failure setting channel."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_gnss_synchro(&gnss_synchro);
|
||||
}) << "Failure setting gnss_synchro."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel_queue(&channel_internal_queue);
|
||||
}) << "Failure setting channel_internal_queue."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000));
|
||||
}) << "Failure setting doppler_max."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 250));
|
||||
}) << "Failure setting doppler_step."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_threshold(config->property("Acquisition.threshold", 0.0));
|
||||
}) << "Failure setting threshold."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->connect(top_block);
|
||||
}) << "Failure connecting acquisition to the top_block."<< std::endl;
|
||||
|
||||
acquisition->init();
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
boost::shared_ptr<GenSignalSource> signal_source;
|
||||
SignalGenerator* signal_generator = new SignalGenerator(config.get(), "SignalSource", 0, 1, queue);
|
||||
FirFilter* filter = new FirFilter(config.get(), "InputFilter", 1, 1, queue);
|
||||
signal_source.reset(new GenSignalSource(config.get(), signal_generator, filter, "SignalSource", queue));
|
||||
signal_source->connect(top_block);
|
||||
top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0);
|
||||
}) << "Failure connecting the blocks of acquisition test." << std::endl;
|
||||
|
||||
// i = 0 --> satellite in acquisition is visible
|
||||
// i = 1 --> satellite in acquisition is not visible
|
||||
|
||||
for (unsigned int i = 0; i < 2; i++)
|
||||
{
|
||||
init();
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
gnss_synchro.PRN = 10; // This satellite is visible
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
gnss_synchro.PRN = 20; // This satellite is not visible
|
||||
}
|
||||
|
||||
acquisition->set_local_code();
|
||||
start_queue();
|
||||
|
||||
EXPECT_NO_THROW( {
|
||||
top_block->run(); // Start threads and wait
|
||||
}) << "Failure running the top_block." << std::endl;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
EXPECT_EQ(1, message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS.";
|
||||
if (message == 1)
|
||||
{
|
||||
|
||||
EXPECT_EQ((unsigned int)1, correct_estimation_counter)
|
||||
<< "Acquisition failure. Incorrect parameters estimation.";
|
||||
}
|
||||
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
EXPECT_EQ(2, message)
|
||||
<< "Acquisition failure. Expected message: 2=ACQ FAIL.";
|
||||
}
|
||||
}
|
||||
unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples;
|
||||
std::cout << "----Acquired: " << nsamples << " samples"<< std::endl;
|
||||
}
|
||||
|
||||
|
||||
TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResultsWithNoise)
|
||||
{
|
||||
config_3();
|
||||
|
||||
acquisition = std::make_shared<GpsL1CaPcpsQuickSyncAcquisition>(config.get(), "Acquisition", 1, 1, queue);
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel(1);
|
||||
}) << "Failure setting channel."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_gnss_synchro(&gnss_synchro);
|
||||
}) << "Failure setting gnss_synchro."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel_queue(&channel_internal_queue);
|
||||
}) << "Failure setting channel_internal_queue."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000));
|
||||
}) << "Failure setting doppler_max."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 250));
|
||||
}) << "Failure setting doppler_step."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_threshold(config->property("Acquisition.threshold", 0.0));
|
||||
}) << "Failure setting threshold."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->connect(top_block);
|
||||
}) << "Failure connecting acquisition to the top_block."<< std::endl;
|
||||
|
||||
acquisition->init();
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
boost::shared_ptr<GenSignalSource> signal_source;
|
||||
SignalGenerator* signal_generator = new SignalGenerator(config.get(), "SignalSource", 0, 1, queue);
|
||||
FirFilter* filter = new FirFilter(config.get(), "InputFilter", 1, 1, queue);
|
||||
signal_source.reset(new GenSignalSource(config.get(), signal_generator, filter, "SignalSource", queue));
|
||||
signal_source->connect(top_block);
|
||||
top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0);
|
||||
}) << "Failure connecting the blocks of acquisition test." << std::endl;
|
||||
|
||||
// i = 0 --> satellite in acquisition is visible
|
||||
// i = 1 --> satellite in acquisition is not visible
|
||||
|
||||
for (unsigned int i = 0; i < 2; i++)
|
||||
{
|
||||
init();
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
gnss_synchro.PRN = 10; // This satellite is visible
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
gnss_synchro.PRN = 20; // This satellite is not visible
|
||||
}
|
||||
|
||||
acquisition->set_local_code();
|
||||
start_queue();
|
||||
|
||||
EXPECT_NO_THROW( {
|
||||
top_block->run(); // Start threads and wait
|
||||
}) << "Failure running the top_block." << std::endl;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
EXPECT_EQ(1, message) << "Acquisition failure. Expected message: 1=ACQ SUCCESS.";
|
||||
if (message == 1)
|
||||
{
|
||||
|
||||
EXPECT_EQ((unsigned int)1, correct_estimation_counter)
|
||||
<< "Acquisition failure. Incorrect parameters estimation.";
|
||||
}
|
||||
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
EXPECT_EQ(2, message)
|
||||
<< "Acquisition failure. Expected message: 2=ACQ FAIL.";
|
||||
}
|
||||
}
|
||||
unsigned long int nsamples = gnss_synchro.Acq_samplestamp_samples;
|
||||
std::cout << "----Acquired: " << nsamples << " samples"<< std::endl;
|
||||
}
|
||||
|
||||
|
||||
TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResultsProbabilities)
|
||||
{
|
||||
config_2();
|
||||
|
||||
acquisition = std::make_shared<GpsL1CaPcpsQuickSyncAcquisition>(config.get(), "Acquisition", 1, 1, queue);
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel(1);
|
||||
}) << "Failure setting channel."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_gnss_synchro(&gnss_synchro);
|
||||
}) << "Failure setting gnss_synchro."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_channel_queue(&channel_internal_queue);
|
||||
}) << "Failure setting channel_internal_queue."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_max(config->property("Acquisition.doppler_max", 10000));
|
||||
}) << "Failure setting doppler_max."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_doppler_step(config->property("Acquisition.doppler_step", 500));
|
||||
}) << "Failure setting doppler_step."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->set_threshold(config->property("Acquisition.threshold", 0.0));
|
||||
}) << "Failure setting threshold."<< std::endl;
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
acquisition->connect(top_block);
|
||||
}) << "Failure connecting acquisition to the top_block."<< std::endl;
|
||||
|
||||
acquisition->init();
|
||||
|
||||
ASSERT_NO_THROW( {
|
||||
boost::shared_ptr<GenSignalSource> signal_source;
|
||||
SignalGenerator* signal_generator = new SignalGenerator(config.get(), "SignalSource", 0, 1, queue);
|
||||
FirFilter* filter = new FirFilter(config.get(), "InputFilter", 1, 1, queue);
|
||||
signal_source.reset(new GenSignalSource(config.get(), signal_generator, filter, "SignalSource", queue));
|
||||
signal_source->connect(top_block);
|
||||
top_block->connect(signal_source->get_right_block(), 0, acquisition->get_left_block(), 0);
|
||||
}) << "Failure connecting the blocks of acquisition test." << std::endl;
|
||||
|
||||
std::cout << "Probability of false alarm (target) = " << 0.1 << std::endl;
|
||||
|
||||
// i = 0 --> satellite in acquisition is visible (prob of detection and prob of detection with wrong estimation)
|
||||
// i = 1 --> satellite in acquisition is not visible (prob of false detection)
|
||||
for (unsigned int i = 0; i < 2; i++)
|
||||
{
|
||||
init();
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
gnss_synchro.PRN = 10; // This satellite is visible
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
gnss_synchro.PRN = 20; // This satellite is not visible
|
||||
}
|
||||
|
||||
acquisition->set_local_code();
|
||||
start_queue();
|
||||
|
||||
|
||||
EXPECT_NO_THROW( {
|
||||
top_block->run(); // Start threads and wait
|
||||
}) << "Failure running the top_block." << std::endl;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
std::cout << "Estimated probability of detection = " << Pd << std::endl;
|
||||
std::cout << "Estimated probability of false alarm (satellite present) = " << Pfa_p << std::endl;
|
||||
std::cout << "Estimated probability of miss detection (satellite present) = " << Pmd << std::endl;
|
||||
std::cout << "Mean acq time = " << mean_acq_time_us << " microseconds." << std::endl;
|
||||
|
||||
if(dump_test_results)
|
||||
{
|
||||
std::stringstream filenamepd;
|
||||
filenamepd.str("");
|
||||
filenamepd << "../data/test_statistics_" << gnss_synchro.System
|
||||
<< "_" << gnss_synchro.Signal << "_sat_"
|
||||
<< gnss_synchro.PRN << "CN0_dB_0_" << FLAGS_value_CN0_dB_0 << "_dBHz.csv";
|
||||
|
||||
pdpfafile.open(filenamepd.str().c_str(), std::ios::app | std::ios::out);
|
||||
pdpfafile << FLAGS_value_threshold << "," << Pd << "," << Pfa_p << "," << Pmd << std::endl;
|
||||
pdpfafile.close();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
std::cout << "Estimated probability of false alarm (satellite absent) = " << Pfa_a << std::endl;
|
||||
std::cout << "Mean acq time = " << mean_acq_time_us << " microseconds." << std::endl;
|
||||
|
||||
if(dump_test_results)
|
||||
{
|
||||
std::stringstream filenamepf;
|
||||
filenamepf.str("");
|
||||
filenamepf << "../data/test_statistics_" << gnss_synchro.System
|
||||
<< "_" << gnss_synchro.Signal << "_sat_"
|
||||
<< gnss_synchro.PRN << "CN0_dB_0_" << FLAGS_value_CN0_dB_0 << "_dBHz.csv";
|
||||
|
||||
pdpfafile.open(filenamepf.str().c_str(), std::ios::app | std::ios::out);
|
||||
pdpfafile << FLAGS_value_threshold << "," << Pfa_a << std::endl;
|
||||
pdpfafile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -90,6 +90,7 @@ DECLARE_string(log_dir);
|
||||
#if OPENCL_BLOCKS_TEST
|
||||
#include "gnss_block/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc"
|
||||
#endif
|
||||
#include "gnss_block/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc"
|
||||
#include "gnss_block/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc"
|
||||
#include "gnss_block/galileo_e1_pcps_ambiguous_acquisition_test.cc"
|
||||
#include "gnss_block/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc"
|
||||
@ -97,6 +98,7 @@ DECLARE_string(log_dir);
|
||||
#include "gnss_block/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc"
|
||||
#include "gnss_block/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc"
|
||||
#include "gnss_block/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc"
|
||||
#include "gnss_block/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc"
|
||||
#include "gnss_block/galileo_e1_dll_pll_veml_tracking_test.cc"
|
||||
#include "gnuradio_block/gnss_sdr_valve_test.cc"
|
||||
#include "gnuradio_block/direct_resampler_conditioner_cc_test.cc"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# Copyright (C) 2012-2013 (see AUTHORS file for a list of contributors)
|
||||
# Copyright (C) 2012-2014 (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.
|
||||
# (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
|
||||
@ -17,11 +17,7 @@
|
||||
#
|
||||
|
||||
|
||||
if($ENV{RTLSDR_DRIVER})
|
||||
set(RTLSDR_DRIVER ON)
|
||||
endif($ENV{RTLSDR_DRIVER})
|
||||
|
||||
if(RTLSDR_DRIVER)
|
||||
if(ENABLE_RTLSDR)
|
||||
set(FRONT_END_CAL_SOURCES front_end_cal.cc)
|
||||
|
||||
include_directories(
|
||||
@ -76,4 +72,4 @@ if(RTLSDR_DRIVER)
|
||||
DESTINATION ${CMAKE_SOURCE_DIR}/install
|
||||
)
|
||||
|
||||
endif(RTLSDR_DRIVER)
|
||||
endif(ENABLE_RTLSDR)
|
||||
|
Loading…
Reference in New Issue
Block a user