1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-01-18 21:23:02 +00:00

Merge branch 'next' into update-cpu-features

This commit is contained in:
Carles Fernandez 2022-02-23 12:52:19 +01:00
commit c61cd6180e
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
60 changed files with 1993 additions and 1013 deletions

40
.github/workflows/citation.yml vendored Normal file
View File

@ -0,0 +1,40 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2022 Carles Fernandez-Prades <carles.fernandez@cttc.es>
on:
push:
paths:
- CITATION.cff
workflow_dispatch:
pull_request:
paths:
- CITATION.cff
workflow_dispatch:
name: CITATION.cff
jobs:
Validate-CITATION-cff:
runs-on: ubuntu-latest
name: Validate CITATION.cff
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
RSPM: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"
steps:
- name: Checkout
uses: actions/checkout@v2
# This is needed for workflows running on
# ubuntu-20.04 or later
- name: Install V8
if: runner.os == 'Linux'
run: |
sudo apt-get install -y libv8-dev
- name: Validate CITATION.cff
uses: dieghernan/cff-validator@main
# Upload artifact
- uses: actions/upload-artifact@v2
if: failure()
with:
name: citation-cff-errors
path: citation_cff_errors.md

View File

@ -2,7 +2,13 @@
# SPDX-FileCopyrightText: 2020 Carles Fernandez-Prades <carles.fernandez@cttc.es>
name: Simple CI
on: [push, pull_request]
on:
pull_request:
paths-ignore:
- '**/CITATION.cff'
push:
paths-ignore:
- '**/CITATION.cff'
jobs:
build-ubuntu:

View File

@ -60,6 +60,7 @@ Marc Molina marc.molina.pena@gmail.com Contributor
Marc Sales marcsales92@gmail.com Contributor
Piyush Gupta piyush04111999@gmail.com Contributor
Rodrigo Muñoz rodrigo.munoz@proteinlab.cl Contributor
Stefan van der Linden spvdlinden@gmail.com Contributor
Carlos Paniego carpanie@hotmail.com Artwork
# SPDX-License-Identifier: GPL-3.0-or-later

328
CITATION.cff Normal file
View File

@ -0,0 +1,328 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2022 C. Fernandez-Prades carles.fernandez(at)cttc.es
---
authors:
- affiliation: "Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)"
alias: carlesfernandez
email: carles.fernandez@cttc.es
family-names: "Fernández-Prades"
given-names: Carles
orcid: "https://orcid.org/0000-0002-9201-7007"
- affiliation: "Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)"
alias: Arribas
email: javier.arribas@cttc.es
family-names: Arribas
given-names: Javier
orcid: "https://orcid.org/0000-0001-6346-3406"
- affiliation: "Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)"
alias: mmajoral
email: marc.majoral@cttc.es
family-names: Majoral
given-names: Marc
orcid: "https://orcid.org/0000-0001-6161-6747"
- alias: Gastd
email: gabriel.araujo.5000@gmail.com
family-names: Araujo
given-names: Gabriel
- email: anthony.arnold@uqconnect.edu.au
family-names: Arnold
given-names: Anthony
- email: carlos.avilesr@googlemail.com
family-names: Avilés
given-names: Carlos
- alias: marabra
email: mara.branzanti@gmail.com
family-names: Branzanti
given-names: Mara
- alias: acebrianjuan
email: acebrianjuan@gmail.com
family-names: "Cebrián-Juan"
given-names: Álvaro
- email: a.cecilia.luque@gmail.com
family-names: "Cecilia-Luque"
given-names: Andrés
- alias: luis-esteve
email: luis@epsilon-formacion.com
family-names: Esteve
given-names: Luis
- email: fabra@ice.csic.es
family-names: Fabra
given-names: Fran
- email: daniel.co@bluewin.ch
family-names: Fehr
given-names: Daniel
- alias: piyush0411
email: piyush04111999@gmail.com
family-names: Gupta
given-names: Piyush
- alias: glamountain
email: gerald@gece.neu.edu
family-names: LaMountain
given-names: Gerald
- alias: lenhart
email: malte.lenhart@mailbox.org
family-names: Lenhart
given-names: Malte
- alias: jwmelto
email: jim.melton@sncorp.com
family-names: Melton
given-names: Jim
- alias: dmiralles2009
email: dmiralles2009@gmail.com
family-names: Miralles
given-names: Damian
orcid: "https://orcid.org/0000-0001-5820-9569"
- email: marc.molina.pena@gmail.com
family-names: Molina
given-names: Marc
- email: rodrigo.munoz@proteinlab.cl
family-names: Muñoz
given-names: Rodrigo
- alias: odrisci
email: cillian.odriscoll@gmail.com
family-names: "O'Driscoll"
given-names: Cillian
- affiliation: "Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)"
email: david.pubill@cttc.cat
family-names: Pubill
given-names: David
- alias: antonioramosdet
family-names: Ramos
given-names: Antonio
- alias: jschindehette
email: jschindehette@geontech.com
family-names: Schindehette
given-names: Josh
- email: tonetto.dev@gmail.com
family-names: Tonetto
given-names: Leonardo
- alias: stefanlinden
email: spvdlinden@gmail.com
family-names: "van der Linden"
given-names: Stefan
cff-version: "1.2.0"
date-released: "2022-02-15"
identifiers:
- description: "The concept DOI of the work. This is a DOI always pointing to the latest stable release."
type: doi
value: 10.5281/zenodo.591700
keywords:
- "Global Navigation Satellite System"
- GNSS
- "software radio"
- SDR
- GPS
- Galileo
- C++
license: GPL-3.0-or-later
message: "If you use this software, please cite it using the metadata from this file."
references:
- authors:
- family-names: "Fernández-Prades"
given-names: Carles
- family-names: "Vilà-Valls"
given-names: Jordi
- family-names: Arribas
given-names: Javier
- family-names: Ramos
given-names: Antonio
doi: 10.1109/ACCESS.2018.2822835
issue: 1
journal: "IEEE Access"
pages: 13
start: 20451
end: 20463
scope: "Discussion on reproducibility in GNSS signal processing."
title: "Continuous Reproducibility in GNSS Signal Processing."
type: article
volume: 6
year: 2018
- authors:
- family-names: "Fernández-Prades"
given-names: Carles
- family-names: "Lo Presti"
given-names: Letizia
- family-names: Falleti
given-names: Emanuela
doi: 10.1109/JPROC.2011.2158032
issue: 11
journal: "Proceedigs of the IEEE"
month: 11
pages: 23
start: 1882
end: 1904
scope: "General overview on GNSS receiver technology."
title: "Satellite Radiolocalization From GPS to GNSS and Beyond: Novel Technologies and Applications for Civil Mass Market."
type: article
volume: 99
year: 2011
- authors:
- family-names: "Fernández-Prades"
given-names: Carles
- family-names: Arribas
given-names: Javier
- family-names: Majoral
given-names: Marc
- family-names: Ramos
given-names: Antonio
- family-names: "Vilà-Valls"
given-names: Jordi
- family-names: Giordano
given-names: Pietro
conference:
name: "Proc. 9th ESA Workshop on Satellite Navigation Technologies and European Workshop on GNSS Signals and Signal Processing (NAVITEC)"
doi: 10.1109/NAVITEC.2018.8642697
location:
name: "ESA/ESTEC, Noordwijk, Netherlands."
month: 12
pages: 9
scope: "Space applications of the software-defined GNSS embeded receiver."
title: "A Software-Defined Spaceborne GNSS Receiver."
type: conference-paper
year: 2018
- authors:
- family-names: "Fernández-Prades"
given-names: Carles
- family-names: Pomar
given-names: Christian
- family-names: Arribas
given-names: Javier
- family-names: Fàbrega
given-names: "Josep Maria"
- family-names: "Vilà-Valls"
given-names: Jordi
- family-names: "Svaluto Moreolo"
given-names: Michela
- family-names: Casellas
given-names: Ramon
- family-names: Martínez
given-names: Ricardo
- family-names: Navarro
given-names: Mònica
- family-names: Vílchez
given-names: "Francisco Javier"
- family-names: Muñoz
given-names: Raul
- family-names: Vilalta
given-names: Ricard
- family-names: Nadal
given-names: Laia
- family-names: Mayoral
given-names: Arturo
conference:
name: "Proc. 30th Int. Tech. Meeting Sat. Div. Inst. Navig."
doi: 10.33012/2017.15234
location:
name: "Portland, OR."
month: 9
scope: "Introduction of the virtualized GNSS receiver."
pages: 20
start: 3796
end: 3815
title: "A Cloud Optical Access Network for Virtualized GNSS Receivers"
type: conference-paper
year: 2017
- authors:
- family-names: "Fernández-Prades"
given-names: Carles
- family-names: Arribas
given-names: Javier
- family-names: Closas
given-names: Pau
conference:
name: "Proc. 8th ESA Workshop on Satellite Navigation Technologies and European Workshop on GNSS Signals and Signal Processing (NAVITEC)"
doi: 10.1109/NAVITEC.2016.7931740
location:
name: "ESA/ESTEC, Noordwijk, Netherlands."
month: 12
pages: 9
scope: "Discussion on testing methodologies for software-defined GNSS receivers."
title: "Assessment of Software-Defined GNSS Receivers"
type: conference-paper
year: 2016
- authors:
- family-names: "Fernández-Prades"
given-names: Carles
- family-names: Arribas
given-names: Javier
- family-names: Closas
given-names: Pau
conference:
name: "Proc. 29th Int. Tech. Meeting Sat. Div. Inst. Navig."
doi: 10.33012/2016.14576
location:
name: "Portland, OR."
month: 9
pages: 18
start: 44
end: 61
scope: "Analysis of software strategies for accelerating signal processing."
title: "Accelerating GNSS Software Receivers"
type: conference-paper
year: 2016
- authors:
- family-names: "Fernández-Prades"
given-names: Carles
- family-names: Arribas
given-names: Javier
- family-names: Closas
given-names: Pau
- family-names: Avilés
given-names: Carlos
- family-names: Esteve
given-names: Luis
conference:
name: "Proc. 24th Int. Tech. Meeting Sat. Div. Inst. Navig."
location:
name: "Portland, OR."
month: 9
pages: 15
start: 780
end: 794
scope: "General description of the software architecture."
title: "GNSS-SDR: An Open Source Tool For Researchers and Developers"
type: conference-paper
year: 2011
- authors:
- family-names: "Fernández-Prades"
given-names: Carles
- family-names: Avilés
given-names: Carlos
- family-names: Esteve
given-names: Luis
- family-names: Arribas
given-names: Javier
- family-names: Closas
given-names: Pau
conference:
name: "Proc. 5th ESA Workshop on Satellite Navigation Technologies and European Workshop on GNSS Signals and Signal Processing (NAVITEC)."
doi: 10.1109/NAVITEC.2010.5707981
location:
name: "ESA/ESTEC, Noordwijk, Netherlands."
month: 12
pages: 8
scope: "Seminal work on GNSS-SDR and its software design patterns."
title: "Design patterns for GNSS software receivers"
type: conference-paper
year: 2010
- authors:
- name: "The GNU Radio Project team"
doi: 10.5281/zenodo.2704343
repository-code: "https://github.com/gnuradio/gnuradio"
scope: "Software dependency: the SDR framework."
title: "GNU Radio: The Free & Open Software Radio Ecosystem"
type: software
url: "https://www.gnuradio.org"
- authors:
- name: "The VOLK Project team"
doi: 10.5281/zenodo.3360942
repository-code: "https://github.com/gnuradio/volk"
scope: "Software dependency: the portable SIMD library."
title: "VOLK: The Vector-Optimized Library of Kernels"
type: software
url: "https://www.libvolk.org"
repository-code: "https://github.com/gnss-sdr/gnss-sdr"
title: GNSS-SDR
type: software
url: "https://gnss-sdr.org"
version: "0.0.16"

View File

@ -1,7 +1,7 @@
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
# This file is part of GNSS-SDR.
#
# SPDX-FileCopyrightText: 2010-2021 C. Fernandez-Prades cfernandez(at)cttc.es
# SPDX-FileCopyrightText: 2010-2022 C. Fernandez-Prades cfernandez(at)cttc.es
# SPDX-License-Identifier: BSD-3-Clause
################################################################################
@ -11,7 +11,12 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "Prevented in-tree build, it is bad practice.\nTry 'cd build && cmake ..' instead.")
endif()
cmake_minimum_required(VERSION 2.8.12...3.21)
# Select the release build type by default to get optimization flags.
# This has to come before project() which otherwise initializes it.
# Build type can still be overridden by setting -DCMAKE_BUILD_TYPE=
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "")
cmake_minimum_required(VERSION 2.8.12...3.22)
project(gnss-sdr CXX C)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
@ -161,9 +166,9 @@ endif()
set(VERSION_INFO_MAJOR_VERSION 0)
set(VERSION_INFO_API_COMPAT 0)
if(${THIS_IS_A_RELEASE})
set(VERSION_INFO_MINOR_VERSION 15)
set(VERSION_INFO_MINOR_VERSION 16)
else()
set(VERSION_INFO_MINOR_VERSION 15.git-${GIT_BRANCH}-${GIT_COMMIT_HASH})
set(VERSION_INFO_MINOR_VERSION 16.git-${GIT_BRANCH}-${GIT_COMMIT_HASH})
endif()
set(VERSION ${VERSION_INFO_MAJOR_VERSION}.${VERSION_INFO_API_COMPAT}.${VERSION_INFO_MINOR_VERSION})
@ -219,19 +224,9 @@ include(GnsssdrBuildTypes)
# - O2WithASM: -O2 -g -save-temps
# - O3WithASM: -O3 -g -save-temps
# - ASAN: -Wall -Wextra -g -O2 -fsanitize=address -fno-omit-frame-pointer
if(NOT CMAKE_BUILD_TYPE)
if(ENABLE_GPERFTOOLS OR ENABLE_GPROF)
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
message(STATUS "Build type not specified: defaulting to RelWithDebInfo.")
else()
set(CMAKE_BUILD_TYPE "Release")
message(STATUS "Build type not specified: defaulting to Release.")
endif()
else()
message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
endif()
gnsssdr_check_build_type(${CMAKE_BUILD_TYPE})
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
if(NOT (${CMAKE_BUILD_TYPE} STREQUAL "Release"))
set(ENABLE_STRIP OFF)
endif()
@ -326,7 +321,7 @@ set(GNSSSDR_PROTOBUF_MIN_VERSION "3.0.0")
################################################################################
set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2")
set(GNSSSDR_GLOG_LOCAL_VERSION "0.5.0")
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.7.x")
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.8.x")
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) OR
(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))
set(GNSSSDR_GTEST_LOCAL_VERSION "1.10.x")
@ -336,9 +331,9 @@ endif()
set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master")
set(GNSSSDR_GPSTK_LOCAL_VERSION "8.0.0")
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.21")
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.11.4")
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.19.0")
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.6.0")
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.12")
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.19.4")
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.6.1")
set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7")
if(CMAKE_VERSION VERSION_LESS "3.3")
@ -1354,8 +1349,11 @@ endif()
################################################################################
set(LOCAL_GFLAGS FALSE)
if(NOT ENABLE_OWN_GLOG)
find_package(GLOG)
if(GLOG_FOUND)
find_package(GFLAGS)
endif()
endif()
set_package_properties(GFLAGS PROPERTIES
PURPOSE "Used for commandline flags management."
TYPE REQUIRED
@ -1495,9 +1493,6 @@ endif()
################################################################################
# glog - https://github.com/google/glog
################################################################################
if(NOT ENABLE_OWN_GLOG AND NOT ${LOCAL_GFLAGS})
find_package(GLOG)
endif()
set_package_properties(GLOG PROPERTIES
PURPOSE "Used for runtime internal logging."
TYPE REQUIRED

View File

@ -16,8 +16,8 @@ We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
@ -64,13 +64,7 @@ This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event. This Code of Conduct applies both
within project spaces and in public spaces when an individual is representing
the project or its community. Examples of representing a project or community
include using an official project e-mail address, posting via an official social
media account, or acting as an appointed representative at an online or offline
event. Representation of a project may be further defined and clarified by
project maintainers.
representative at an online or offline event.
## Enforcement
@ -131,18 +125,18 @@ community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][version].
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder][diversity].
enforcement ladder][mozilla coc].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][faq]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[diversity]: https://github.com/mozilla/diversity
[version]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
[faq]: https://www.contributor-covenant.org/faq/
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[mozilla coc]: https://github.com/mozilla/diversity
[faq]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

View File

@ -12,7 +12,7 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![REUSE status](https://api.reuse.software/badge/github.com/gnss-sdr/gnss-sdr)](https://api.reuse.software/info/github.com/gnss-sdr/gnss-sdr)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](CODE_OF_CONDUCT.md)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
**Welcome to GNSS-SDR!**
@ -36,8 +36,9 @@ In the L2 band:
In the L5 band:
- &#128752; GPS L5 (centered at 1176.45 MHz) :white_check_mark:
- &#128752; Galileo E5a (centered at 1176.45 MHz) :white_check_mark:
- &#128752; Galileo E5b (centered at 1207.140 MHz) :white_check_mark:
- &#128752; Galileo E5a (centered at 1176.450 MHz) :white_check_mark:
- &#128752; GPS L5 (centered at 1176.450 MHz) :white_check_mark:
GNSS-SDR provides interfaces for a wide range of radio frequency front-ends and
raw sample file formats, generates processing outputs in standard formats,
@ -62,6 +63,7 @@ information about this open-source, software-defined GNSS receiver.
- [CentOS](#centos)
- [Fedora](#fedora)
- [OpenSUSE](#opensuse)
- [Rocky Linux](#rocky-linux)
1. [Alternative 2: Install dependencies using PyBOMBS](#alternative-2-install-dependencies-using-pybombs)
- [Manual installation of other required dependencies](#manual-installation-of-other-required-dependencies)
- [Armadillo](#install-armadillo-a-c-linear-algebra-library)
@ -239,12 +241,15 @@ $ sudo yum install make automake gcc gcc-c++ kernel-devel cmake git boost-devel
In Fedora 33 and above, you will need to add `gmp-devel` to the package list.
Optionally, you can add `uhd-devel` starting from Fedora 32.
In Fedora 36 and above, packages `spdlog-devel` and `fmt-devel` are also
required.
#### openSUSE
If you are using openSUSE Leap:
```
zypper install cmake git gcc-c++ boost-devel libboost_atomic-devel \
$ zypper install cmake git gcc-c++ boost-devel libboost_atomic-devel \
libboost_system-devel libboost_filesystem-devel libboost_chrono-devel \
libboost_thread-devel libboost_serialization-devel log4cpp-devel \
gnuradio-devel pugixml-devel libpcap-devel armadillo-devel libtool \
@ -254,10 +259,10 @@ zypper install cmake git gcc-c++ boost-devel libboost_atomic-devel \
If you are using openSUSE Tumbleweed:
```
zypper install cmake git gcc-c++ boost-devel libboost_atomic-devel \
$ zypper install cmake git gcc-c++ boost-devel libboost_atomic-devel \
libboost_system-devel libboost_filesystem-devel libboost_date_time-devel \
libboost_thread-devel libboost_chrono-devel libboost_serialization-devel \
log4cpp-devel gtest gnuradio-devel pugixml-devel libpcap-devel \
spdlog-devel fmt-devel gtest gnuradio-devel pugixml-devel libpcap-devel \
armadillo-devel libtool automake hdf5-devel libopenssl-devel \
python3-Mako protobuf-devel
```
@ -265,6 +270,24 @@ zypper install cmake git gcc-c++ boost-devel libboost_atomic-devel \
Once you have installed these packages, you can jump directly to
[download the source code and build GNSS-SDR](#download-and-build-linux).
#### Rocky Linux
If you are using Rocky Linux:
```
$ dnf install -y 'dnf-command(config-manager)'
$ dnf config-manager --set-enabled powertools
$ yum install -y epel-release
$ yum install -y make gcc gcc-c++ kernel-devel cmake git boost-devel \
boost-date-time boost-system boost-thread boost-chrono boost-serialization \
log4cpp-devel gmp-devel uhd-devel gnuradio-devel pugixml-devel matio-devel \
protobuf-devel glog-devel libpcap-devel blas-devel lapack-devel \
armadillo-devel openssl-devel python3-mako libarchive
```
Once you have installed these packages, you can jump directly to
[download the source code and build GNSS-SDR](#download-and-build-linux).
### Alternative 2: Install dependencies using PyBOMBS
This option is adequate if you are interested in development, in working with
@ -355,9 +378,9 @@ $ sudo apt-get install libblas-dev liblapack-dev # For Debian/Ubuntu/Linux
$ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL
$ sudo zypper install lapack-devel blas-devel # For OpenSUSE
$ sudo pacman -S blas lapack # For Arch Linux
$ wget http://sourceforge.net/projects/arma/files/armadillo-10.6.1.tar.xz
$ tar xvfz armadillo-10.6.1.tar.xz
$ cd armadillo-10.6.1
$ wget https://sourceforge.net/projects/arma/files/armadillo-10.8.0.tar.xz
$ tar xvfz armadillo-10.8.0.tar.xz
$ cd armadillo-10.8.0
$ cmake .
$ make
$ sudo make install
@ -470,9 +493,9 @@ $ sudo apt-get install autoconf automake libtool curl make g++ unzip
and then:
```
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.18.0/protobuf-cpp-3.18.0.tar.gz
$ tar xvfz protobuf-cpp-3.18.0.tar.gz
$ cd protobuf-3.18.0
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protobuf-cpp-3.19.4.tar.gz
$ tar xvfz protobuf-cpp-3.19.4.tar.gz
$ cd protobuf-3.19.4
$ ./autogen.sh
$ ./configure
$ make
@ -483,9 +506,9 @@ $ sudo ldconfig
#### Install [Pugixml](https://pugixml.org/ "Pugixml's Homepage"), a light-weight C++ XML processing library:
```
$ wget https://github.com/zeux/pugixml/releases/download/v1.11.4/pugixml-1.11.4.tar.gz
$ tar xvfz pugixml-1.11.4.tar.gz
$ cd pugixml-1.11.4
$ wget https://github.com/zeux/pugixml/releases/download/v1.12/pugixml-1.12.tar.gz
$ tar xvfz pugixml-1.12.tar.gz
$ cd pugixml-1.12
$ mkdir build && cd build
$ cmake ..
$ make
@ -1640,6 +1663,7 @@ identifiers:
| Glonass L2 C/A | 2G |
| GPS L5 | L5 |
| Galileo E5a | 5X |
| Galileo E5b | 7X |
Example: Eight GPS L1 C/A channels.

View File

@ -6,9 +6,6 @@
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second].
;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE
; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/
GNSS-SDR.internal_fs_sps=5000000
GNSS-SDR.use_acquisition_resampler=true
@ -17,19 +14,17 @@ SignalSource.implementation=Limesdr_Signal_Source
SignalSource.item_type=gr_complex
SignalSource.sampling_frequency=5000000
SignalSource.freq=1575420000
SignalSource.gain=50; //0-73 dB//no agc in LimeSDR
;SignalSource.analog_bw //if not set, defaults to sample_rate/2
;SignalSource.digital_bw // if not set, defaults to 0 (disabled filter)
SignalSource.limesdr_serial // if not set, its automatic
SignalSource.antenna=2 // None(0), LNAH(1), LNAL(2), LNAW(3), AUTO(255)
SignalSource.ext_clock_MHz_=0 //0 -> internal clock
SignalSource.PPS_mode=false; //requires special gr-limesdr
SignalSource.limechannel_mode = 0; //ChannelMode must be A(0), B(1) or (A+B) MIMO(2)"
SignalSource.gain=50 ; 0-73 dB no AGC in LimeSDR
; SignalSource.analog_bw ; if not set, defaults to sample_rate/2
; SignalSource.digital_bw ; if not set, defaults to 0 (disabled filter)
; SignalSource.limesdr_serial ; if not set, its automatic
SignalSource.antenna=2 ; None(0), LNAH(1), LNAL(2), LNAW(3), AUTO(255)
SignalSource.ext_clock_MHz=0 ; 0 -> internal clock
SignalSource.limechannel_mode=0 ; A(0), B(1) or (A+B) MIMO(2)
SignalSource.samples=0
SignalSource.repeat=false
SignalSource.dump=false
SignalSource.dump_filename=../data/signal_source.dat
SignalSource.enable_throttle_control=false
SignalSource.dump_filename=./captured_signal.dat
SignalConditioner.implementation=Signal_Conditioner
DataTypeAdapter.implementation=Pass_Through
@ -37,6 +32,7 @@ InputFilter.implementation=Pulse_Blanking_Filter ; <- Required in some locations
InputFilter.pfa=0.001
InputFilter.segments_est=2500
Resampler.implementation=Pass_Through
;######### CHANNELS GLOBAL CONFIG ############
Channels_1C.count=7
Channels_1B.count=0
@ -44,30 +40,29 @@ Channels.in_acquisition=1
Channel.signal=1C
;######### ACQUISITION GLOBAL CONFIG ############
;######### GPS L1 ACQUISITION CONFIG ############
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
Acquisition_1C.item_type=gr_complex
Acquisition_1C.coherent_integration_time_ms=1
Acquisition_1C.use_CFAR_algorithm=false;
Acquisition_1C.threshold=2.4
Acquisition_1C.doppler_max=6000
Acquisition_1C.pfa=0.01
Acquisition_1C.doppler_max=5000
Acquisition_1C.doppler_step=250
Acquisition_1C.dump=false
Acquisition_1C.dump_filename=./acq_dump.dat
;######### GALILEO ACQUISITION CONFIG ############
;######### GALILEO E1 ACQUISITION CONFIG ############
Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition
Acquisition_1B.item_type=gr_complex
Acquisition_1B.threshold=2.5
Acquisition_1B.use_CFAR_algorithm=false
Acquisition_1B.coherent_integration_time_ms=4
Acquisition_1B.pfa=0.01
Acquisition_1B.blocking=false
Acquisition_1B.doppler_max=6000
Acquisition_1B.doppler_max=5000
Acquisition_1B.doppler_step=125
Acquisition_1B.dump=false
Acquisition_1B.dump_filename=./acq_dump.dat
;######### TRACKING GLOBAL CONFIG ############
;######### GPS L1 TRACKING CONFIG ############
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
Tracking_1C.item_type=gr_complex
Tracking_1C.dump=false
@ -81,7 +76,7 @@ Tracking_1C.order=3;
Tracking_1C.early_late_space_chips=0.5;
Tracking_1C.early_late_space_narrow_chips=0.5
;######### TRACKING GALILEO CONFIG ############
;######### GALILEO E1 TRACKING CONFIG ############
Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking
Tracking_1B.item_type=gr_complex
Tracking_1B.pll_bw_hz=15.0;
@ -100,13 +95,15 @@ Tracking_1B.dump=false
Tracking_1B.dump_filename=tracking_ch_
;######### TELEMETRY DECODER GPS CONFIG ############
;######### TELEMETRY DECODER GPS L1 CONFIG ############
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_1C.dump=false
;######### TELEMETRY DECODER Galileo E1 CONFIG ############
TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder
TelemetryDecoder_1B.dump=false
;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=false

View File

@ -4,7 +4,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
)
[comment]: # (
SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es>
SPDX-FileCopyrightText: 2011-2022 Carles Fernandez-Prades <carles.fernandez@cttc.es>
)
<!-- prettier-ignore-end -->
@ -14,8 +14,23 @@ All notable changes to GNSS-SDR will be documented in this file.
## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next)
### Improvements in Reliability:
- Fix some defects detected by Coverity Scan 2021.12.1.
See the definitions of concepts and metrics at
https://gnss-sdr.org/design-forces/
&nbsp;
## [GNSS-SDR v0.0.16](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.16) - 2022-02-15
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6090349.svg)](https://doi.org/10.5281/zenodo.6090349)
### Improvements in Availability:
- Added the Galileo E5b receiving chain. The software is now able to compute PVT
solutions as a standalone Galileo E5b receiver.
- Improved Time-To-First-Fix when using GPS L1 C/A signals, fixing a bug that
was making the receiver to drop the satellite if the PLL got locked at 180
degrees, and making some optimizations on bit transition detection.
@ -40,14 +55,14 @@ All notable changes to GNSS-SDR will be documented in this file.
memory management and source code readability.
- Prefer initialization to assignment in constructors. This improves the
readability of the code, could potentially increase performance, and allows
for easier detection of unused data members (see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md/#Rc-initialize).
for easier detection of unused data members (see the
[CppCoreGuidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md/#Rc-initialize)).
Added the `cppcoreguidelines-prefer-member-initializer` clang-tidy check to
enforce this policy.
- Non-functional change: Fixed formatting defects detected by clang-format 13.0.
- Non-functional change: Simplified flow graph disconnection.
- Updated GSL implementation to v0.40.0. See
https://github.com/gsl-lite/gsl-lite/releases/tag/v0.40.0
- Updated GSL implementation to v0.40.0. See the
[gsl-lite release](https://github.com/gsl-lite/gsl-lite/releases/tag/v0.40.0).
- CI - `cpplint` job on GitHub: Added the `build/include_what_you_use` filter
for early detection of missing includes.
- CI - `clang-tidy` job on GitHub: More robust detection of LLVM paths installed
@ -56,11 +71,11 @@ All notable changes to GNSS-SDR will be documented in this file.
### Improvements in Portability:
- Fixed building against the new API in the gr-iio component present in GNU
Radio v3.10.0.0-rc1.
- Fixed building against GNU Radio v3.10.0.0-rc1, which does not support the
C++20 standard.
- Fixed building against GNU Radio v3.10.0.0-rc1, which replaced
[log4cpp](http://log4cpp.sourceforge.net/) by
Radio v3.10.X.Y.
- Fixed building against GNU Radio v3.10.X.Y, which does not support the C++20
standard.
- Fixed building against GNU Radio v3.10.X.Y, which replaced
[log4cpp](http://log4cpp.sourceforge.net/) by the
[spdlog](https://github.com/gabime/spdlog) and
[fmt](https://github.com/fmtlib/fmt) libraries.
- Updated `cpu_features` library for improved processor detection.
@ -98,12 +113,18 @@ All notable changes to GNSS-SDR will be documented in this file.
- Added a new output parameter `Flag_PLL_180_deg_phase_locked` in the monitor
output that indicates if the PLL got locked at 180 degrees, so the symbol sign
is reversed.
- Fix bug in the satellite selection algorithm for configurations with a large
number of channels. The maximum number of channels per signal is now limited
to the number of available satellites per system minus one. The number of
channels performing concurrent acquisition, `Channels.in_acquisition`, cannot
be larger than the total number of channels. The program will stop if those
requirements are not met in the configuration file.
- Fixed a bug in the satellite selection algorithm for configurations with a
large number of channels. The maximum number of channels per signal is now
limited to the number of available satellites per system minus one. The number
of channels performing concurrent acquisition, `Channels.in_acquisition`,
cannot be larger than the total number of channels. The program will stop if
those requirements are not met in the configuration file.
- Fixed program termination when using `File_Signal_Source` and extended
integration times.
- The `Fifo_Signal_Source` Signal Source implementation learned to handle the
`ibyte` type.
- Added a `CITATION.cff` file.
- Updated version of the Contributor Covenant to version 2.1.
See the definitions of concepts and metrics at
https://gnss-sdr.org/design-forces/
@ -112,6 +133,8 @@ https://gnss-sdr.org/design-forces/
## [GNSS-SDR v0.0.15](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.15) - 2021-08-23
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.5242839.svg)](https://doi.org/10.5281/zenodo.5242839)
### Improvements in Availability:
- Added the reading of reduced clock and ephemeris data (CED) in the Galileo E1B
@ -236,6 +259,8 @@ https://gnss-sdr.org/design-forces/
## [GNSS-SDR v0.0.14](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.14) - 2021-01-08
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4428100.svg)](https://doi.org/10.5281/zenodo.4428100)
### Improvements in Availability:
- Fixed bug in acquisition detection when the configuration parameter
@ -345,6 +370,8 @@ https://gnss-sdr.org/design-forces/
## [GNSS-SDR v0.0.13](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.13) - 2020-07-29
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3965566.svg)](https://doi.org/10.5281/zenodo.3965566)
### Improvements in Efficiency:
- Faster internal handling of `Gnss_Synchro` objects by reducing the amount of
@ -459,6 +486,8 @@ https://gnss-sdr.org/design-forces/
## [GNSS-SDR v0.0.12](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.12) - 2020-03-13
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3709089.svg)](https://doi.org/10.5281/zenodo.3709089)
### Improvements in Accuracy:
- Improved accuracy of the C/N0 estimator.
@ -653,6 +682,8 @@ https://gnss-sdr.org/design-forces/
## [GNSS-SDR v0.0.11](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.11) - 2019-08-04
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3359989.svg)](https://doi.org/10.5281/zenodo.3359989)
This release has several improvements in different dimensions, addition of new
features and bug fixes:
@ -806,6 +837,8 @@ https://gnss-sdr.org/design-forces/
## [GNSS-SDR v0.0.10](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.10) - 2018-12-14
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.2279988.svg)](https://doi.org/10.5281/zenodo.2279988)
This release has several improvements in different dimensions, addition of new
features and bug fixes:
@ -1038,7 +1071,7 @@ https://gnss-sdr.org/design-forces/
## [GNSS-SDR v0.0.9](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.9) - 2017-02-13
DOI: https://doi.org/10.5281/zenodo.291371
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.291371.svg)](https://doi.org/10.5281/zenodo.291371)
This release has several improvements, addition of new features and bug fixes in
many dimensions:
@ -1159,7 +1192,7 @@ https://gnss-sdr.org/design-forces/
## [GNSS-SDR v0.0.8](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.8) - 2016-07-04
DOI: https://doi.org/10.5281/zenodo.57022
[![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.57022.svg)](http://dx.doi.org/10.5281/zenodo.57022)
This is a maintenance and bug fix release with no relevant new features with
respect to v0.0.7. The main changes are:
@ -1185,7 +1218,7 @@ respect to v0.0.7. The main changes are:
## [GNSS-SDR v0.0.7](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.7) - 2016-05-15
DOI: https://doi.org/10.5281/zenodo.51521
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.51521.svg)](https://doi.org/10.5281/zenodo.51521)
This release has several improvements, addition of new features and bug fixes:
@ -1277,6 +1310,8 @@ This release has several improvements, addition of new features and bug fixes:
## [GNSS-SDR v0.0.6](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.6) - 2015-09-02
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.30104.svg)](https://doi.org/10.5281/zenodo.30104)
This release has several improvements and bug fixes:
- Added initial support to multi-band, multi-source configurations (multiple
@ -1327,6 +1362,8 @@ This release has several improvements and bug fixes:
## [GNSS-SDR v0.0.5](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.5) - 2015-01-13
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.13920.svg)](https://doi.org/10.5281/zenodo.13920)
This release has several improvements and bug fixes:
- Now GNSS-SDR can be installed on the system with the usual
@ -1354,6 +1391,8 @@ This release has several improvements and bug fixes:
## [GNSS-SDR v0.0.4](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.4) - 2014-09-08
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.11628.svg)](https://doi.org/10.5281/zenodo.11628)
This release has several improvements and bug fixes:
- Added hybrid processing GPS L1 C/A and Galileo E1B, providing position fixes
@ -1391,6 +1430,8 @@ This release has several improvements and bug fixes:
## [GNSS-SDR v0.0.3](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.3) - 2014-06-30
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.10708.svg)](https://doi.org/10.5281/zenodo.10708)
This release has several improvements and bug fixes, completing the transition
from Subversion to Git. The main changes are:

View File

@ -1,7 +1,7 @@
# Doxyfile 1.8.20
# Doxyfile 1.9.3
#
# SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades <carles.fernandez(at)cttc.es>
# SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez(at)cttc.es>
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This file describes the settings to be used by the documentation system
@ -36,7 +36,7 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = "GNSS-SDR"
PROJECT_NAME = GNSS-SDR
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
@ -97,14 +97,6 @@ ALLOW_UNICODE_NAMES = YES
OUTPUT_LANGUAGE = English
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all generated output in the proper direction.
# Possible values are: None, LTR, RTL and Context.
# The default value is: None.
OUTPUT_TEXT_DIRECTION = None
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
@ -252,16 +244,16 @@ TAB_SIZE = 8
# the documentation. An alias has the form:
# name=value
# For example adding
# "sideeffect=@par Side Effects:\n"
# "sideeffect=@par Side Effects:^^"
# will allow you to put the command \sideeffect (or @sideeffect) in the
# documentation, which will result in a user-defined paragraph with heading
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines (in the resulting output). You can put ^^ in the value part of an
# alias to insert a newline as if a physical newline was in the original file.
# When you need a literal { or } or , in the value part of an alias you have to
# escape them by means of a backslash (\), this can lead to conflicts with the
# commands \{ and \} for these it is advised to use the version @{ and @} or use
# a double escape (\\{ and \\})
# "Side Effects:". Note that you cannot put \n's in the value part of an alias
# to insert newlines (in the resulting output). You can put ^^ in the value part
# of an alias to insert a newline as if a physical newline was in the original
# file. When you need a literal { or } or , in the value part of an alias you
# have to escape them by means of a backslash (\), this can lead to conflicts
# with the commands \{ and \} for these it is advised to use the version @{ and
# @} or use a double escape (\\{ and \\})
ALIASES =
@ -306,8 +298,8 @@ OPTIMIZE_OUTPUT_SLICE = NO
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice,
# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
# tries to guess whether the code is fixed or free formatted code, this is the
# default for Fortran type files). For instance to make doxygen treat .inc files
@ -317,7 +309,10 @@ OPTIMIZE_OUTPUT_SLICE = NO
# Note: For files without extension you can use no_extension as a placeholder.
#
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
# the files are not read by doxygen.
# the files are not read by doxygen. When specifying no_extension you should add
# * to the FILE_PATTERNS.
#
# Note see also the list of default file extension mappings.
EXTENSION_MAPPING =
@ -457,7 +452,7 @@ LOOKUP_CACHE_SIZE = 0
# than 0 to get more control over the balance between CPU load and processing
# speed. At this moment only the input processing can be done using multiple
# threads. Since this is still an experimental feature the default is set to 1,
# which efficively disables parallel processing. Please report any issues you
# which effectively disables parallel processing. Please report any issues you
# encounter. Generating dot graphs in parallel is controlled by the
# DOT_NUM_THREADS setting.
# Minimum value: 0, maximum value: 32, default value: 1.
@ -527,6 +522,13 @@ EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
# If this flag is set to YES, the name of an unnamed parameter in a declaration
# will be determined by the corresponding definition. By default unnamed
# parameters remain unnamed in the output.
# The default value is: YES.
RESOLVE_UNNAMED_PARAMS = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
# undocumented members inside documented classes or files. If set to NO these
# members will be included in the various overviews, but no documentation
@ -564,11 +566,18 @@ HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
# names in lower-case letters. If set to YES, upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# (including Cygwin) and Mac users are advised to set this option to NO.
# With the correct setting of option CASE_SENSE_NAMES doxygen will better be
# able to match the capabilities of the underlying filesystem. In case the
# filesystem is case sensitive (i.e. it supports files in the same directory
# whose names only differ in casing), the option must be set to YES to properly
# deal with such files in case they appear in the input. For filesystems that
# are not case sensitive the option should be be set to NO to properly deal with
# output files written for symbols that only differ in casing, such as for two
# classes, one named CLASS and the other named Class, and to also support
# references to files without having to specify the exact matching casing. On
# Windows (including Cygwin) and MacOS, users should typically set this option
# to NO, whereas on Linux or other Unix flavors it should typically be set to
# YES.
# The default value is: system dependent.
CASE_SENSE_NAMES = YES
@ -587,6 +596,12 @@ HIDE_SCOPE_NAMES = NO
HIDE_COMPOUND_REFERENCE= NO
# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class
# will show which file needs to be included to use the class.
# The default value is: YES.
SHOW_HEADERFILE = YES
# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
# the files that are included by a file in the documentation of that file.
# The default value is: YES.
@ -744,7 +759,8 @@ FILE_VERSION_FILTER =
# output files in an output format independent way. To create the layout file
# that represents doxygen's defaults, run doxygen with the -l option. You can
# optionally specify a file name after the option, if omitted DoxygenLayout.xml
# will be used as the name of the layout file.
# will be used as the name of the layout file. See also section "Changing the
# layout of pages" for information.
#
# Note that if you run doxygen from a directory containing a file called
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
@ -790,24 +806,35 @@ WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
# potential errors in the documentation, such as not documenting some parameters
# in a documented function, or documenting parameters that don't exist or using
# markup commands wrongly.
# potential errors in the documentation, such as documenting some parameters in
# a documented function twice, or documenting parameters that don't exist or
# using markup commands wrongly.
# The default value is: YES.
WARN_IF_DOC_ERROR = YES
# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete
# function parameter documentation. If set to NO, doxygen will accept that some
# parameters have no documentation without warning.
# The default value is: YES.
WARN_IF_INCOMPLETE_DOC = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
# value. If set to NO, doxygen will only warn about wrong or incomplete
# parameter documentation, but not about the absence of documentation. If
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
# value. If set to NO, doxygen will only warn about wrong parameter
# documentation, but not about the absence of documentation. If EXTRACT_ALL is
# set to YES then this flag will automatically be disabled. See also
# WARN_IF_INCOMPLETE_DOC
# The default value is: NO.
WARN_NO_PARAMDOC = NO
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered.
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
# at the end of the doxygen process doxygen will return with a non-zero status.
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
# The default value is: NO.
WARN_AS_ERROR = NO
@ -824,7 +851,10 @@ WARN_FORMAT = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning and error
# messages should be written. If left blank the output is written to standard
# error (stderr).
# error (stderr). In case the file specified cannot be opened for writing the
# warning and error messages are written to standard error. When as file - is
# specified the warning and error messages are written to standard output
# (stdout).
WARN_LOGFILE =
@ -844,8 +874,8 @@ INPUT = @top_srcdir@/src \
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
# possible encodings.
# documentation (see:
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
# The default value is: UTF-8.
INPUT_ENCODING = UTF-8
@ -858,12 +888,14 @@ INPUT_ENCODING = UTF-8
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# read by doxygen.
#
# Note the list of default checked file patterns might differ from the list of
# default file extension mappings.
#
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml,
# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C
# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
# *.vhdl, *.ucf, *.qsf and *.ice.
FILE_PATTERNS = *.h \
@ -909,7 +941,7 @@ EXCLUDE_PATTERNS =
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
# ANamespace::AClass, ANamespace::*Test
#
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*
@ -1095,13 +1127,6 @@ VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = YES
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
# which the alphabetical index list will be split.
# Minimum value: 1, maximum value: 20, default value: 5.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all classes will
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
# can be used to specify a prefix (or a list of prefixes) that should be ignored
@ -1201,7 +1226,7 @@ HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a colorwheel, see
# this color. Hue is specified as an angle on a color-wheel, see
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
# purple, and 360 is red again.
@ -1211,7 +1236,7 @@ HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
# in the HTML output. For a value of 0 the output will use grayscales only. A
# in the HTML output. For a value of 0 the output will use gray-scales only. A
# value of 255 will produce the most vivid colors.
# Minimum value: 0, maximum value: 255, default value: 100.
# This tag requires that the tag GENERATE_HTML is set to YES.
@ -1272,10 +1297,11 @@ HTML_INDEX_NUM_ENTRIES = 100
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
# environment (see: https://developer.apple.com/xcode/), introduced with OSX
# 10.5 (Leopard). To create a documentation set, doxygen will generate a
# Makefile in the HTML output directory. Running make will produce the docset in
# that directory and running make install will install the docset in
# environment (see:
# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
# create a documentation set, doxygen will generate a Makefile in the HTML
# output directory. Running make will produce the docset in that directory and
# running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
# genXcode/_index.html for more information.
@ -1292,6 +1318,13 @@ GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
# This tag determines the URL of the docset feed. A documentation feed provides
# an umbrella under which multiple documentation sets from a single provider
# (such as a company or product suite) can be grouped.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_FEEDURL =
# This tag specifies a string that should uniquely identify the documentation
# set bundle. This should be a reverse domain-name style string, e.g.
# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
@ -1317,8 +1350,12 @@ DOCSET_PUBLISHER_NAME = CTTC
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# Windows.
# on Windows. In the beginning of 2021 Microsoft took the original page, with
# a.o. the download links, offline the HTML help workshop was already many years
# in maintenance mode). You can download the HTML help workshop from the web
# archives at Installation executable (see:
# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo
# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe).
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
@ -1393,7 +1430,8 @@ QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
# (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.
@ -1401,8 +1439,8 @@ QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
# folders).
# Folders (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
@ -1410,16 +1448,16 @@ QHP_VIRTUAL_FOLDER = doc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
# filters).
# Filters (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
# filters).
# Filters (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_ATTRS =
@ -1431,9 +1469,9 @@ QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
# The QHG_LOCATION tag can be used to specify the location of Qt's
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
# generated .qhp file.
# The QHG_LOCATION tag can be used to specify the location (absolute path
# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to
# run qhelpgenerator on the generated .qhp file.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHG_LOCATION =
@ -1476,16 +1514,28 @@ DISABLE_INDEX = NO
# to work a browser that supports JavaScript, DHTML, CSS and frames is required
# (i.e. any modern browser). Windows users are probably better off using the
# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
# further fine-tune the look of the index. As an example, the default style
# sheet generated by doxygen has an example that shows how to put an image at
# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
# the same information as the tab index, you could consider setting
# DISABLE_INDEX to YES when enabling this option.
# further fine tune the look of the index (see "Fine-tuning the output"). As an
# example, the default style sheet generated by doxygen has an example that
# shows how to put an image at the root of the tree instead of the PROJECT_NAME.
# Since the tree basically has the same information as the tab index, you could
# consider setting DISABLE_INDEX to YES when enabling this option.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = NO
# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the
# FULL_SIDEBAR option determines if the side bar is limited to only the treeview
# area (value NO) or if it should extend to the full height of the window (value
# YES). Setting this to YES gives a layout similar to
# https://docs.readthedocs.io with more room for contents, but less room for the
# project logo, title, and description. If either GENERATE_TREEVIEW or
# DISABLE_INDEX is set to NO, this option has no effect.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
FULL_SIDEBAR = NO
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
#
@ -1510,6 +1560,13 @@ TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email
# addresses.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
OBFUSCATE_EMAILS = YES
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
@ -1558,11 +1615,29 @@ FORMULA_MACROFILE =
USE_MATHJAX = @GNSSSDR_USE_MATHJAX@
# With MATHJAX_VERSION it is possible to specify the MathJax version to be used.
# Note that the different versions of MathJax have different requirements with
# regards to the different settings, so it is possible that also other MathJax
# settings have to be changed when switching between the different MathJax
# versions.
# Possible values are: MathJax_2 and MathJax_3.
# The default value is: MathJax_2.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_VERSION = MathJax_2
# When MathJax is enabled you can set the default output format to be used for
# the MathJax output. See the MathJax site (see:
# http://docs.mathjax.org/en/latest/output.html) for more details.
# the MathJax output. For more details about the output format see MathJax
# version 2 (see:
# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3
# (see:
# http://docs.mathjax.org/en/latest/web/components/output.html).
# Possible values are: HTML-CSS (which is slower, but has the best
# compatibility), NativeMML (i.e. MathML) and SVG.
# compatibility. This is the name for Mathjax version 2, for MathJax version 3
# this will be translated into chtml), NativeMML (i.e. MathML. Only supported
# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This
# is the name for Mathjax version 3, for MathJax version 2 this will be
# translated into HTML-CSS) and SVG.
# The default value is: HTML-CSS.
# This tag requires that the tag USE_MATHJAX is set to YES.
@ -1575,15 +1650,21 @@ MATHJAX_FORMAT = SVG
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from https://www.mathjax.org before deployment.
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
# MathJax from https://www.mathjax.org before deployment. The default value is:
# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2
# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = @MATHJAX2_PATH@
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
# extension names that should be enabled during MathJax rendering. For example
# for MathJax version 2 (see
# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions):
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# For example for MathJax version 3 (see
# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html):
# MATHJAX_EXTENSIONS = ams
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_EXTENSIONS = TeX/AMSmath \
@ -1591,7 +1672,8 @@ MATHJAX_EXTENSIONS = TeX/AMSmath \
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
# of code that will be used on startup of the MathJax code. See the MathJax site
# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
# (see:
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
# example see the documentation.
# This tag requires that the tag USE_MATHJAX is set to YES.
@ -1638,7 +1720,8 @@ SERVER_BASED_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: https://xapian.org/).
# Xapian (see:
# https://xapian.org/).
#
# See the section "External Indexing and Searching" for details.
# The default value is: NO.
@ -1651,8 +1734,9 @@ EXTERNAL_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: https://xapian.org/). See the section "External Indexing and
# Searching" for details.
# Xapian (see:
# https://xapian.org/). See the section "External Indexing and Searching" for
# details.
# This tag requires that the tag SEARCHENGINE is set to YES.
SEARCHENGINE_URL =
@ -1763,29 +1847,31 @@ EXTRA_PACKAGES = amsmath \
amssymb \
amsfonts
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
# generated LaTeX document. The header should contain everything until the first
# chapter. If it is left blank doxygen will generate a standard header. See
# section "Doxygen usage" for information on how to let doxygen write the
# default header to a separate file.
# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for
# the generated LaTeX document. The header should contain everything until the
# first chapter. If it is left blank doxygen will generate a standard header. It
# is highly recommended to start with a default header using
# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty
# and then modify the file new_header.tex. See also section "Doxygen usage" for
# information on how to generate the default header that doxygen normally uses.
#
# Note: Only use a user-defined header if you know what you are doing! The
# following commands have a special meaning inside the header: $title,
# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
# string, for the replacement values of the other commands the user is referred
# to HTML_HEADER.
# Note: Only use a user-defined header if you know what you are doing!
# Note: The header is subject to change so you typically have to regenerate the
# default header when upgrading to a newer version of doxygen. The following
# commands have a special meaning inside the header (and footer): For a
# description of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER =
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
# generated LaTeX document. The footer should contain everything after the last
# chapter. If it is left blank doxygen will generate a standard footer. See
# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for
# the generated LaTeX document. The footer should contain everything after the
# last chapter. If it is left blank doxygen will generate a standard footer. See
# LATEX_HEADER for more information on how to generate a default footer and what
# special commands can be used inside the footer.
#
# Note: Only use a user-defined footer if you know what you are doing!
# special commands can be used inside the footer. See also section "Doxygen
# usage" for information on how to generate the default footer that doxygen
# normally uses. Note: Only use a user-defined footer if you know what you are
# doing!
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_FOOTER =
@ -1830,8 +1916,7 @@ USE_PDFLATEX = YES
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
# command to the generated LaTeX files. This will instruct LaTeX to keep running
# if errors occur, instead of asking the user for help. This option is also used
# when generating formulas in HTML.
# if errors occur, instead of asking the user for help.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@ -1844,16 +1929,6 @@ LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
# code with syntax highlighting in the LaTeX output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
@ -1934,16 +2009,6 @@ RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
# with syntax highlighting in the RTF output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
@ -2040,15 +2105,6 @@ GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
# program listings (including syntax highlighting and cross-referencing
# information) to the DOCBOOK output. Note that enabling this will significantly
# increase the size of the DOCBOOK output.
# The default value is: NO.
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
@ -2227,15 +2283,6 @@ EXTERNAL_PAGES = YES
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
# disabled, but it is recommended to install and use dot, since it yields more
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
@ -2292,11 +2339,14 @@ DOT_FONTSIZE = 10
DOT_FONTPATH =
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
# each documented class showing the direct and indirect inheritance relations.
# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a
# graph for each documented class showing the direct and indirect inheritance
# relations. In case HAVE_DOT is set as well dot will be used to draw the graph,
# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set
# to TEXT the direct and indirect inheritance relations will be shown as texts /
# links.
# Possible values are: NO, YES, TEXT and GRAPH.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
CLASS_GRAPH = YES
@ -2333,10 +2383,32 @@ UML_LOOK = YES
# but if the number exceeds 15, the total amount of fields shown is limited to
# 10.
# Minimum value: 0, maximum value: 100, default value: 10.
# This tag requires that the tag HAVE_DOT is set to YES.
# This tag requires that the tag UML_LOOK is set to YES.
UML_LIMIT_NUM_FIELDS = 10
# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and
# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS
# tag is set to YES, doxygen will add type and arguments for attributes and
# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen
# will not generate fields with class member information in the UML graphs. The
# class diagrams will look similar to the default class diagrams but using UML
# notation for the relationships.
# Possible values are: NO, YES and NONE.
# The default value is: NO.
# This tag requires that the tag UML_LOOK is set to YES.
DOT_UML_DETAILS = NO
# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
# to display on a single line. If the actual line length exceeds this threshold
# significantly it will wrapped across multiple lines. Some heuristics are apply
# to avoid ugly line breaks.
# Minimum value: 0, maximum value: 1000, default value: 17.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_WRAP_THRESHOLD = 17
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
# collaboration graphs will show the relations between templates and their
# instances.
@ -2403,6 +2475,13 @@ GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels
# of child directories generated in directory dependency graphs by dot.
# Minimum value: 1, maximum value: 25, default value: 1.
# This tag requires that the tag DIRECTORY_GRAPH is set to YES.
DIR_GRAPH_MAX_DEPTH = 1
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. For an explanation of the image formats see the section
# output formats in the documentation of the dot tool (Graphviz (see:
@ -2456,10 +2535,10 @@ MSCFILE_DIRS =
DIAFILE_DIRS =
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
# path where java can find the plantuml.jar file. If left blank, it is assumed
# PlantUML is not used or called during a preprocessing step. Doxygen will
# generate a warning when it encounters a \startuml command in this case and
# will not generate output for the diagram.
# path where java can find the plantuml.jar file or to the filename of jar file
# to be used. If left blank, it is assumed PlantUML is not used or called during
# a preprocessing step. Doxygen will generate a warning when it encounters a
# \startuml command in this case and will not generate output for the diagram.
PLANTUML_JAR_PATH =
@ -2521,14 +2600,18 @@ DOT_MULTI_TARGETS = YES
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
# explaining the meaning of the various boxes and arrows in the dot generated
# graphs.
# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal
# graphical representation for inheritance and collaboration diagrams is used.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
# files that are used to generate the various graphs.
#
# Note: This setting is not only used for dot files but also for msc temporary
# files.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_CLEANUP = YES

View File

@ -2,7 +2,7 @@
.\" SPDX-License-Identifier: GPL-3.0-or-later
.\" SPDX-FileCopyrightText: Carles Fernandez-Prades <carles.fernandez(at)cttc.es>
.\" Contact carles.fernandez@cttc.es to correct errors or typos.
.TH gnss\-sdr 1 "23 Aug 2021" "0.0.15" "gnss\-sdr man page"
.TH gnss\-sdr 1 "15 Feb 2022" "0.0.16" "gnss\-sdr man page"
.SH NAME
\fBgnss\-sdr\fR \- GNSS Software Defined Receiver.
.SH SYNOPSIS

View File

@ -1698,7 +1698,7 @@ void rtklib_pvt_gs::log_source_timetag_info(double RX_time_ns, double TAG_time_n
}
catch (const std::exception& e)
{
std::cerr << "Problem writting at the log PVT timetag metadata file: " << e.what() << '\n';
std::cerr << "Problem writing at the log PVT timetag metadata file: " << e.what() << '\n';
}
}
}

View File

@ -98,7 +98,7 @@ public:
* \brief Print RINEX annotation. If it is the first annotation, it also
* prints the RINEX headers for navigation and observation files. If it is
* not the first annotation, it only annotates the observation, and updates
* the navigation header if UTC data was not available when writting it for
* the navigation header if UTC data was not available when writing it for
* the first time. The meaning of type_of_rx is as follows:
*
* type_of_rx | Signals

View File

@ -406,6 +406,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
bool gps_dual_band = false;
bool band1 = false;
bool band2 = false;
bool gal_e5_is_e5b = false;
for (gnss_observables_iter = gnss_observables_map.cbegin();
gnss_observables_iter != gnss_observables_map.cend();
++gnss_observables_iter)
@ -468,7 +469,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
}
// Galileo E5
if (sig_ == "5X")
if ((sig_ == "5X") || (sig_ == "7X"))
{
// 1 Gal - find the ephemeris for the current GALILEO SV observation. The SV PRN ID is the map key
galileo_ephemeris_iter = galileo_ephemeris_map.find(gnss_observables_iter->second.PRN);
@ -508,6 +509,10 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
{
DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN;
}
if (sig_ == "7X")
{
gal_e5_is_e5b = true;
}
}
break;
}
@ -873,10 +878,18 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
for (int i = 0; i < MAXSAT; i++)
{
for (int j = 0; j < NFREQ; j++)
{
if (j == 2 && gal_e5_is_e5b)
{
// frq = 4 corresponds to E5B in that function
nav_data.lam[i][j] = satwavelen(i + 1, 4, &nav_data);
}
else
{
nav_data.lam[i][j] = satwavelen(i + 1, j, &nav_data);
}
}
}
result = rtkpos(&d_rtk, d_obs_data.data(), valid_obs + glo_valid_obs, &nav_data);

View File

@ -216,7 +216,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items,
d_state = 1;
}
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
break;
@ -368,7 +368,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += d_fft_size * ninput_items[0]; // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
acquisition_message = 1;
@ -403,7 +403,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
acquisition_message = 2;

View File

@ -852,7 +852,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
}
d_worker_active = false;
if ((d_num_noncoherent_integrations_counter == d_acq_parameters.max_dwells) or (d_positive_acq == 1))
if ((d_num_noncoherent_integrations_counter == d_acq_parameters.max_dwells) or (d_positive_acq == 1) or (d_acq_parameters.bit_transition_flag))
{
// Record results to file if required
if (d_dump and d_channel == d_dump_channel)
@ -888,7 +888,7 @@ void pcps_acquisition::calculate_threshold()
const int num_bins = effective_fft_size * num_doppler_bins;
d_threshold = static_cast<float>(2.0 * boost::math::gamma_p_inv(2.0 * d_acq_parameters.max_dwells, std::pow(1.0 - pfa, 1.0 / static_cast<float>(num_bins))));
d_threshold = static_cast<float>(2.0 * boost::math::gamma_p_inv(2.0 * (d_acq_parameters.bit_transition_flag ? 1 : d_acq_parameters.max_dwells), std::pow(1.0 - pfa, 1.0 / static_cast<float>(num_bins))));
}

View File

@ -226,7 +226,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
d_state = 1;
}
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
break;
@ -389,7 +389,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
acquisition_message = 1;
@ -424,7 +424,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
acquisition_message = 2;

View File

@ -680,7 +680,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items,
d_state = 1;
}
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
break;
}
@ -710,7 +710,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items,
{
// We already have d_max_dwells consecutive blocks in the internal buffer,
// just skip input blocks.
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]);
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0];
}
// We create a new thread to process next block if the following
@ -754,7 +754,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
acquisition_message = 1;
this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message));
@ -788,7 +788,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
acquisition_message = 2;
this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message));

View File

@ -256,7 +256,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
d_state = 1;
}
d_sample_counter += static_cast<uint64_t>(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_sampled_ms) * d_samples_per_ms * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
// DLOG(INFO) << "END CASE 0";
break;
@ -290,7 +290,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
d_test_statistics = 0.0;
d_noise_floor_power = 0.0;
d_sample_counter += static_cast<uint64_t>(d_sampled_ms * d_samples_per_ms); // sample counter
d_sample_counter += static_cast<uint64_t>(d_sampled_ms) * d_samples_per_ms; // sample counter
d_well_count++;
@ -495,7 +495,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += static_cast<uint64_t>(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_sampled_ms) * d_samples_per_ms * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
acquisition_message = 1;
@ -538,7 +538,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += static_cast<uint64_t>(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_sampled_ms) * d_samples_per_ms * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
acquisition_message = 2;

View File

@ -251,7 +251,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
d_state = 1;
}
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
break;
@ -390,7 +390,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
acquisition_message = 1;
@ -425,7 +425,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items,
d_active = false;
d_state = 0;
d_sample_counter += static_cast<uint64_t>(d_fft_size * ninput_items[0]); // sample counter
d_sample_counter += static_cast<uint64_t>(d_fft_size) * ninput_items[0]; // sample counter
consume_each(ninput_items[0]);
acquisition_message = 2;

View File

@ -71,6 +71,10 @@ obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro
break;
case 'E':
rtklib_obs.sat = gnss_synchro.PRN + NSATGPS + NSATGLO;
if (sig_ == "7X")
{
rtklib_obs.code[band] = static_cast<unsigned char>(CODE_L7X);
}
break;
case 'R':
rtklib_obs.sat = gnss_synchro.PRN + NSATGPS;

View File

@ -8,7 +8,7 @@
########################################################################
# Project setup
########################################################################
cmake_minimum_required(VERSION 2.8.12...3.21)
cmake_minimum_required(VERSION 2.8.12...3.22)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
@ -209,7 +209,7 @@ message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
set(VERSION_INFO_MAJOR_VERSION 0)
set(VERSION_INFO_MINOR_VERSION 0)
set(VERSION_INFO_MAINT_VERSION 15)
set(VERSION_INFO_MAINT_VERSION 16)
include(VolkGnsssdrVersion) # setup version info

View File

@ -46,8 +46,7 @@ kernel is actually doing.
This figure shows the role of some VOLK_GNSSSDR kernels in the context of a GNSS
baseband processor:
![Example of VOLK_GNSSSDR
usage.](./docs/images/VOLK_GNSSSDR_Usage_Example.png)
![Example of VOLK_GNSSSDR usage.](./docs/images/VOLK_GNSSSDR_Usage_Example.png)
## How to build VOLK_GNSSSDR

View File

@ -2,7 +2,7 @@
.\" SPDX-License-Identifier: GPL-3.0-or-later
.\" SPDX-FileCopyrightText: Carles Fernandez-Prades <carles.fernandez(at)cttc.es>
.\" Contact carles.fernandez@cttc.es to correct errors or typos.
.TH volk_gnsssdr\-config\-info 1 "23 Aug 2021" "0.0.15" "volk_gnsssdr\-config\-info man page"
.TH volk_gnsssdr\-config\-info 1 "15 Feb 2022" "0.0.16" "volk_gnsssdr\-config\-info man page"
.SH NAME
\fBvolk_gnsssdr\-config\-info\fR \- Prints configuration information of libvolk_gnsssdr functions.
.SH SYNOPSIS

View File

@ -2,7 +2,7 @@
.\" SPDX-License-Identifier: GPL-3.0-or-later
.\" SPDX-FileCopyrightText: Carles Fernandez-Prades <carles.fernandez(at)cttc.es>
.\" Contact carles.fernandez@cttc.es to correct errors or typos.
.TH volk_gnsssdr_profile 1 "23 Aug 2021" "0.0.15" "volk_gnsssdr_profile man page"
.TH volk_gnsssdr_profile 1 "15 Feb 2022" "0.0.16" "volk_gnsssdr_profile man page"
.SH NAME
\fBvolk_gnsssdr_profile\fR \- Profiler application for libvolk_gnsssdr functions.
.SH SYNOPSIS

View File

@ -65,11 +65,6 @@ uint32_t GetXCR0Eax(void) { return (uint32_t)_xgetbv(0); }
#error "Unsupported compiler, x86 cpuid requires either GCC, Clang or MSVC."
#endif
static Leaf CpuId(uint32_t leaf_id)
{
return GetCpuidLeaf(leaf_id, 0);
}
static const Leaf kEmptyLeaf;
static Leaf SafeCpuIdEx(uint32_t max_cpuid_leaf, uint32_t leaf_id, int ecx)
@ -84,9 +79,42 @@ static Leaf SafeCpuIdEx(uint32_t max_cpuid_leaf, uint32_t leaf_id, int ecx)
}
}
static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id)
typedef struct
{
return SafeCpuIdEx(max_cpuid_leaf, leaf_id, 0);
uint32_t max_cpuid_leaf;
Leaf leaf_0; // Root
Leaf leaf_1; // Family, Model, Stepping
Leaf leaf_2; // Intel cache info + features
Leaf leaf_7; // Features
Leaf leaf_7_1; // Features
uint32_t max_cpuid_leaf_ext;
Leaf leaf_80000000; // Root for extended leaves
Leaf leaf_80000001; // AMD features features and cache
Leaf leaf_80000002; // brand string
Leaf leaf_80000003; // brand string
Leaf leaf_80000004; // brand string
} Leaves;
static Leaves ReadLeaves()
{
const Leaf leaf_0 = GetCpuidLeaf(0, 0);
const uint32_t max_cpuid_leaf = leaf_0.eax;
const Leaf leaf_80000000 = GetCpuidLeaf(0x80000000, 0);
const uint32_t max_cpuid_leaf_ext = leaf_80000000.eax;
return (Leaves){
.max_cpuid_leaf = max_cpuid_leaf,
.leaf_0 = leaf_0,
.leaf_1 = SafeCpuIdEx(max_cpuid_leaf, 0x00000001, 0),
.leaf_2 = SafeCpuIdEx(max_cpuid_leaf, 0x00000002, 0),
.leaf_7 = SafeCpuIdEx(max_cpuid_leaf, 0x00000007, 0),
.leaf_7_1 = SafeCpuIdEx(max_cpuid_leaf, 0x00000007, 1),
.max_cpuid_leaf_ext = max_cpuid_leaf_ext,
.leaf_80000000 = leaf_80000000,
.leaf_80000001 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000001, 0),
.leaf_80000002 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000002, 0),
.leaf_80000003 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000003, 0),
.leaf_80000004 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000004, 0),
};
}
////////////////////////////////////////////////////////////////////////////////
@ -162,19 +190,19 @@ static int IsVendorByX86Info(const X86Info* info, const char* const name)
return equals(info->vendor, name, sizeof(info->vendor));
}
// TODO: Remove when deprecation period is over,
void FillX86BrandString(char brand_string[49])
{
const Leaf leaf_ext_0 = CpuId(0x80000000);
const uint32_t max_cpuid_leaf_ext = leaf_ext_0.eax;
const Leaf leaves[3] = {
SafeCpuId(max_cpuid_leaf_ext, 0x80000002),
SafeCpuId(max_cpuid_leaf_ext, 0x80000003),
SafeCpuId(max_cpuid_leaf_ext, 0x80000004),
const Leaves leaves = ReadLeaves();
const Leaf packed[3] = {
leaves.leaf_80000002,
leaves.leaf_80000003,
leaves.leaf_80000004,
};
#if __STDC_VERSION__ >= 201112L
_Static_assert(sizeof(leaves) == 48, "Leaves must be packed");
_Static_assert(sizeof(packed) == 48, "Leaves must be packed");
#endif
copy(brand_string, (const char*)(leaves), 48);
copy(brand_string, (const char*)(packed), 48);
brand_string[48] = '\0';
}
@ -182,34 +210,36 @@ void FillX86BrandString(char brand_string[49])
// CpuId
////////////////////////////////////////////////////////////////////////////////
static bool HasSecondFMA(uint32_t model)
static bool HasSecondFMA(const X86Info* info)
{
// Skylake server
if (model == 0x55)
if (info->model == 0x55)
{
char proc_name[49] = {0};
FillX86BrandString(proc_name);
// detect Xeon
if (proc_name[9] == 'X')
if (info->brand_string[9] == 'X')
{
// detect Silver or Bronze
if (proc_name[17] == 'S' || proc_name[17] == 'B') return false;
if (info->brand_string[17] == 'S' || info->brand_string[17] == 'B')
return false;
// detect Gold 5_20 and below, except for Gold 53__
if (proc_name[17] == 'G' && proc_name[22] == '5')
return ((proc_name[23] == '3') ||
(proc_name[24] == '2' && proc_name[25] == '2'));
if (info->brand_string[17] == 'G' && info->brand_string[22] == '5')
return (
(info->brand_string[23] == '3') ||
(info->brand_string[24] == '2' && info->brand_string[25] == '2'));
// detect Xeon W 210x
if (proc_name[17] == 'W' && proc_name[21] == '0') return false;
if (info->brand_string[17] == 'W' && info->brand_string[21] == '0')
return false;
// detect Xeon D 2xxx
if (proc_name[17] == 'D' && proc_name[19] == '2' && proc_name[20] == '1')
if (info->brand_string[17] == 'D' && info->brand_string[19] == '2' &&
info->brand_string[20] == '1')
return false;
}
return true;
}
// Cannon Lake client
if (model == 0x66) return false;
if (info->model == 0x66) return false;
// Ice Lake client
if (model == 0x7d || model == 0x7e) return false;
if (info->model == 0x7d || info->model == 0x7e) return false;
// This is the right default...
return true;
}
@ -227,15 +257,15 @@ typedef struct
// These two functions have to be implemented by the OS, that is the file
// including this file.
static void OverrideOsPreserves(OsPreserves* os_preserves);
static void DetectFeaturesFromOs(X86Features* features);
static void DetectFeaturesFromOs(X86Info* info, X86Features* features);
// Reference https://en.wikipedia.org/wiki/CPUID.
static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info,
static void ParseCpuId(const Leaves* leaves, X86Info* info,
OsPreserves* os_preserves)
{
const Leaf leaf_1 = SafeCpuId(max_cpuid_leaf, 1);
const Leaf leaf_7 = SafeCpuId(max_cpuid_leaf, 7);
const Leaf leaf_7_1 = SafeCpuIdEx(max_cpuid_leaf, 7, 1);
const Leaf leaf_1 = leaves->leaf_1;
const Leaf leaf_7 = leaves->leaf_7;
const Leaf leaf_7_1 = leaves->leaf_7_1;
const bool have_xsave = IsBitSet(leaf_1.ecx, 26);
const bool have_osxsave = IsBitSet(leaf_1.ecx, 27);
@ -248,10 +278,24 @@ static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info,
X86Features* const features = &info->features;
// Fill Family, Model and Stepping.
info->family = extended_family + family;
info->model = (extended_model << 4) + model;
info->stepping = ExtractBitRange(leaf_1.eax, 3, 0);
// Fill Brand String.
const Leaf packed[3] = {
leaves->leaf_80000002,
leaves->leaf_80000003,
leaves->leaf_80000004,
};
#if __STDC_VERSION__ >= 201112L
_Static_assert(sizeof(packed) == 48, "Leaves must be packed");
#endif
copy(info->brand_string, (const char*)(packed), 48);
info->brand_string[48] = '\0';
// Fill cpu features.
features->fpu = IsBitSet(leaf_1.edx, 0);
features->tsc = IsBitSet(leaf_1.edx, 4);
features->cx8 = IsBitSet(leaf_1.edx, 8);
@ -330,7 +374,7 @@ static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info,
features->avx512vpopcntdq = IsBitSet(leaf_7.ecx, 14);
features->avx512_4vnniw = IsBitSet(leaf_7.edx, 2);
features->avx512_4vbmi2 = IsBitSet(leaf_7.edx, 3);
features->avx512_second_fma = HasSecondFMA(info->model);
features->avx512_second_fma = HasSecondFMA(info);
features->avx512_4fmaps = IsBitSet(leaf_7.edx, 3);
features->avx512_bf16 = IsBitSet(leaf_7_1.eax, 5);
features->avx512_vp2intersect = IsBitSet(leaf_7.edx, 8);
@ -346,7 +390,7 @@ static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info,
{
// When XCR0 is not available (Atom based or older cpus) we need to defer to
// the OS via custom code.
DetectFeaturesFromOs(features);
DetectFeaturesFromOs(info, features);
// Now that we have queried the OS for SSE support, we report this back to
// os_preserves. This is needed in case of AMD CPU's to enable testing of
// sse4a (See ParseExtraAMDCpuId below).
@ -354,17 +398,10 @@ static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info,
}
}
// Reference
// https://en.wikipedia.org/wiki/CPUID#EAX=80000000h:_Get_Highest_Extended_Function_Implemented.
static Leaf GetLeafByIdAMD(uint32_t leaf_id)
static void ParseExtraAMDCpuId(const Leaves* leaves, X86Info* info,
OsPreserves os_preserves)
{
uint32_t max_extended = CpuId(0x80000000).eax;
return SafeCpuId(max_extended, leaf_id);
}
static void ParseExtraAMDCpuId(X86Info* info, OsPreserves os_preserves)
{
const Leaf leaf_80000001 = GetLeafByIdAMD(0x80000001);
const Leaf leaf_80000001 = leaves->leaf_80000001;
X86Features* const features = &info->features;
@ -385,19 +422,24 @@ static const OsPreserves kEmptyOsPreserves;
X86Info GetX86Info(void)
{
X86Info info = kEmptyX86Info;
const Leaf leaf_0 = CpuId(0);
const bool is_intel = IsVendor(leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL);
const bool is_amd = IsVendor(leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
const bool is_hygon = IsVendor(leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE);
SetVendor(leaf_0, info.vendor);
if (is_intel || is_amd || is_hygon)
const Leaves leaves = ReadLeaves();
const bool is_intel =
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL);
const bool is_amd =
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
const bool is_hygon =
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE);
const bool is_zhaoxin =
(IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_CENTAUR_HAULS) ||
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_SHANGHAI));
SetVendor(leaves.leaf_0, info.vendor);
if (is_intel || is_amd || is_hygon || is_zhaoxin)
{
OsPreserves os_preserves = kEmptyOsPreserves;
const uint32_t max_cpuid_leaf = leaf_0.eax;
ParseCpuId(max_cpuid_leaf, &info, &os_preserves);
ParseCpuId(&leaves, &info, &os_preserves);
if (is_amd || is_hygon)
{
ParseExtraAMDCpuId(&info, os_preserves);
ParseExtraAMDCpuId(&leaves, &info, os_preserves);
}
}
return info;
@ -563,6 +605,46 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info)
return X86_UNKNOWN;
}
}
if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_CENTAUR_HAULS))
{
switch (CPUID(info->family, info->model))
{
case CPUID(0x06, 0x0F):
case CPUID(0x06, 0x19):
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/zhangjiang
return ZHAOXIN_ZHANGJIANG;
case CPUID(0x07, 0x1B):
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/wudaokou
return ZHAOXIN_WUDAOKOU;
case CPUID(0x07, 0x3B):
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/lujiazui
return ZHAOXIN_LUJIAZUI;
case CPUID(0x07, 0x5B):
return ZHAOXIN_YONGFENG;
default:
return X86_UNKNOWN;
}
}
if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_SHANGHAI))
{
switch (CPUID(info->family, info->model))
{
case CPUID(0x06, 0x0F):
case CPUID(0x06, 0x19):
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/zhangjiang
return ZHAOXIN_ZHANGJIANG;
case CPUID(0x07, 0x1B):
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/wudaokou
return ZHAOXIN_WUDAOKOU;
case CPUID(0x07, 0x3B):
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/lujiazui
return ZHAOXIN_LUJIAZUI;
case CPUID(0x07, 0x5B):
return ZHAOXIN_YONGFENG;
default:
return X86_UNKNOWN;
}
}
if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_AUTHENTIC_AMD))
{
switch (CPUID(info->family, info->model))
@ -1551,9 +1633,9 @@ static CacheLevelInfo GetCacheLevelInfo(const uint32_t reg)
}
// From https://www.felixcloutier.com/x86/cpuid#tbl-3-12
static void ParseLeaf2(const int max_cpuid_leaf, CacheInfo* info)
static void ParseLeaf2(const Leaves* leaves, CacheInfo* info)
{
Leaf leaf = SafeCpuId(max_cpuid_leaf, 2);
Leaf leaf = leaves->leaf_2;
// The least-significant byte in register EAX (register AL) will always return
// 01H. Software should ignore this value and not interpret it as an
// informational descriptor.
@ -1626,24 +1708,23 @@ static void ParseCacheInfo(const int max_cpuid_leaf, uint32_t leaf_id,
CacheInfo GetX86CacheInfo(void)
{
CacheInfo info = kEmptyCacheInfo;
const Leaf leaf_0 = CpuId(0);
if (IsVendor(leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL))
const Leaves leaves = ReadLeaves();
if (IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL) ||
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_CENTAUR_HAULS) ||
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_SHANGHAI))
{
ParseLeaf2(leaf_0.eax, &info);
ParseCacheInfo(leaf_0.eax, 4, &info);
ParseLeaf2(&leaves, &info);
ParseCacheInfo(leaves.max_cpuid_leaf, 4, &info);
}
else if (IsVendor(leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD) ||
IsVendor(leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE))
else if (IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD) ||
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE))
{
const uint32_t max_ext = CpuId(0x80000000).eax;
const uint32_t cpuid_ext = SafeCpuId(max_ext, 0x80000001).ecx;
// If CPUID Fn8000_0001_ECX[TopologyExtensions]==0
// then CPUID Fn8000_0001_E[D,C,B,A]X is reserved.
// https://www.amd.com/system/files/TechDocs/25481.pdf
if (IsBitSet(cpuid_ext, 22))
if (IsBitSet(leaves.leaf_80000001.ecx, 22))
{
ParseCacheInfo(max_ext, 0x8000001D, &info);
ParseCacheInfo(leaves.max_cpuid_leaf_ext, 0x8000001D, &info);
}
}
return info;
@ -1720,6 +1801,10 @@ CacheInfo GetX86CacheInfo(void)
#define X86_MICROARCHITECTURE_NAMES \
LINE(X86_UNKNOWN) \
LINE(ZHAOXIN_ZHANGJIANG) \
LINE(ZHAOXIN_WUDAOKOU) \
LINE(ZHAOXIN_LUJIAZUI) \
LINE(ZHAOXIN_YONGFENG) \
LINE(INTEL_80486) \
LINE(INTEL_P5) \
LINE(INTEL_LAKEMONT) \

View File

@ -1,8 +1,11 @@
/*!
* \file ad9361_fpga_signal_source.cc
* \brief signal source for Analog Devices front-end AD9361 connected directly to FPGA accelerators.
* This source implements only the AD9361 control. It is NOT compatible with conventional SDR acquisition and tracking blocks.
* Please use the fmcomms2 source if conventional SDR acquisition and tracking is selected in the configuration file.
* \brief signal source for Analog Devices front-end AD9361 connected directly
* to FPGA accelerators.
* This source implements only the AD9361 control. It is NOT compatible with
* conventional SDR acquisition and tracking blocks.
* Please use the fmcomms2 source if conventional SDR acquisition and tracking
* is selected in the configuration file.
* \authors <ul>
* <li> Javier Arribas, jarribas(at)cttc.es
* <li> Marc Majoral, mmajoral(at)cttc.es
@ -30,19 +33,16 @@
#include "uio_fpga.h"
#include <glog/logging.h>
#include <iio.h>
#include <algorithm> // for max
#include <chrono> // for std::this_thread
#include <cmath> // for abs
#include <exception> // for exceptions
#include <algorithm> // for std::max
#include <chrono> // for std::chrono
#include <cmath> // for std::floor
#include <exception> // for std::exception
#include <fcntl.h> // for open, O_WRONLY
#include <fstream> // for std::ifstream
#include <iomanip> // for std::setprecision
#include <iostream> // for cout
#include <string> // for string manipulation
#include <thread> // for std::chrono
#include <iostream> // for std::cout
#include <unistd.h> // for write
#include <utility>
#include <vector>
#include <vector> // fr std::vector
using namespace std::string_literals;
@ -50,32 +50,53 @@ using namespace std::string_literals;
Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *configuration,
const std::string &role, unsigned int in_stream, unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t> *queue __attribute__((unused)))
: SignalSourceBase(configuration, role, "Ad9361_Fpga_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream), queue_(queue)
: SignalSourceBase(configuration, role, "Ad9361_Fpga_Signal_Source"s),
queue_(queue),
gain_mode_rx1_(configuration->property(role + ".gain_mode_rx1", default_gain_mode)),
gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)),
rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)),
filter_filename_(configuration->property(role + ".filter_filename", filter_file_)),
rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)),
rf_gain_rx2_(configuration->property(role + ".gain_rx1", default_manual_gain_rx2)),
freq_(configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ))),
sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)),
bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)),
samples_to_skip_(0),
samples_(configuration->property(role + ".samples", static_cast<int64_t>(0))),
Fpass_(configuration->property(role + ".Fpass", static_cast<float>(0.0))),
Fstop_(configuration->property(role + ".Fstop", static_cast<float>(0.0))),
num_freq_bands_(2),
dma_buff_offset_pos_(0),
scale_dds_dbfs_(configuration->property(role + ".scale_dds_dbfs", -3.0)),
phase_dds_deg_(configuration->property(role + ".phase_dds_deg", 0.0)),
tx_attenuation_db_(configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db)),
freq_dds_tx_hz_(configuration->property(role + ".freq_dds_tx_hz", uint64_t(10000))),
freq_rf_tx_hz_(configuration->property(role + ".freq_rf_tx_hz", static_cast<uint64_t>(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_))),
tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast<uint64_t>(500000))),
item_size_(sizeof(int8_t)),
in_stream_(in_stream),
out_stream_(out_stream),
switch_position_(configuration->property(role + ".switch_position", 0)),
enable_dds_lo_(configuration->property(role + ".enable_dds_lo", false)),
filter_auto_(configuration->property(role + ".filter_auto", false)),
quadrature_(configuration->property(role + ".quadrature", true)),
rf_dc_(configuration->property(role + ".rf_dc", true)),
bb_dc_(configuration->property(role + ".bb_dc", true)),
rx1_enable_(configuration->property(role + ".rx1_enable", true)),
rx2_enable_(configuration->property(role + ".rx2_enable", true)),
enable_DMA_(false),
enable_dynamic_bit_selection_(configuration->property(role + ".enable_dynamic_bit_selection", true)),
enable_ovf_check_buffer_monitor_active_(false),
dump_(configuration->property(role + ".dump", false)),
rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)),
repeat_(configuration->property(role + ".repeat", false))
{
// initialize the variables that are used in real-time mode
const int l1_band = configuration->property("Channels_1C.count", 0) +
configuration->property("Channels_1B.count", 0);
const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", 0.0);
const size_t header_size = configuration->property(role + ".header_size", 0);
const std::string default_gain_mode("slow_attack");
const double default_tx_attenuation_db = -10.0;
const double default_manual_gain_rx1 = 64.0;
const double default_manual_gain_rx2 = 64.0;
const uint64_t default_bandwidth = 12500000;
const std::string default_rf_port_select("A_BALANCED");
freq_ = configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ));
sample_rate_ = configuration->property(role + ".sampling_frequency", static_cast<uint64_t>(12500000));
bandwidth_ = configuration->property(role + ".bandwidth", default_bandwidth);
quadrature_ = configuration->property(role + ".quadrature", true);
rf_dc_ = configuration->property(role + ".rf_dc", true);
bb_dc_ = configuration->property(role + ".bb_dc", true);
rx1_enable_ = configuration->property(role + ".rx1_enable", true);
rx2_enable_ = configuration->property(role + ".rx2_enable", true);
gain_mode_rx1_ = configuration->property(role + ".gain_mode_rx1", default_gain_mode);
gain_mode_rx2_ = configuration->property(role + ".gain_mode_rx2", default_gain_mode);
rf_gain_rx1_ = configuration->property(role + ".gain_rx1", default_manual_gain_rx1);
rf_gain_rx2_ = configuration->property(role + ".gain_rx2", default_manual_gain_rx2);
rf_port_select_ = configuration->property(role + ".rf_port_select", default_rf_port_select);
filter_file_ = configuration->property(role + ".filter_file", std::string(""));
filter_filename_ = configuration->property(role + ".filter_filename", filter_file_);
filter_auto_ = configuration->property(role + ".filter_auto", false);
if (filter_auto_)
{
filter_source_ = configuration->property(role + ".filter_source", std::string("Auto"));
@ -84,29 +105,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
{
filter_source_ = configuration->property(role + ".filter_source", std::string("Off"));
}
Fpass_ = configuration->property(role + ".Fpass", static_cast<float>(0.0));
Fstop_ = configuration->property(role + ".Fstop", static_cast<float>(0.0));
enable_dds_lo_ = configuration->property(role + ".enable_dds_lo", false);
freq_dds_tx_hz_ = configuration->property(role + ".freq_dds_tx_hz", static_cast<uint64_t>(10000));
freq_rf_tx_hz_ = configuration->property(role + ".freq_rf_tx_hz", static_cast<uint64_t>(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_));
scale_dds_dbfs_ = configuration->property(role + ".scale_dds_dbfs", -3.0);
tx_attenuation_db_ = configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db);
tx_bandwidth_ = configuration->property(role + ".tx_bandwidth", static_cast<uint64_t>(500000));
phase_dds_deg_ = configuration->property(role + ".phase_dds_deg", 0.0);
rf_shutdown_ = configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown);
// initialize the variables that are used in post-processing mode
enable_DMA_ = false;
const int l1_band = configuration->property("Channels_1C.count", 0) +
configuration->property("Channels_1B.count", 0);
const double default_seconds_to_skip = 0.0;
const std::string empty_string;
filename0 = configuration->property(role + ".filename", empty_string);
// override value with commandline flag, if present
if (FLAGS_signal_source != "-")
@ -118,16 +116,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
filename0 = FLAGS_s;
}
if (filename0.empty())
{
filename0 = configuration->property(role + ".filename0", empty_string);
filename1 = configuration->property(role + ".filename1", empty_string);
}
// by default the DMA transfers samples corresponding to two frequency bands to the FPGA
num_freq_bands_ = 2;
dma_buff_offset_pos_ = 0;
// if only one input file is specified in the configuration file then:
// if there is at least one channel assigned to frequency band 1 then the DMA transfers the samples to the L1 frequency band channels
// otherwise the DMA transfers the samples to the L2/L5 frequency band channels
@ -145,15 +133,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
dma_buff_offset_pos_ = 2;
}
samples_ = configuration->property(role + ".samples", static_cast<int64_t>(0));
const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", default_seconds_to_skip);
const size_t header_size = configuration->property(role + ".header_size", 0);
std::string item_type = "ibyte"; // for now only the ibyte format is supported
item_size_ = sizeof(int8_t);
repeat_ = configuration->property(role + ".repeat", false);
samples_to_skip_ = 0;
if (seconds_to_skip > 0)
{
samples_to_skip_ = static_cast<uint64_t>(seconds_to_skip * sample_rate_) * 2;
@ -163,10 +142,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
samples_to_skip_ += header_size;
}
// check the switch status (determines real-time mode or post-processing mode)
std::string device_io_name; // Switch UIO device file
// find the uio device file corresponding to the switch.
if (find_uio_dev_file_name(device_io_name, switch_device_name, 0) < 0)
{
@ -175,7 +151,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
return;
}
switch_position_ = configuration->property(role + ".switch_position", 0);
if (switch_position_ != 0 && switch_position_ != 2)
{
std::cout << "SignalSource.switch_position configuration parameter must be either 0: read from file(s) via DMA, or 2: read from AD9361\n";
@ -272,7 +247,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
}
DLOG(INFO) << "Samples " << samples_;
DLOG(INFO) << "Sampling frequency " << sample_rate_;
DLOG(INFO) << "Item type " << item_type;
DLOG(INFO) << "Item type " << std::string("ibyte");
DLOG(INFO) << "Item size " << item_size_;
DLOG(INFO) << "Repeat " << repeat_;
}
@ -429,7 +404,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
std::string device_io_name_buffer_monitor;
dump_ = configuration->property(role + ".dump", false);
std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename);
// find the uio device file corresponding to the buffer monitor
@ -445,7 +419,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
}
// dynamic bits selection
enable_dynamic_bit_selection_ = configuration->property(role + ".enable_dynamic_bit_selection", true);
if (enable_dynamic_bit_selection_)
{
std::string device_io_name_dyn_bit_sel_0;
@ -616,7 +589,6 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
}
}
// rx signal vectors
std::vector<int8_t> input_samples(sample_block_size * 2); // complex samples
std::vector<int8_t> input_samples_dma(sample_block_size * 4); // complex samples, two frequency bands

View File

@ -1,8 +1,11 @@
/*!
* \file ad9361_fpga_signal_source.h
* \brief signal source for Analog Devices front-end AD9361 connected directly to FPGA accelerators.
* This source implements only the AD9361 control. It is NOT compatible with conventional SDR acquisition and tracking blocks.
* Please use the fmcomms2 source if conventional SDR acquisition and tracking is selected in the configuration file.
* \brief signal source for Analog Devices front-end AD9361 connected directly
* to FPGA accelerators.
* This source implements only the AD9361 control. It is NOT compatible with
* conventional SDR acquisition and tracking blocks.
* Please use the fmcomms2 source if conventional SDR acquisition and tracking
* is selected in the configuration file.
*
* -----------------------------------------------------------------------------
*
@ -62,10 +65,17 @@ public:
gr::basic_block_sptr get_right_block() override;
private:
const std::string switch_device_name = "AXIS_Switch_v1_0_0"; // Switch UIO device name
const std::string dyn_bit_sel_device_name = "dynamic_bits_selector"; // Switch dhnamic bit selector device name
const std::string buffer_monitor_device_name = "buffer_monitor"; // buffer monitor device name
const std::string switch_device_name = std::string("AXIS_Switch_v1_0_0"); // Switch UIO device name
const std::string dyn_bit_sel_device_name = std::string("dynamic_bits_selector"); // Switch dhnamic bit selector device name
const std::string buffer_monitor_device_name = std::string("buffer_monitor"); // buffer monitor device name
const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat");
const std::string default_rf_port_select = std::string("A_BALANCED");
const std::string default_gain_mode = std::string("slow_attack");
const double default_tx_attenuation_db = -10.0;
const double default_manual_gain_rx1 = 64.0;
const double default_manual_gain_rx2 = 64.0;
const uint64_t default_bandwidth = 12500000;
// perform dynamic bit selection every 500 ms by default
const uint32_t Gain_control_period_ms = 500;
// check buffer overflow and perform buffer monitoring every 1s by default
@ -95,6 +105,12 @@ private:
std::shared_ptr<Fpga_dynamic_bit_selection> dynamic_bit_selection_fpga;
std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga;
std::mutex dma_mutex;
std::mutex dynamic_bit_selection_mutex;
std::mutex buffer_monitor_mutex;
Concurrent_Queue<pmt::pmt_t> *queue_;
// Front-end settings
std::string gain_mode_rx1_;
std::string gain_mode_rx2_;
@ -105,24 +121,24 @@ private:
std::string filename0;
std::string filename1;
std::mutex dma_mutex;
std::mutex dynamic_bit_selection_mutex;
std::mutex buffer_monitor_mutex;
double rf_gain_rx1_;
double rf_gain_rx2_;
uint64_t freq_; // frequency of local oscillator
uint64_t sample_rate_;
uint64_t bandwidth_;
uint64_t samples_to_skip_;
int64_t samples_;
float Fpass_;
float Fstop_;
uint32_t num_freq_bands_;
uint32_t dma_buff_offset_pos_;
// DDS configuration for LO generation for external mixer
double scale_dds_dbfs_;
double phase_dds_deg_;
double tx_attenuation_db_;
uint64_t freq_rf_tx_hz_;
uint64_t freq_dds_tx_hz_;
uint64_t freq_rf_tx_hz_;
uint64_t tx_bandwidth_;
size_t item_size_;
uint32_t in_stream_;
@ -141,15 +157,7 @@ private:
bool enable_ovf_check_buffer_monitor_active_;
bool dump_;
bool rf_shutdown_;
// post-processing mode
int64_t samples_;
uint64_t samples_to_skip_;
bool repeat_;
uint32_t num_freq_bands_;
uint32_t dma_buff_offset_pos_;
Concurrent_Queue<pmt::pmt_t> *queue_;
};

View File

@ -15,15 +15,25 @@
*/
#include "file_source_base.h"
#include "Beidou_B1I.h"
#include "Beidou_B3I.h"
#include "GPS_L1_CA.h"
#include "GPS_L2C.h"
#include "GPS_L5.h"
#include "Galileo_E1.h"
#include "Galileo_E5a.h"
#include "Galileo_E5b.h"
#include "Galileo_E6.h"
#include "configuration_interface.h"
#include "gnss_sdr_filesystem.h"
#include "gnss_sdr_flags.h"
#include "gnss_sdr_string_literals.h"
#include "gnss_sdr_valve.h"
#include <glog/logging.h>
#include <cmath> // ceil, floor
#include <fstream>
#include <utility> // move
#include <algorithm> // for std::max
#include <cmath> // for ceil, floor
#include <iostream> // for std::cout, std:cerr
#include <utility> // for std::move
using namespace std::string_literals;
@ -31,31 +41,58 @@ using namespace std::string_literals;
FileSourceBase::FileSourceBase(ConfigurationInterface const* configuration, std::string const& role, std::string impl,
Concurrent_Queue<pmt::pmt_t>* queue,
std::string default_item_type)
: SignalSourceBase(configuration, role, std::move(impl)), filename_(configuration->property(role + ".filename"s, "../data/example_capture.dat"s)),
file_source_(), // NOLINT
item_type_(configuration->property(role + ".item_type"s, default_item_type)), // NOLINT
item_size_(0),
is_complex_(false),
// apparently, MacOS (LLVM) finds 0UL ambiguous with bool, int64_t, uint64_t, int32_t, int16_t, uint16_t,... float, double
header_size_(configuration->property(role + ".header_size"s, uint64_t(0))),
seconds_to_skip_(configuration->property(role + ".seconds_to_skip"s, 0.0)),
repeat_(configuration->property(role + ".repeat"s, false)),
samples_(configuration->property(role + ".samples"s, uint64_t(0))),
sampling_frequency_(configuration->property(role + ".sampling_frequency"s, int64_t(0))),
valve_(), // NOLINT
: SignalSourceBase(configuration, role, std::move(impl)),
queue_(queue),
enable_throttle_control_(configuration->property(role + ".enable_throttle_control"s, false)),
throttle_(), // NOLINT
dump_(configuration->property(role + ".dump"s, false)),
dump_filename_(configuration->property(role + ".dump_filename"s, "../data/my_capture.dat"s)),
sink_() // NOLINT
role_(role),
filename_(configuration->property(role_ + ".filename"s, "../data/example_capture.dat"s)),
dump_filename_(configuration->property(role_ + ".dump_filename"s, "../data/my_capture.dat"s)),
item_type_(configuration->property(role_ + ".item_type"s, std::move(default_item_type))),
item_size_(0),
header_size_(configuration->property(role_ + ".header_size"s, uint64_t(0))),
samples_(configuration->property(role_ + ".samples"s, uint64_t(0))),
sampling_frequency_(configuration->property(role_ + ".sampling_frequency"s, int64_t(0))),
minimum_tail_s_(0.1),
seconds_to_skip_(configuration->property(role_ + ".seconds_to_skip"s, 0.0)),
is_complex_(false),
repeat_(configuration->property(role_ + ".repeat"s, false)),
enable_throttle_control_(configuration->property(role_ + ".enable_throttle_control"s, false)),
dump_(configuration->property(role_ + ".dump"s, false))
{
minimum_tail_s_ = std::max(configuration->property("Acquisition_1C.coherent_integration_time_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Acquisition_2S.coherent_integration_time_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Acquisition_L5.coherent_integration_time_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Acquisition_1B.coherent_integration_time_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Acquisition_5X.coherent_integration_time_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Acquisition_7X.coherent_integration_time_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Acquisition_E6.coherent_integration_time_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Acquisition_B1.coherent_integration_time_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Acquisition_B3.coherent_integration_time_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Acquisition_1G.coherent_integration_time_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Acquisition_2G.coherent_integration_time_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Tracking_1C.extend_correlation_symbols", 0.0) * GPS_L1_CA_CODE_PERIOD_S * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Tracking_2S.extend_correlation_symbols", 0.0) * GPS_L2_M_PERIOD_S * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Tracking_L5.extend_correlation_symbols", 0.0) * GPS_L5I_PERIOD_S * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Tracking_1B.extend_correlation_symbols", 0.0) * GALILEO_E1_CODE_PERIOD_S * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Tracking_5X.extend_correlation_symbols", 0.0) * GALILEO_E5A_CODE_PERIOD_S * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Tracking_7X.extend_correlation_symbols", 0.0) * GALILEO_E5B_CODE_PERIOD_S * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Tracking_E6.extend_correlation_symbols", 0.0) * GALILEO_E6_CODE_PERIOD_S * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Tracking_B1.extend_correlation_symbols", 0.0) * BEIDOU_B1I_CODE_PERIOD_S * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Tracking_B3.extend_correlation_symbols", 0.0) * BEIDOU_B3I_CODE_PERIOD_S * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Tracking_1G.extend_correlation_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
minimum_tail_s_ = std::max(configuration->property("Tracking_2G.extend_correlation_ms", 0.0) * 0.001 * 2.0, minimum_tail_s_);
if (repeat())
{
minimum_tail_s_ = 0.0;
if (seconds_to_skip_ != 0.0)
{
seconds_to_skip_ = 0.0;
std::cout << "Warning: since " << role_ << ".repeat is set to true, "
<< role_ << ".seconds_to_skip parameter will be ignored.\n";
}
}
// override value with commandline flag, if present
if (FLAGS_signal_source != "-")
{
@ -67,9 +104,9 @@ FileSourceBase::FileSourceBase(ConfigurationInterface const* configuration, std:
}
if (sampling_frequency_ == 0)
{
std::cerr << "Warning: parameter " << role << ".sampling_frequency is not set, this could lead to wrong results.\n"
<< " Please set the " << role << ".sampling_frequency parameter in your configuration file.\n"
<< " If not set, " << role << ".sampling_frequency=" << configuration->property("GNSS-SDR.internal_fs_sps"s, int64_t(0))
std::cerr << "Warning: parameter " << role_ << ".sampling_frequency is not set, this could lead to wrong results.\n"
<< " Please set the " << role_ << ".sampling_frequency parameter in your configuration file.\n"
<< " If not set, " << role_ << ".sampling_frequency=" << configuration->property("GNSS-SDR.internal_fs_sps"s, int64_t(0))
<< " will be assumed.\n";
sampling_frequency_ = configuration->property("GNSS-SDR.internal_fs_sps"s, int64_t(0));
}
@ -348,39 +385,62 @@ size_t FileSourceBase::computeSamplesInFile() const
{
auto n_samples = static_cast<size_t>(samples());
// if configured with 0 samples (read the whole file), figure out how many samples are in the file, and go from there
if (n_samples == 0)
{
// this could throw, but the existence of the file has been proven before we get here.
auto size = fs::file_size(filename());
const auto size = fs::file_size(filename());
// if there is some kind of compression/encoding, figure out the uncompressed number of samples
n_samples = std::floor(packetsPerSample() * size / item_size());
auto to_skip = samplesToSkip();
const auto to_skip = samplesToSkip();
/*!
* BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File.
* BUG workaround: The GNU Radio 3.7 file source does not stop the receiver after reaching the End of File.
* A possible solution is to compute the file length in samples using file size, excluding at least
* the last 2 milliseconds, and enable always the valve block
*/
auto tail = static_cast<size_t>(std::ceil(0.002 * sampling_frequency()));
const auto tail = static_cast<size_t>(std::ceil(minimum_tail_s_ * sampling_frequency()));
if (tail > size)
{
std::cout << "Warning: file " << filename() << " has " << size << " samples (it is too short).\n";
return 1;
}
if (to_skip + tail > size)
{
std::cout << "Warning: " << role_ << ".seconds_to_skip is larger than file duration.\n";
return 1;
}
// if configured with 0 samples (read the whole file), figure out how many samples are in the file, and go from there
if (n_samples == 0)
{
// if there is some kind of compression/encoding, figure out the uncompressed number of samples
n_samples = std::floor(packetsPerSample() * size / item_size());
DLOG(INFO) << "Total samples in the file= " << n_samples;
std::cout << "Processing file " << filename() << ", which contains " << n_samples << " samples (" << size << " bytes)\n";
if (n_samples > (to_skip + tail))
{
// process all the samples available in the file excluding up to the last 2 ms
// process all the samples available in the file excluding the hearder and the tail
n_samples -= to_skip + tail;
}
else
{
// this will terminate the program
LOG(FATAL) << "Skipping " << to_skip << " samples from the front and truncating 2ms (" << tail << " samples)\n"
<< "is greater than the number of samples in the file (" << n_samples << ")";
std::cout << "Warning: Skipping " << to_skip << " samples from the front and truncating " << tail << " samples\n"
<< "is greater than the number of samples in the file (" << size << ")\n";
return 1;
}
}
else
{
if (n_samples > size - to_skip - tail)
{
std::cout << "Warning: file " << filename() << " has " << size - to_skip
<< " samples, but " << role_ << ".samples has been set to " << n_samples << ".\n"
<< " Setting " << role_ << ".samples to " << size - to_skip - tail
<< " (" << to_skip << " samples skipped at header and " << tail << " samples skipped at the tail).\n";
n_samples = size - to_skip - tail;
}
std::cout << "Processing " << n_samples << " samples from file " << filename() << '\n';
}
return n_samples;
}
@ -421,7 +481,7 @@ gr::blocks::file_source::sptr FileSourceBase::create_file_source()
if (samples_to_skip > 0)
{
LOG(INFO) << "Skipping " << samples_to_skip << " samples of the input file";
if (not file_source_->seek(samples_to_skip, SEEK_SET))
if (!file_source_->seek(samples_to_skip, SEEK_SET))
{
LOG(ERROR) << "Error skipping bytes!";
}
@ -435,7 +495,7 @@ gr::blocks::file_source::sptr FileSourceBase::create_file_source()
<< "[" << filename() << "]\n"
<< "\n"
<< "Please modify your configuration file\n"
<< "and point SignalSource.filename to a valid raw data file. Then:\n"
<< "and point " << role_ << ".filename to a valid raw data file. Then:\n"
<< "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf\n"
<< "Examples of configuration files available at:\n"
<< GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/\n"

View File

@ -152,16 +152,9 @@ protected:
virtual void post_disconnect_hook(gr::top_block_sptr top_block);
private:
std::string filename_;
gr::blocks::file_source::sptr file_source_;
std::string item_type_;
size_t item_size_;
bool is_complex_; // a misnomer; if I/Q are interleaved as integer values
size_t header_size_; // length (in samples) of the header (if any)
double seconds_to_skip_;
bool repeat_;
gr::blocks::throttle::sptr throttle_;
gr::blocks::file_sink::sptr sink_;
// The valve allows only the configured number of samples through, then it closes.
@ -169,17 +162,23 @@ private:
// class has two choices: construct the valve in the ctor, or hold onto the pointer, possibly
// beyond its lifetime. Fortunately, the queue is only used to create the valve, so the
// likelihood of holding a stale pointer is mitigated
uint64_t samples_;
int64_t sampling_frequency_; // why is this signed
gnss_shared_ptr<gr::block> valve_;
Concurrent_Queue<pmt::pmt_t>* queue_;
bool enable_throttle_control_;
gr::blocks::throttle::sptr throttle_;
bool dump_;
std::string role_;
std::string filename_;
std::string dump_filename_;
gr::blocks::file_sink::sptr sink_;
std::string item_type_;
size_t item_size_;
size_t header_size_; // length (in samples) of the header (if any)
uint64_t samples_;
int64_t sampling_frequency_; // why is this signed
double minimum_tail_s_;
double seconds_to_skip_;
bool is_complex_; // a misnomer; if I/Q are interleaved as integer values
bool repeat_;
bool enable_throttle_control_;
bool dump_;
};
/** \} */

View File

@ -28,7 +28,6 @@
#include <algorithm> // for max
#include <exception>
#include <iostream>
#include <utility>
#include <vector>
using namespace std::string_literals;
@ -36,30 +35,44 @@ using namespace std::string_literals;
Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configuration,
const std::string &role, unsigned int in_stream, unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t> *queue)
: SignalSourceBase(configuration, role, "Fmcomms2_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
: SignalSourceBase(configuration, role, "Fmcomms2_Signal_Source"s),
item_type_(configuration->property(role + ".item_type", std::string("gr_complex"))),
dump_filename_(configuration->property(role + ".dump_filename", std::string("./data/signal_source.dat"))),
uri_(configuration->property(role + ".device_address", std::string("192.168.2.1"))),
gain_mode_rx1_(configuration->property(role + ".gain_mode_rx1", default_gain_mode)),
gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)),
rf_port_select_(configuration->property(role + ".rf_port_select", std::string("A_BALANCED"))),
filter_file_(configuration->property(role + ".filter_file", std::string(""))),
filter_filename_(configuration->property(role + ".filter_filename", filter_file_)),
samples_(configuration->property(role + ".samples", static_cast<int64_t>(0))),
item_size_(sizeof(gr_complex)),
rf_gain_rx1_(configuration->property(role + ".gain_rx1", 64.0)),
rf_gain_rx2_(configuration->property(role + ".gain_rx2", 64.0)),
freq_(configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ))),
sample_rate_(configuration->property(role + ".sampling_frequency", static_cast<uint64_t>(2600000))),
bandwidth_(configuration->property(role + ".bandwidth", static_cast<uint64_t>(2000000))),
buffer_size_(configuration->property(role + ".buffer_size", 0xA0000)),
Fpass_(configuration->property(role + ".Fpass", 0.0)),
Fstop_(configuration->property(role + ".Fstop", 0.0)),
in_stream_(in_stream),
out_stream_(out_stream),
RF_channels_(configuration->property(role + ".RF_channels", 1)),
scale_dds_dbfs_(configuration->property(role + ".scale_dds_dbfs", 0.0)),
phase_dds_deg_(configuration->property(role + ".phase_dds_deg", 0.0)),
tx_attenuation_db_(configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db)),
freq_dds_tx_hz_(configuration->property(role + ".freq_dds_tx_hz", static_cast<uint64_t>(10000))),
freq_rf_tx_hz_(configuration->property(role + ".freq_rf_tx_hz", static_cast<uint64_t>(GPS_L1_FREQ_HZ - GPS_L2_FREQ_HZ - freq_dds_tx_hz_))),
tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast<uint64_t>(500000))),
enable_dds_lo_(configuration->property(role + ".enable_dds_lo", false)),
rx1_en_(configuration->property(role + ".rx1_enable", true)),
rx2_en_(configuration->property(role + ".rx2_enable", false)),
quadrature_(configuration->property(role + ".quadrature", true)),
rf_dc_(configuration->property(role + ".rf_dc", true)),
bb_dc_(configuration->property(role + ".bb_dc", true)),
filter_auto_(configuration->property(role + ".filter_auto", false)),
rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)),
dump_(configuration->property(role + ".dump", false))
{
const std::string default_item_type("gr_complex");
const std::string default_dump_file("./data/signal_source.dat");
const std::string default_gain_mode("slow_attack");
const double default_tx_attenuation_db = -10.0;
uri_ = configuration->property(role + ".device_address", std::string("192.168.2.1"));
freq_ = configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ));
sample_rate_ = configuration->property(role + ".sampling_frequency", static_cast<uint64_t>(2600000));
bandwidth_ = configuration->property(role + ".bandwidth", static_cast<uint64_t>(2000000));
rx1_en_ = configuration->property(role + ".rx1_enable", true);
rx2_en_ = configuration->property(role + ".rx2_enable", false);
buffer_size_ = configuration->property(role + ".buffer_size", 0xA0000);
quadrature_ = configuration->property(role + ".quadrature", true);
rf_dc_ = configuration->property(role + ".rf_dc", true);
bb_dc_ = configuration->property(role + ".bb_dc", true);
RF_channels_ = configuration->property(role + ".RF_channels", 1);
gain_mode_rx1_ = configuration->property(role + ".gain_mode_rx1", default_gain_mode);
gain_mode_rx2_ = configuration->property(role + ".gain_mode_rx2", default_gain_mode);
rf_gain_rx1_ = configuration->property(role + ".gain_rx1", 64.0);
rf_gain_rx2_ = configuration->property(role + ".gain_rx2", 64.0);
rf_port_select_ = configuration->property(role + ".rf_port_select", std::string("A_BALANCED"));
filter_file_ = configuration->property(role + ".filter_file", std::string(""));
filter_auto_ = configuration->property(role + ".filter_auto", false);
if (filter_auto_)
{
filter_source_ = configuration->property(role + ".filter_source", std::string("Auto"));
@ -68,27 +81,6 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configu
{
filter_source_ = configuration->property(role + ".filter_source", std::string("Off"));
}
filter_filename_ = configuration->property(role + ".filter_filename", filter_file_);
Fpass_ = configuration->property(role + ".Fpass", 0.0);
Fstop_ = configuration->property(role + ".Fstop", 0.0);
item_type_ = configuration->property(role + ".item_type", default_item_type);
samples_ = configuration->property(role + ".samples", static_cast<int64_t>(0));
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file);
// AD9361 Local Oscillator generation for dual band operation
enable_dds_lo_ = configuration->property(role + ".enable_dds_lo", false);
freq_dds_tx_hz_ = configuration->property(role + ".freq_dds_tx_hz", static_cast<uint64_t>(10000));
freq_rf_tx_hz_ = configuration->property(role + ".freq_rf_tx_hz", static_cast<uint64_t>(GPS_L1_FREQ_HZ - GPS_L2_FREQ_HZ - freq_dds_tx_hz_));
scale_dds_dbfs_ = configuration->property(role + ".scale_dds_dbfs", 0.0);
phase_dds_deg_ = configuration->property(role + ".phase_dds_deg", 0.0);
tx_attenuation_db_ = configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db);
tx_bandwidth_ = configuration->property(role + ".tx_bandwidth", static_cast<uint64_t>(500000));
rf_shutdown_ = configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown);
item_size_ = sizeof(gr_complex);
// some basic checks
if ((rf_port_select_ != "A_BALANCED") && (rf_port_select_ != "B_BALANCED") && (rf_port_select_ != "A_N") && (rf_port_select_ != "B_N") && (rf_port_select_ != "B_P") && (rf_port_select_ != "C_N") && (rf_port_select_ != "C_P") && (rf_port_select_ != "TX_MONITOR1") && (rf_port_select_ != "TX_MONITOR2") && (rf_port_select_ != "TX_MONITOR1_2"))
@ -181,6 +173,10 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configu
{
LOG(FATAL) << "Configuration error: both rx1 and rx2 are enabled but RF_channels=1 !";
}
else if (!rx1_en_ && !rx2_en_)
{
LOG(FATAL) << "Configuration error: both rx1 and rx2 are disabled.";
}
else
{
#if GNURADIO_API_IIO

View File

@ -61,6 +61,9 @@ public:
gr::basic_block_sptr get_right_block() override;
private:
const std::string default_gain_mode = std::string("slow_attack");
const double default_tx_attenuation_db = -10.0;
#if GNURADIO_API_IIO
#if GR_IIO_TEMPLATIZED_API
gr::iio::fmcomms2_source<gr_complex>::sptr fmcomms2_source_f32c_;
@ -88,9 +91,6 @@ private:
int64_t samples_;
size_t item_size_;
unsigned int in_stream_;
unsigned int out_stream_;
double rf_gain_rx1_;
double rf_gain_rx2_;
uint64_t freq_; // frequency of local oscilator
@ -99,14 +99,16 @@ private:
uint64_t buffer_size_; // reception buffer
float Fpass_;
float Fstop_;
unsigned int in_stream_;
unsigned int out_stream_;
int RF_channels_;
// DDS configuration for LO generation for external mixer
double scale_dds_dbfs_;
double phase_dds_deg_;
double tx_attenuation_db_;
uint64_t freq_rf_tx_hz_;
uint64_t freq_dds_tx_hz_;
uint64_t freq_rf_tx_hz_;
uint64_t tx_bandwidth_;
bool enable_dds_lo_;

View File

@ -16,12 +16,12 @@
#include "limesdr_signal_source.h"
#include "configuration_interface.h"
#include "gnss_frequencies.h"
#include "gnss_sdr_string_literals.h"
#include "gnss_sdr_valve.h"
#include <glog/logging.h>
#include <gnuradio/blocks/file_sink.h>
#include <iostream>
#include <utility>
using namespace std::string_literals;
@ -31,33 +31,25 @@ LimesdrSignalSource::LimesdrSignalSource(const ConfigurationInterface* configura
unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t>* queue)
: SignalSourceBase(configuration, role, "Limesdr_Signal_Source"s),
item_type_(configuration->property(role + ".item_type", std::string("gr_complex"))),
dump_filename_(configuration->property(role + ".dump_filename", std::string("./data/signal_source.dat"))),
limesdr_serial_(configuration->property(role + ".limesdr_serial", std::string())),
limesdr_file_(configuration->property(role + ".limesdr_file", std::string())),
sample_rate_(configuration->property(role + ".sampling_frequency", 2.0e6)),
freq_(configuration->property(role + ".freq", FREQ1)),
gain_(configuration->property(role + ".gain", 40.0)),
analog_bw_hz_(configuration->property(role + ".analog_bw", sample_rate_ / 2.0)), // LPF analog filters in I,Q branches
digital_bw_hz_(configuration->property(role + ".digital_bw", 0.0)), // disable by default
ext_clock_MHz_(configuration->property(role + ".ext_clock_MHz", 0.0)), // external clock: 0.0 MHz will enable the internal clock
samples_(configuration->property(role + ".samples", int64_t(0))),
in_stream_(in_stream),
out_stream_(out_stream)
out_stream_(out_stream),
limechannel_mode_(configuration->property(role + ".limechannel_mode", 0)),
antenna_(configuration->property(role + ".antenna", 255)),
channel_(configuration->property(role + ".channel", 0)),
PPS_mode_(configuration->property(role + ".PPS_mode", false)),
dump_(configuration->property(role + ".dump", false))
{
// DUMP PARAMETERS
const std::string empty;
const std::string default_dump_file("./data/signal_source.dat");
const std::string default_item_type("gr_complex");
samples_ = configuration->property(role + ".samples", static_cast<int64_t>(0));
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file);
// Driver parameters
channel_ = configuration->property(role + ".channel", 0);
freq_ = configuration->property(role + ".freq", 1575420000);
gain_ = configuration->property(role + ".gain", 40.0);
sample_rate_ = configuration->property(role + ".sampling_frequency", 2.0e6);
// todo: check if bw is within limits
analog_bw_hz_ = configuration->property(role + ".analog_bw", sample_rate_ / 2); // LPF analog filters in I,Q branches
digital_bw_hz_ = configuration->property(role + ".digital_bw", 0); // disable by default
item_type_ = configuration->property(role + ".item_type", default_item_type);
limesdr_serial_ = configuration->property(role + ".limesdr_serial", std::string());
limesdr_file_ = configuration->property(role + ".limesdr_file", std::string());
antenna_ = configuration->property(role + ".antenna", 255);
PPS_mode_ = configuration->property(role + ".PPS_mode", false);
ext_clock_MHz_ = configuration->property(role + ".ext_clock_MHz", 0.0); // external clock: 0.0 MHz will enable the internal clock
limechannel_mode_ = configuration->property(role + ".limechannel_mode", 0);
if ((limechannel_mode_ < 0) || (limechannel_mode_ > 2))
{
std::cerr << "ERROR: source_impl::source_impl(): ChannelMode must be A(0), B(1) or (A+B) MIMO(2)\n";

View File

@ -63,13 +63,10 @@ private:
gnss_shared_ptr<gr::block> valve_;
gr::blocks::file_sink::sptr file_sink_;
std::string role_;
std::string item_type_;
std::string dump_filename_;
std::string limesdr_serial_;
std::string limesdr_file_;
int antenna_;
int channel_;
// Front-end settings
double sample_rate_;
@ -85,6 +82,8 @@ private:
unsigned int out_stream_;
int limechannel_mode_;
int antenna_;
int channel_;
bool PPS_mode_;
bool dump_;

View File

@ -23,7 +23,6 @@
#include <glog/logging.h>
#include <gnuradio/blocks/file_sink.h>
#include <iostream>
#include <utility>
using namespace std::string_literals;
@ -32,28 +31,22 @@ using namespace std::string_literals;
OsmosdrSignalSource::OsmosdrSignalSource(const ConfigurationInterface* configuration,
const std::string& role, unsigned int in_stream, unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t>* queue)
: SignalSourceBase(configuration, role, "Osmosdr_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
: SignalSourceBase(configuration, role, "Osmosdr_Signal_Source"s),
item_type_(configuration->property(role + ".item_type", std::string("gr_complex"))),
dump_filename_(configuration->property(role + ".dump_filename", std::string("./data/signal_source.dat"))),
osmosdr_args_(configuration->property(role + ".osmosdr_args", std::string())),
antenna_(configuration->property(role + ".antenna", std::string())),
sample_rate_(configuration->property(role + ".sampling_frequency", 2.0e6)),
freq_(configuration->property(role + ".freq", GPS_L1_FREQ_HZ)),
gain_(configuration->property(role + ".gain", 40.0)),
if_gain_(configuration->property(role + ".if_gain", 40.0)),
rf_gain_(configuration->property(role + ".rf_gain", 40.0)),
samples_(configuration->property(role + ".samples", static_cast<int64_t>(0))),
in_stream_(in_stream),
out_stream_(out_stream),
AGC_enabled_(configuration->property(role + ".AGC_enabled", true)),
dump_(configuration->property(role + ".dump", false))
{
// DUMP PARAMETERS
const std::string empty;
const std::string default_dump_file("./data/signal_source.dat");
const std::string default_item_type("gr_complex");
samples_ = configuration->property(role + ".samples", static_cast<int64_t>(0));
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename",
default_dump_file);
// OSMOSDR Driver parameters
AGC_enabled_ = configuration->property(role + ".AGC_enabled", true);
freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ);
gain_ = configuration->property(role + ".gain", 40.0);
rf_gain_ = configuration->property(role + ".rf_gain", 40.0);
if_gain_ = configuration->property(role + ".if_gain", 40.0);
sample_rate_ = configuration->property(role + ".sampling_frequency", 2.0e6);
item_type_ = configuration->property(role + ".item_type", default_item_type);
osmosdr_args_ = configuration->property(role + ".osmosdr_args", std::string());
antenna_ = configuration->property(role + ".antenna", empty);
if (item_type_ == "short")
{
item_size_ = sizeof(int16_t);

View File

@ -22,7 +22,6 @@
#include "gnss_sdr_valve.h"
#include <glog/logging.h>
#include <iostream>
#include <utility>
using namespace std::string_literals;
@ -31,23 +30,30 @@ using namespace std::string_literals;
PlutosdrSignalSource::PlutosdrSignalSource(const ConfigurationInterface* configuration,
const std::string& role, unsigned int in_stream, unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t>* queue)
: SignalSourceBase(configuration, role, "Plutosdr_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
: SignalSourceBase(configuration, role, "Plutosdr_Signal_Source"s),
dump_filename_(configuration->property(role + ".dump_filename", std::string("./data/signal_source.dat"))),
uri_(configuration->property(role + ".device_address", std::string("192.168.2.1"))),
gain_mode_(configuration->property(role + ".gain_mode", default_gain_mode)),
filter_file_(configuration->property(role + ".filter_file", std::string(""))),
filter_filename_(configuration->property(role + ".filter_filename", filter_file_)),
item_type_(configuration->property(role + ".item_type", std::string("gr_complex"))),
rf_gain_(configuration->property(role + ".gain", 50.0)),
samples_(configuration->property(role + ".samples", static_cast<int64_t>(0))),
freq_(configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ))),
sample_rate_(configuration->property(role + ".sampling_frequency", static_cast<uint64_t>(3000000))),
bandwidth_(configuration->property(role + ".bandwidth", static_cast<uint64_t>(2000000))),
buffer_size_(configuration->property(role + ".buffer_size", 0xA0000)),
item_size_(sizeof(gr_complex)),
Fpass_(configuration->property(role + ".Fpass", 0.0)),
Fstop_(configuration->property(role + ".Fstop", 0.0)),
in_stream_(in_stream),
out_stream_(out_stream),
quadrature_(configuration->property(role + ".quadrature", true)),
rf_dc_(configuration->property(role + ".rf_dc", true)),
bb_dc_(configuration->property(role + ".bb_dc", true)),
filter_auto_(configuration->property(role + ".filter_auto", false)),
dump_(configuration->property(role + ".dump", false))
{
const std::string default_item_type("gr_complex");
const std::string default_dump_file("./data/signal_source.dat");
const std::string default_gain_mode("slow_attack");
uri_ = configuration->property(role + ".device_address", std::string("192.168.2.1"));
freq_ = configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ));
sample_rate_ = configuration->property(role + ".sampling_frequency", static_cast<uint64_t>(3000000));
bandwidth_ = configuration->property(role + ".bandwidth", static_cast<uint64_t>(2000000));
buffer_size_ = configuration->property(role + ".buffer_size", 0xA0000);
quadrature_ = configuration->property(role + ".quadrature", true);
rf_dc_ = configuration->property(role + ".rf_dc", true);
bb_dc_ = configuration->property(role + ".bb_dc", true);
gain_mode_ = configuration->property(role + ".gain_mode", default_gain_mode);
rf_gain_ = configuration->property(role + ".gain", 50.0);
filter_file_ = configuration->property(role + ".filter_file", std::string(""));
filter_auto_ = configuration->property(role + ".filter_auto", false);
if (filter_auto_)
{
filter_source_ = configuration->property(role + ".filter_source", std::string("Auto"));
@ -56,13 +62,6 @@ PlutosdrSignalSource::PlutosdrSignalSource(const ConfigurationInterface* configu
{
filter_source_ = configuration->property(role + ".filter_source", std::string("Off"));
}
filter_filename_ = configuration->property(role + ".filter_filename", filter_file_);
Fpass_ = configuration->property(role + ".Fpass", 0.0);
Fstop_ = configuration->property(role + ".Fstop", 0.0);
item_type_ = configuration->property(role + ".item_type", default_item_type);
samples_ = configuration->property(role + ".samples", static_cast<int64_t>(0));
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file);
if (item_type_ != "gr_complex")
{
@ -117,8 +116,6 @@ PlutosdrSignalSource::PlutosdrSignalSource(const ConfigurationInterface* configu
LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=2000000";
}
item_size_ = sizeof(gr_complex);
std::cout << "device address: " << uri_ << '\n';
std::cout << "frequency : " << freq_ << " Hz\n";
std::cout << "sample rate: " << sample_rate_ << " Sps\n";

View File

@ -66,6 +66,7 @@ public:
gr::basic_block_sptr get_right_block() override;
private:
const std::string default_gain_mode = std::string("slow_attack");
#if GR_IIO_TEMPLATIZED_API
gr::iio::fmcomms2_source<gr_complex>::sptr plutosdr_source_;
#else

View File

@ -64,9 +64,14 @@ int FifoReader::work(int noutput_items,
// ishort == int16_t
items_retrieved = read_interleaved<int16_t>(noutput_items, output_items);
}
else if (sample_type_ == "ibyte") // Does this also work with cbyte?
{
// ibyte == int8_t
items_retrieved = read_interleaved<int8_t>(noutput_items, output_items);
}
else if (sample_type_ == "gr_complex")
{
LOG(WARNING) << sample_type_ << " is not yet tested. Please consider removing this warning if tested successfully";
// gr_complex == complex<float>
items_retrieved = read_gr_complex(noutput_items, output_items);
}
else
@ -80,6 +85,7 @@ int FifoReader::work(int noutput_items,
return this->WORK_CALLED_PRODUCE;
}
// read gr_complex items from fifo
// this fct has duplicate code with the templated read_interleaved fct in header
size_t FifoReader::read_gr_complex(int noutput_items, gr_vector_void_star &output_items)

View File

@ -51,8 +51,11 @@ private:
FifoReader(const std::string &file_name, const std::string &sample_type);
size_t read_gr_complex(int noutput_items, gr_vector_void_star &output_items);
//! function to read data out of FIFO which is stored as interleaved I/Q stream.
//! template argument determines sample_type
// Note: template definition necessary in header file
// See also: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file
template <typename Type>
size_t read_interleaved(int noutput_items, gr_vector_void_star &output_items)
{
@ -61,15 +64,13 @@ private:
{
// TODO: try if performance increases if we copy larger chunks to vector.
// how to read from stream: https://en.cppreference.com/w/cpp/io/basic_ifstream
std::array<char, 4> buffer; // gr_complex is 32bit = 4*char
fifo_.read(reinterpret_cast<char *>(&buffer[0]), buffer.size());
std::array<char, 2 * sizeof(Type)> buffer;
fifo_.read(reinterpret_cast<char *>(buffer.data()), buffer.size());
if (fifo_.good())
{
Type real;
Type imag;
memcpy(&real, &buffer[0], sizeof(real));
memcpy(&imag, &buffer[2], sizeof(imag));
static_cast<gr_complex *>(output_items.at(0))[n] = gr_complex(real, imag);
auto real = reinterpret_cast<Type const *>(&buffer[0]);
auto imag = reinterpret_cast<Type const *>(&buffer[sizeof(Type)]);
static_cast<gr_complex *>(output_items[0])[n] = gr_complex(*real, *imag);
items_retrieved++;
}
else if (fifo_.eof())

View File

@ -33,11 +33,11 @@ boost::system::error_code Rtl_Tcp_Dongle_Info::read(boost::asio::ip::tcp::socket
{
boost::system::error_code ec;
unsigned char data[sizeof(char) * 4 + sizeof(uint32_t) * 2];
std::vector<unsigned char> data(sizeof(char) * 4 + sizeof(uint32_t) * 2);
size_t received_bits = socket.receive(boost::asio::buffer(data), 0, ec);
if (!ec && (received_bits > 0))
{
std::memcpy(magic_, data, 4);
std::memcpy(magic_, data.data(), 4);
uint32_t type;
std::memcpy(&type, &data[4], 4);

View File

@ -662,30 +662,8 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
d_band = current_symbol.Signal[0];
// add new symbol to the symbol queue
switch (d_frame_type)
{
case 1: // INAV
{
d_symbol_history.push_back(current_symbol.Prompt_I);
break;
}
case 2: // FNAV
{
d_symbol_history.push_back(current_symbol.Prompt_Q);
break;
}
case 3: // CNAV
{
d_symbol_history.push_back(current_symbol.Prompt_I);
break;
}
default:
{
LOG(WARNING) << "Frame type " << d_frame_type << " is not defined";
d_symbol_history.push_back(current_symbol.Prompt_I);
break;
}
}
d_sample_counter++; // count for the processed symbols
// Time Tags from signal source (optional feature)
@ -1025,6 +1003,7 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
{
d_TOW_at_current_symbol_ms += static_cast<uint32_t>(GALILEO_FNAV_CODES_PER_SYMBOL * GALILEO_E5A_CODE_PERIOD_MS);
}
}
if (d_enable_navdata_monitor && !d_nav_msg_packet.nav_message.empty())
{
d_nav_msg_packet.system = std::string(1, current_symbol.System);
@ -1037,7 +1016,6 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
}
break;
}
}
case 3: // CNAV
{
// TODO

View File

@ -305,6 +305,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_)
// remove data secondary code
d_data_secondary_code_length = static_cast<uint32_t>(GALILEO_E5A_I_SECONDARY_CODE_LENGTH);
d_data_secondary_code_string = GALILEO_E5A_I_SECONDARY_CODE;
d_interchange_iq = true;
}
else
{
@ -312,7 +313,6 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_)
d_secondary_code_length = static_cast<uint32_t>(GALILEO_E5A_I_SECONDARY_CODE_LENGTH);
d_secondary_code_string = GALILEO_E5A_I_SECONDARY_CODE;
d_signal_pretty_name = d_signal_pretty_name + "I";
d_interchange_iq = true;
}
}
else if (d_signal_type == "7X")
@ -336,6 +336,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_)
// remove data secondary code
d_data_secondary_code_length = static_cast<uint32_t>(GALILEO_E5B_I_SECONDARY_CODE_LENGTH);
d_data_secondary_code_string = GALILEO_E5B_I_SECONDARY_CODE;
d_interchange_iq = true;
}
else
{
@ -343,7 +344,6 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_)
d_secondary_code_length = static_cast<uint32_t>(GALILEO_E5B_I_SECONDARY_CODE_LENGTH);
d_secondary_code_string = GALILEO_E5B_I_SECONDARY_CODE;
d_signal_pretty_name = d_signal_pretty_name + "I";
d_interchange_iq = true;
}
}
else if (d_signal_type == "E6")

View File

@ -303,7 +303,7 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga &
// remove data secondary code
d_data_secondary_code_length = static_cast<uint32_t>(GALILEO_E5A_I_SECONDARY_CODE_LENGTH);
d_data_secondary_code_string = GALILEO_E5A_I_SECONDARY_CODE;
d_interchange_iq = true;
// the pilot secondary code depends on PRN and it is initialized later
}
else
@ -312,7 +312,6 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga &
d_secondary_code_length = static_cast<uint32_t>(GALILEO_E5A_I_SECONDARY_CODE_LENGTH);
d_secondary_code_string = GALILEO_E5A_I_SECONDARY_CODE;
d_signal_pretty_name = d_signal_pretty_name + "I";
d_interchange_iq = true;
}
}
else

View File

@ -178,8 +178,7 @@ void Galileo_E1_Tcp_Connector_Tracking_cc::start_tracking()
d_carrier_doppler_hz = d_acq_carrier_doppler_hz;
d_current_prn_length_samples = d_vector_length;
std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
sys = std::string(1, d_acquisition_gnss_synchro->System);
// DEBUG OUTPUT
std::cout << "Tracking of Galileo E1 signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n';

View File

@ -263,8 +263,7 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking()
d_pll_to_dll_assist_secs_Ti = 0.0;
d_code_phase_samples = d_acq_code_phase_samples;
const std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
sys = std::string(1, d_acquisition_gnss_synchro->System);
d_acc_carrier_phase_initialized = false;
// DEBUG OUTPUT

View File

@ -263,8 +263,7 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_sc::start_tracking()
d_pll_to_dll_assist_secs_Ti = 0.0;
d_code_phase_samples = d_acq_code_phase_samples;
const std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
sys = std::string(1, d_acquisition_gnss_synchro->System);
d_acc_carrier_phase_initialized = false;
// DEBUG OUTPUT

View File

@ -205,8 +205,7 @@ void Glonass_L1_Ca_Dll_Pll_Tracking_cc::start_tracking()
d_code_phase_samples = d_acq_code_phase_samples;
const std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
sys = std::string(1, d_acquisition_gnss_synchro->System);
d_acc_carrier_phase_initialized = false;
// DEBUG OUTPUT

View File

@ -259,8 +259,7 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_cc::start_tracking()
d_pll_to_dll_assist_secs_Ti = 0.0;
d_code_phase_samples = d_acq_code_phase_samples;
const std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
sys = std::string(1, d_acquisition_gnss_synchro->System);
// DEBUG OUTPUT
std::cout << "Tracking of GLONASS L2 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n';

View File

@ -260,8 +260,7 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_sc::start_tracking()
d_pll_to_dll_assist_secs_Ti = 0.0;
d_code_phase_samples = d_acq_code_phase_samples;
const std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
sys = std::string(1, d_acquisition_gnss_synchro->System);
// DEBUG OUTPUT
std::cout << "Tracking of GLONASS L2 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n';

View File

@ -206,8 +206,7 @@ void Glonass_L2_Ca_Dll_Pll_Tracking_cc::start_tracking()
d_code_phase_samples = d_acq_code_phase_samples;
const std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
sys = std::string(1, d_acquisition_gnss_synchro->System);
// DEBUG OUTPUT
std::cout << "Tracking of GLONASS L2 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n';

View File

@ -218,8 +218,7 @@ void Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::start_tracking()
d_pll_to_dll_assist_secs_Ti = 0.0;
d_code_phase_samples = d_acq_code_phase_samples;
const std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
sys = std::string(1, d_acquisition_gnss_synchro->System);
// DEBUG OUTPUT
std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n';

View File

@ -302,9 +302,8 @@ void Gps_L1_Ca_Kf_Tracking_cc::start_tracking()
d_code_phase_samples = d_acq_code_phase_samples;
std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
sys = std::string(1, d_acquisition_gnss_synchro->System);
std::cout << "++++++++++++++ " << sys << "++++++++++++\n";
// DEBUG OUTPUT
std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n';
LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel;

View File

@ -203,8 +203,7 @@ void Gps_L1_Ca_Tcp_Connector_Tracking_cc::start_tracking()
d_code_phase_samples = d_acq_code_phase_samples;
std::string sys_ = &d_acquisition_gnss_synchro->System;
sys = sys_.substr(0, 1);
sys = std::string(1, d_acquisition_gnss_synchro->System);
// DEBUG OUTPUT
std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n';

View File

@ -89,6 +89,7 @@ target_link_libraries(tracking_libs
PRIVATE
gnss_sdr_flags
Glog::glog
Gnuradio::runtime
)
if(ENABLE_CUDA)

View File

@ -20,6 +20,7 @@
#include "tracking_discriminators.h"
#include "MATH_CONSTANTS.h"
#include <gnuradio/math.h>
// All the outputs are in RADIANS
@ -53,7 +54,7 @@ double fll_four_quadrant_atan(gr_complex prompt_s1, gr_complex prompt_s2, double
{
const float dot = prompt_s1.real() * prompt_s2.real() + prompt_s1.imag() * prompt_s2.imag();
const float cross = prompt_s1.real() * prompt_s2.imag() - prompt_s2.real() * prompt_s1.imag();
return std::atan2(cross, dot) / (t2 - t1);
return static_cast<double>(gr::fast_atan2f(cross, dot) / (t2 - t1));
}
@ -84,7 +85,7 @@ double fll_diff_atan(gr_complex prompt_s1, gr_complex prompt_s2, double t1, doub
*/
double pll_four_quadrant_atan(gr_complex prompt_s1)
{
return static_cast<double>(std::atan2(prompt_s1.imag(), prompt_s1.real()));
return static_cast<double>(gr::fast_atan2f(prompt_s1.imag(), prompt_s1.real()));
}

View File

@ -18,7 +18,7 @@
*/
#ifndef GNSS_SDR_VERSION
#define GNSS_SDR_VERSION "0.0.15"
#define GNSS_SDR_VERSION "0.0.16"
#endif
#ifndef GOOGLE_STRIP_LOG

View File

@ -102,6 +102,7 @@ add_benchmark(benchmark_copy)
add_benchmark(benchmark_preamble core_system_parameters)
add_benchmark(benchmark_detector core_system_parameters)
add_benchmark(benchmark_reed_solomon core_system_parameters)
add_benchmark(benchmark_atan2 Gnuradio::runtime)
if(has_std_plus_void)
target_compile_definitions(benchmark_detector PRIVATE -DCOMPILER_HAS_STD_PLUS_VOID=1)

View File

@ -0,0 +1,65 @@
/*!
* \file benchmark_atan2.cc
* \brief Benchmark for atan2 implementations
* \author Carles Fernandez-Prades, 2022. cfernandez(at)cttc.es
*
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2022 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#include <benchmark/benchmark.h>
#include <gnuradio/math.h>
#include <cmath>
#include <random>
void bm_std_atan2(benchmark::State& state)
{
std::random_device rd;
std::default_random_engine e2(rd());
std::uniform_real_distribution<> dist(-1.0, 1.0);
float a = dist(e2);
float b = dist(e2);
float c;
while (state.KeepRunning())
{
c = std::atan2(a, b);
}
if (c > 1.0)
{
// Avoid unused-but-set-variable warning
}
}
void bm_gr_fast_atan2f(benchmark::State& state)
{
std::random_device rd;
std::default_random_engine e2(rd());
std::uniform_real_distribution<> dist(-1.0, 1.0);
float a = dist(e2);
float b = dist(e2);
float c;
while (state.KeepRunning())
{
c = gr::fast_atan2f(a, b);
}
if (c > 1.0)
{
// Avoid unused-but-set-variable warning
}
}
BENCHMARK(bm_std_atan2);
BENCHMARK(bm_gr_fast_atan2f);
BENCHMARK_MAIN();

View File

@ -266,7 +266,7 @@ protected:
pfa_vector.push_back(FLAGS_acq_test_pfa_init * std::pow(10, aux));
aux = aux + 1.0;
}
pfa_vector.push_back(1.0);
pfa_vector.push_back(0.999);
}
else
{
@ -282,8 +282,17 @@ protected:
num_thresholds = pfa_vector.size();
int aux2 = ((generated_signal_duration_s * 900 - (FLAGS_acq_test_coherent_time_ms * FLAGS_acq_test_max_dwells)) / (FLAGS_acq_test_coherent_time_ms * FLAGS_acq_test_max_dwells));
if ((FLAGS_acq_test_num_meas > 0) and (FLAGS_acq_test_num_meas < aux2))
// the gnss simulator does not dump the trk observables for the last 100 ms of generated signal
int aux2;
if (FLAGS_acq_test_bit_transition_flag)
{
aux2 = floor((generated_signal_duration_s * ms_per_s - 100) / (FLAGS_acq_test_coherent_time_ms * 2.0) - 1);
}
else
{
aux2 = floor((generated_signal_duration_s * ms_per_s - 100) / (FLAGS_acq_test_coherent_time_ms * FLAGS_acq_test_max_dwells) - 1);
}
if ((FLAGS_acq_test_num_meas > 0) && (FLAGS_acq_test_num_meas < aux2))
{
num_of_measurements = static_cast<unsigned int>(FLAGS_acq_test_num_meas);
}
@ -369,6 +378,8 @@ protected:
std::string signal_id;
private:
static const uint32_t ms_per_s = 1000;
std::string generator_binary;
std::string p1;
std::string p2;
@ -936,7 +947,7 @@ TEST_F(AcquisitionPerformanceTest, ROC)
// Cut measurements without reference
for (int i = 0; i < num_executions; i++)
{
if (!std::isnan(doppler_estimation_error(i)) and !std::isnan(delay_estimation_error(i)))
if (!std::isnan(doppler_estimation_error(i)) && !std::isnan(delay_estimation_error(i)))
{
num_clean_executions++;
}
@ -946,7 +957,7 @@ TEST_F(AcquisitionPerformanceTest, ROC)
num_clean_executions = 0;
for (int i = 0; i < num_executions; i++)
{
if (!std::isnan(doppler_estimation_error(i)) and !std::isnan(delay_estimation_error(i)))
if (!std::isnan(doppler_estimation_error(i)) && !std::isnan(delay_estimation_error(i)))
{
clean_doppler_estimation_error(num_clean_executions) = doppler_estimation_error(i);
clean_delay_estimation_error(num_clean_executions) = delay_estimation_error(i);
@ -988,10 +999,9 @@ TEST_F(AcquisitionPerformanceTest, ROC)
{
arma::vec correct_acq = arma::zeros(num_executions, 1);
double correctly_detected = 0.0;
for (int i = 0; i < num_clean_executions - 1; i++)
for (int i = 0; i < num_clean_executions; i++)
{
if (abs(clean_delay_estimation_error(i)) < 0.5 and abs(clean_doppler_estimation_error(i)) < static_cast<float>(config->property("Acquisition.doppler_step", 1)) / 2.0)
if (abs(clean_delay_estimation_error(i)) < 0.5 && abs(clean_doppler_estimation_error(i)) < static_cast<float>(config->property("Acquisition.doppler_step", 1)))
{
correctly_detected = correctly_detected + 1.0;
}
@ -1027,7 +1037,7 @@ TEST_F(AcquisitionPerformanceTest, ROC)
float sum_pd = static_cast<float>(std::accumulate(meas_Pd_.begin(), meas_Pd_.end(), 0.0));
float sum_pd_correct = static_cast<float>(std::accumulate(meas_Pd_correct_.begin(), meas_Pd_correct_.end(), 0.0));
float sum_pfa = static_cast<float>(std::accumulate(meas_Pfa_.begin(), meas_Pfa_.end(), 0.0));
if (!meas_Pd_.empty() and !meas_Pfa_.empty())
if (!meas_Pd_.empty() && !meas_Pfa_.empty())
{
Pd[cn0_index][pfa_iter] = sum_pd / static_cast<float>(meas_Pd_.size());
Pfa[cn0_index][pfa_iter] = sum_pfa / static_cast<float>(meas_Pfa_.size());