mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-11-15 22:34:58 +00:00
Merge with next
This commit is contained in:
commit
bf1a7e8c2c
79
.github/workflows/gnss-sdr_archs.yml
vendored
Normal file
79
.github/workflows/gnss-sdr_archs.yml
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
# SPDX-FileCopyrightText: 2023 Carles Fernandez-Prades <carles.fernandez@cttc.es>
|
||||
|
||||
name: Run gnss-sdr in non-x86 archs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "**-archs"
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
gnss-sdr-non-x86:
|
||||
runs-on: ubuntu-latest
|
||||
name: ${{ matrix.distro }} ${{ matrix.arch }} ${{ matrix.compiler.name }}
|
||||
|
||||
# Run steps on a matrix of archs.
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: aarch64
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 }
|
||||
- arch: aarch64
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: clang-14, cc: clang-14, cxx: clang++-14 }
|
||||
- arch: armv7
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 }
|
||||
- arch: ppc64le
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 }
|
||||
- arch: s390x
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 }
|
||||
- arch: riscv64
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.1.0
|
||||
- uses: uraimo/run-on-arch-action@v2.5.0
|
||||
name: Test in non-x86 container
|
||||
continue-on-error: ${{ contains(fromJson('["ppc64le", "s390x"]'), matrix.arch) }}
|
||||
id: test
|
||||
with:
|
||||
arch: ${{ matrix.arch }}
|
||||
distro: ${{ matrix.distro }}
|
||||
githubToken: ${{ github.token }} # Not required, but speeds up builds
|
||||
setup: |
|
||||
mkdir -p "${PWD}/testing"
|
||||
dockerRunArgs: |
|
||||
--volume "${PWD}:/gnss-sdr"
|
||||
env: |
|
||||
CC: ${{ matrix.compiler.cc }}
|
||||
CXX: ${{ matrix.compiler.cxx }}
|
||||
shell: /bin/sh
|
||||
install: |
|
||||
apt-get update -q -y
|
||||
apt-get install -q -y ${{ matrix.compiler.name }} git ninja-build cmake \
|
||||
libboost-dev libboost-date-time-dev libboost-system-dev libboost-filesystem-dev \
|
||||
libboost-thread-dev libboost-chrono-dev libboost-serialization-dev \
|
||||
liblog4cpp5-dev gnuradio-dev gr-osmosdr libpugixml-dev libpcap-dev libblas-dev \
|
||||
liblapack-dev libarmadillo-dev libgflags-dev libgoogle-glog-dev \
|
||||
libgnutls-openssl-dev libmatio-dev googletest protobuf-compiler libprotobuf-dev \
|
||||
python3-mako liborc-0.4-dev
|
||||
run: |
|
||||
git config --global --add safe.directory /gnss-sdr
|
||||
cd /gnss-sdr
|
||||
cd testing
|
||||
mkdir install
|
||||
cmake -DENABLE_SYSTEM_TESTING_EXTRA=ON -DCMAKE_INSTALL_PREFIX=/gnss-sdr/testing/install -DENABLE_INSTALL_TESTS=ON ..
|
||||
echo "Build with $(nproc) thread(s)"
|
||||
make -j$(nproc)
|
||||
make install
|
||||
cd install/bin
|
||||
./position_test
|
3
.github/workflows/main.yml
vendored
3
.github/workflows/main.yml
vendored
@ -9,6 +9,7 @@ on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- "**/CITATION.cff"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-ubuntu:
|
||||
@ -113,7 +114,7 @@ jobs:
|
||||
ln -s $(brew --prefix llvm)/bin/clang-apply-replacements /usr/local/bin
|
||||
ln -s $(brew --prefix llvm)/bin/run-clang-tidy /usr/local/bin
|
||||
- name: Prepare run
|
||||
run: cd build && cmake .. && make volk_gnsssdr_module gtest-1.12.1 core_monitor core_libs pvt_libs
|
||||
run: cd build && cmake .. && make volk_gnsssdr_module gtest-1.13.0 core_monitor core_libs pvt_libs
|
||||
- name: run clang-tidy
|
||||
run: cd build && run-clang-tidy -fix
|
||||
- name: check
|
||||
|
@ -4,12 +4,14 @@ on:
|
||||
push:
|
||||
paths:
|
||||
- "src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/**"
|
||||
- "CMakeLists.txt"
|
||||
pull_request:
|
||||
paths:
|
||||
- "src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/**"
|
||||
- "CMakeLists.txt"
|
||||
workflow_dispatch:
|
||||
|
||||
name: Build volk-gnssdr on Android NDK
|
||||
name: Build volk_gnsssdr on Android NDK
|
||||
jobs:
|
||||
build:
|
||||
name: Build on Android NDK ${{ matrix.arch.name }}
|
80
.github/workflows/volk_gnsssdr_archs.yml
vendored
Normal file
80
.github/workflows/volk_gnsssdr_archs.yml
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
# SPDX-FileCopyrightText: 2023 Carles Fernandez-Prades <carles.fernandez@cttc.es>
|
||||
|
||||
name: Run volk_gnsssdr tests
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/**"
|
||||
- "CMakeLists.txt"
|
||||
pull_request:
|
||||
paths:
|
||||
- "src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/**"
|
||||
- "CMakeLists.txt"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-ubuntu-non-x86:
|
||||
runs-on: ubuntu-latest
|
||||
name: ${{ matrix.distro }} ${{ matrix.arch }} ${{ matrix.compiler.name }}
|
||||
|
||||
# Run steps on a matrix of archs.
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: aarch64
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 }
|
||||
- arch: aarch64
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: clang-14, cc: clang-14, cxx: clang++-14 }
|
||||
- arch: armv7
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 }
|
||||
- arch: ppc64le
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 }
|
||||
- arch: s390x
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 }
|
||||
- arch: riscv64
|
||||
distro: ubuntu22.04
|
||||
compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.1.0
|
||||
- uses: uraimo/run-on-arch-action@v2.5.0
|
||||
name: Build in non-x86 container
|
||||
# continue-on-error: ${{ contains(fromJson('["ppc64le", "s390x"]'), matrix.arch) }}
|
||||
id: build
|
||||
with:
|
||||
arch: ${{ matrix.arch }}
|
||||
distro: ${{ matrix.distro }}
|
||||
githubToken: ${{ github.token }} # Not required, but speeds up builds
|
||||
setup: |
|
||||
mkdir -p "${PWD}/testing"
|
||||
dockerRunArgs: |
|
||||
--volume "${PWD}:/volk_gnsssdr"
|
||||
env: |
|
||||
CC: ${{ matrix.compiler.cc }}
|
||||
CXX: ${{ matrix.compiler.cxx }}
|
||||
shell: /bin/sh
|
||||
install: |
|
||||
apt-get update -q -y
|
||||
apt-get install -q -y git cmake python3-mako liborc-dev ${{ matrix.compiler.name }}
|
||||
run: |
|
||||
git config --global --add safe.directory /volk_gnsssdr
|
||||
cd /volk_gnsssdr
|
||||
cd testing
|
||||
cmake ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/
|
||||
echo "Build with $(nproc) thread(s)"
|
||||
make -j$(nproc)
|
||||
./cpu_features/list_cpu_features
|
||||
./apps/volk_gnsssdr-config-info --alignment
|
||||
./apps/volk_gnsssdr-config-info --avail-machines
|
||||
./apps/volk_gnsssdr-config-info --all-machines
|
||||
./apps/volk_gnsssdr-config-info --malloc
|
||||
./apps/volk_gnsssdr-config-info --cc
|
||||
ctest -V
|
@ -48,7 +48,7 @@ option(ENABLE_FLEXIBAND "Enable the use of the signal source adater for the Tele
|
||||
|
||||
option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal source (experimental)" OFF)
|
||||
|
||||
option(ENABLE_ZMQ "Enable GNU Radio ZeroMQ Messaging, requires gr-zeromq" OFF)
|
||||
option(ENABLE_ZMQ "Enable GNU Radio ZeroMQ Messaging, requires gr-zeromq" ON)
|
||||
|
||||
# Performance analysis tools
|
||||
option(ENABLE_GPERFTOOLS "Enable linking to Gperftools libraries (tcmalloc and profiler)" OFF)
|
||||
@ -68,8 +68,6 @@ option(ENABLE_CUDA "Enable building of processing blocks implemented with CUDA (
|
||||
option(ENABLE_FPGA "Enable building of processing blocks implementing FPGA offloading" OFF)
|
||||
|
||||
# Building and packaging options
|
||||
option(ENABLE_GENERIC_ARCH "Builds a portable binary" OFF)
|
||||
|
||||
option(ENABLE_PACKAGING "Enable software packaging" OFF)
|
||||
|
||||
option(ENABLE_OWN_GLOG "Download glog and link it to gflags" OFF)
|
||||
@ -85,7 +83,6 @@ option(ENABLE_STRIP "Create stripped binaries without debugging symbols (in Rele
|
||||
option(Boost_USE_STATIC_LIBS "Use Boost static libs" OFF)
|
||||
|
||||
if(ENABLE_PACKAGING)
|
||||
set(ENABLE_GENERIC_ARCH ON)
|
||||
set(ENABLE_ARMA_NO_DEBUG ON)
|
||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
set(ENABLE_STRIP OFF)
|
||||
@ -344,7 +341,7 @@ if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_
|
||||
CMAKE_VERSION VERSION_LESS 3.5)
|
||||
set(GNSSSDR_GTEST_LOCAL_VERSION "1.10.x")
|
||||
else()
|
||||
set(GNSSSDR_GTEST_LOCAL_VERSION "1.12.1")
|
||||
set(GNSSSDR_GTEST_LOCAL_VERSION "1.13.0")
|
||||
endif()
|
||||
set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master")
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.17.0)
|
||||
@ -442,7 +439,6 @@ endif()
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Set minimal C and C++ standards
|
||||
################################################################################
|
||||
@ -501,23 +497,19 @@ endif()
|
||||
################################################################################
|
||||
# Check if the compiler defines the architecture as ARM
|
||||
################################################################################
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(^arm)|(^aarch64)")
|
||||
set(IS_ARM TRUE)
|
||||
endif()
|
||||
if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Darwin"))
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
set(IS_ARM TRUE)
|
||||
if(NOT CMAKE_NO_SYSTEM_FROM_IMPORTED)
|
||||
set(CMAKE_NO_SYSTEM_FROM_IMPORTED TRUE)
|
||||
endif()
|
||||
else()
|
||||
if(NOT IS_ARM)
|
||||
include(TestForARM)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)")
|
||||
set(IS_ARM TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# pkg-config - Helper tool used when compiling applications and libraries.
|
||||
################################################################################
|
||||
@ -526,6 +518,7 @@ set(FPHSA_NAME_MISMATCHED ON)
|
||||
find_package(PkgConfig)
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Find the POSIX thread (pthread) libraries
|
||||
################################################################################
|
||||
@ -620,8 +613,17 @@ if(ENABLE_UHD)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(ZEROMQ)
|
||||
set_package_properties(ZEROMQ PROPERTIES
|
||||
PURPOSE "Used by the ZMQ_Signal_Source."
|
||||
TYPE OPTIONAL
|
||||
)
|
||||
if(ENABLE_ZMQ)
|
||||
if(NOT ZEROMQ_FOUND)
|
||||
set(ENABLE_ZMQ OFF)
|
||||
else()
|
||||
list(APPEND GR_REQUIRED_COMPONENTS ZEROMQ)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(GNURADIO)
|
||||
@ -1193,7 +1195,7 @@ if(NOT VOLKGNSSSDR_FOUND)
|
||||
include(GNUInstallDirs)
|
||||
set(SUPPORTED_CPU_FEATURES_ARCH FALSE)
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES
|
||||
"(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)")
|
||||
"(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)|^riscv")
|
||||
set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
|
||||
endif()
|
||||
if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64)
|
||||
@ -1232,11 +1234,14 @@ if(NOT VOLKGNSSSDR_FOUND)
|
||||
set_package_properties(CPUFEATURES PROPERTIES
|
||||
DESCRIPTION "A cross platform C99 library to get CPU features at runtime (version: ${CPUFEATURES_VERSION})"
|
||||
)
|
||||
if((CMAKE_SYSTEM_PROCESSOR MATCHES "(^s390x)|^riscv") AND (CPUFEATURES_VERSION VERSION_LESS "0.8.0")) # detect cpu_features without s390x / riscv support
|
||||
set(ENABLE_CPUFEATURES OFF)
|
||||
endif()
|
||||
else()
|
||||
set_package_properties(CPUFEATURES PROPERTIES
|
||||
DESCRIPTION "A cross platform C99 library to get CPU features at runtime"
|
||||
)
|
||||
if(VOLK_VERSION AND VOLK_VERSION VERSION_GREATER "2.3" AND VOLK_VERSION VERSION_LESS "2.5.2") # detect "hidden" cpu_features 0.6.0
|
||||
if(DEFINED VOLK_VERSION AND VOLK_VERSION VERSION_GREATER "2.3") # avoid clash with volk's cpufeatures.
|
||||
set(ENABLE_CPUFEATURES OFF)
|
||||
else()
|
||||
set_package_properties(CPUFEATURES PROPERTIES
|
||||
@ -1805,6 +1810,9 @@ else()
|
||||
if(NOT BLA_VENDOR)
|
||||
set(BLA_VENDOR "Generic")
|
||||
endif()
|
||||
if(NOT CMAKE_CROSSCOMPILING AND NOT DEFINED BLA_PREFER_PKGCONFIG)
|
||||
set(BLA_PREFER_PKGCONFIG ON) # Required by riscv64 arch
|
||||
endif()
|
||||
find_package(BLAS)
|
||||
set_package_properties(BLAS PROPERTIES
|
||||
URL "https://www.netlib.org/blas/"
|
||||
@ -2903,9 +2911,9 @@ if(ENABLE_OPENCL)
|
||||
message(STATUS " You can disable OpenCL use by doing 'cmake -DENABLE_OPENCL=OFF ..'")
|
||||
endif()
|
||||
endif()
|
||||
if(ENABLE_GENERIC_ARCH)
|
||||
if(ENABLE_PACKAGING)
|
||||
set(ENABLE_OPENCL OFF)
|
||||
message(STATUS "ENABLE_GENERIC_ARCH is set to ON so the use of OpenCL has been disabled.")
|
||||
message(STATUS "ENABLE_PACKAGING is set to ON so the use of OpenCL has been disabled.")
|
||||
endif()
|
||||
if(NOT OPENCL_FOUND)
|
||||
message(STATUS "Processing blocks using OpenCL will not be built.")
|
||||
@ -3282,36 +3290,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Processor-architecture related flags
|
||||
# See https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32)
|
||||
if(NOT ENABLE_GENERIC_ARCH)
|
||||
if(IS_ARM)
|
||||
# ARM-specific options
|
||||
# See https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html
|
||||
if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_TOOLCHAIN_FILE)
|
||||
add_compile_options(-mtune=native)
|
||||
endif()
|
||||
else()
|
||||
if(NOT ENABLE_CUDA)
|
||||
add_compile_options(-march=native)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(NOT ENABLE_GENERIC_ARCH)
|
||||
if(IS_ARM)
|
||||
# ARM-specific options
|
||||
if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_TOOLCHAIN_FILE)
|
||||
add_compile_options(-mcpu=native)
|
||||
endif()
|
||||
else()
|
||||
add_compile_options(-march=native)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
@ -3384,7 +3362,6 @@ add_feature_info(ENABLE_OPENCL ENABLE_OPENCL "Enables GPS_L1_CA_PCPS_OpenCl_Acqu
|
||||
add_feature_info(ENABLE_CUDA ENABLE_CUDA "Enables GPS_L1_CA_DLL_PLL_Tracking_GPU (experimental). Requires CUDA.")
|
||||
add_feature_info(ENABLE_FPGA ENABLE_FPGA "Enables building of processing blocks for FPGA offloading.")
|
||||
add_feature_info(ENABLE_ARMA_NO_DEBUG ENABLE_ARMA_NO_DEBUG "Enables passing the ARMA_NO_DEBUG macro to Armadillo, hence disabling bound checking.")
|
||||
add_feature_info(ENABLE_GENERIC_ARCH ENABLE_GENERIC_ARCH "When disabled, flags such as '-march=native' are passed to the compiler.")
|
||||
add_feature_info(ENABLE_PACKAGING ENABLE_PACKAGING "Enables software packaging.")
|
||||
add_feature_info(ENABLE_OWN_GLOG ENABLE_OWN_GLOG "Forces the downloading and building of Google glog.")
|
||||
add_feature_info(ENABLE_OWN_ARMADILLO ENABLE_OWN_ARMADILLO "Forces the downloading and building of Armadillo.")
|
||||
|
61
README.md
61
README.md
@ -64,11 +64,12 @@ information about this open-source, software-defined GNSS receiver.
|
||||
1. [GNU/Linux](#gnulinux)
|
||||
1. [Alternative 1: Install dependencies using software packages](#alternative-1-install-dependencies-using-software-packages)
|
||||
1. [Debian / Ubuntu](#debian--ubuntu)
|
||||
2. [Arch Linux](#arch-linux)
|
||||
3. [CentOS](#centos)
|
||||
4. [Fedora](#fedora)
|
||||
5. [openSUSE](#opensuse)
|
||||
6. [Rocky Linux](#rocky-linux)
|
||||
2. [AlmaLinux](#almalinux)
|
||||
3. [Arch Linux](#arch-linux)
|
||||
4. [CentOS](#centos)
|
||||
5. [Fedora](#fedora)
|
||||
6. [openSUSE](#opensuse)
|
||||
7. [Rocky Linux](#rocky-linux)
|
||||
2. [Alternative 2: Install dependencies using PyBOMBS](#alternative-2-install-dependencies-using-pybombs)
|
||||
3. [Manual installation of other required dependencies](#manual-installation-of-other-required-dependencies)
|
||||
1. [Install Armadillo, a C++ linear algebra library](#install-armadillo-a-c-linear-algebra-library)
|
||||
@ -85,7 +86,6 @@ information about this open-source, software-defined GNSS receiver.
|
||||
2. [Build FMCOMMS2 based SDR Hardware support (OPTIONAL)](#build-fmcomms2-based-sdr-hardware-support-optional)
|
||||
3. [Build OpenCL support (OPTIONAL)](#build-opencl-support-optional)
|
||||
4. [Build CUDA support (OPTIONAL)](#build-cuda-support-optional)
|
||||
5. [Build a portable binary](#build-a-portable-binary)
|
||||
2. [macOS](#macos)
|
||||
1. [Macports](#macports)
|
||||
2. [Homebrew](#homebrew)
|
||||
@ -142,6 +142,7 @@ This section describes how to set up the compilation environment in GNU/Linux or
|
||||
Motorola (now Freescale), and Apple.
|
||||
- ppc64: 64-bit big-endian PowerPC architecture.
|
||||
- ppc64el: 64-bit little-endian PowerPC architecture.
|
||||
- riscv64: 64-bit RISC-V open standard instruction set architecture.
|
||||
- s390x: IBM System z architecture for mainframe computers.
|
||||
|
||||
Older distribution releases might work as well, but you will need GCC 4.7 or
|
||||
@ -201,6 +202,26 @@ need `python-six`.
|
||||
Once you have installed these packages, you can jump directly to
|
||||
[download the source code and build GNSS-SDR](#clone-gnss-sdrs-git-repository).
|
||||
|
||||
#### AlmaLinux
|
||||
|
||||
If you are using AlmaLinux:
|
||||
|
||||
```
|
||||
# dnf update -y
|
||||
# dnf install -y 'dnf-command(config-manager)'
|
||||
# dnf config-manager --set-enabled powertools
|
||||
# dnf install -y epel-release
|
||||
# dnf 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](#clone-gnss-sdrs-git-repository).
|
||||
|
||||
#### Arch Linux
|
||||
|
||||
If you are using Arch Linux:
|
||||
@ -496,8 +517,8 @@ $ sudo ldconfig
|
||||
#### Download [GoogleTest](https://github.com/google/googletest "Googletest Homepage")
|
||||
|
||||
```
|
||||
$ wget https://github.com/google/googletest/archive/release-1.12.1.zip
|
||||
$ unzip release-1.12.1.zip
|
||||
$ wget https://github.com/google/googletest/archive/refs/tags/v1.13.0.zip
|
||||
$ unzip v1.13.0.zip
|
||||
```
|
||||
|
||||
Please **DO NOT build or install** Google Test. Every user needs to compile
|
||||
@ -521,10 +542,10 @@ downloaded resides. Just type in your terminal (or add it to your
|
||||
`$HOME/.bashrc` file for a permanent solution) the following line:
|
||||
|
||||
```
|
||||
export GTEST_DIR=/home/username/googletest-release-1.12.1
|
||||
export GTEST_DIR=/home/username/googletest-1.13.0
|
||||
```
|
||||
|
||||
changing `/home/username/googletest-release-1.12.1` by the actual path where you
|
||||
changing `/home/username/googletest-1.13.0` by the actual path where you
|
||||
unpacked Google Test. If the CMake script does not find that folder, or the
|
||||
environment variable is not defined, or the source code is not installed by a
|
||||
package, then it will download a fresh copy of the Google Test source code and
|
||||
@ -790,26 +811,6 @@ $ sudo make install
|
||||
Of course, you will also need a GPU that
|
||||
[supports CUDA](https://developer.nvidia.com/cuda-gpus "CUDA GPUs").
|
||||
|
||||
#### Build a portable binary
|
||||
|
||||
In order to build an executable that not depends on the specific SIMD
|
||||
instruction set that is present in the processor of the compiling machine, so
|
||||
other users can execute it in other machines without those particular sets, use:
|
||||
|
||||
```
|
||||
$ cmake -DENABLE_GENERIC_ARCH=ON ..
|
||||
$ make
|
||||
$ sudo make install
|
||||
```
|
||||
|
||||
Using this option, all SIMD instructions are exclusively accessed via VOLK,
|
||||
which automatically includes versions of each function for different SIMD
|
||||
instruction sets, then detects at runtime which to use, or if there are none,
|
||||
substitutes a generic, non-SIMD implementation.
|
||||
|
||||
More details can be found in our tutorial about
|
||||
[GNSS-SDR configuration options at building time](https://gnss-sdr.org/docs/tutorials/using-git/ "Configuration options at building time").
|
||||
|
||||
## macOS
|
||||
|
||||
GNSS-SDR can be built on macOS (or the former Mac OS X), starting from 10.9
|
||||
|
@ -20,7 +20,7 @@ if(DEFINED ENV{GFORTRAN_ROOT})
|
||||
)
|
||||
endif()
|
||||
|
||||
set(GCC_MAJOR_SERIES 12 11 10 9 8 7 6 5)
|
||||
set(GCC_MAJOR_SERIES 13 12 11 10 9 8 7 6 5)
|
||||
set(GCC4_SERIES 4.9.1 4.9 4.8.3 4.8.1 4.7.2 4.7 4.8.2 4.8 4.7 4.6 4.5 4.4.4 4.4)
|
||||
set(GCC_SERIES ${GCC_MAJOR_SERIES} ${GCC4_SERIES})
|
||||
|
||||
|
82
cmake/Modules/FindZEROMQ.cmake
Normal file
82
cmake/Modules/FindZEROMQ.cmake
Normal file
@ -0,0 +1,82 @@
|
||||
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
# This file is part of GNSS-SDR.
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2023 C. Fernandez-Prades cfernandez(at)cttc.es
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#
|
||||
# Provides the following imported target:
|
||||
# ZeroMQ::ZeroMQ
|
||||
#
|
||||
|
||||
if(NOT COMMAND feature_summary)
|
||||
include(FeatureSummary)
|
||||
endif()
|
||||
|
||||
if(NOT PKG_CONFIG_FOUND)
|
||||
include(FindPkgConfig)
|
||||
endif()
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_ZEROMQ "libzmq")
|
||||
|
||||
find_path(ZEROMQ_INCLUDE_DIRS
|
||||
NAMES zmq.hpp
|
||||
HINTS ${PC_ZEROMQ_INCLUDE_DIR} ${CMAKE_INSTALL_PREFIX}/include
|
||||
PATHS /usr/local/include /usr/include /opt/local/include
|
||||
)
|
||||
|
||||
find_library(ZEROMQ_LIBRARIES
|
||||
NAMES zmq libzmq.so.5 ${ZEROMQ_LIBRARY_NAME}
|
||||
HINTS ${PC_ZEROMQ_LIBDIR} ${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_INSTALL_PREFIX}/lib64
|
||||
PATHS /usr/lib
|
||||
/usr/lib64
|
||||
/usr/lib/alpha-linux-gnu
|
||||
/usr/lib/x86_64-linux-gnu
|
||||
/usr/lib/aarch64-linux-gnu
|
||||
/usr/lib/arm-linux-gnueabi
|
||||
/usr/lib/arm-linux-gnueabihf
|
||||
/usr/lib/hppa-linux-gnu
|
||||
/usr/lib/i386-linux-gnu
|
||||
/usr/lib/m68k-linux-gnu
|
||||
/usr/lib/mips-linux-gnu
|
||||
/usr/lib/mips64el-linux-gnuabi64
|
||||
/usr/lib/mipsel-linux-gnu
|
||||
/usr/lib/powerpc-linux-gnuspe
|
||||
/usr/lib/powerpc64-linux-gnu
|
||||
/usr/lib/powerpc64le-linux-gnu
|
||||
/usr/lib/riscv64-linux-gnu
|
||||
/usr/lib/s390x-linux-gnu
|
||||
/usr/lib/sh4-linux-gnu
|
||||
/usr/lib/sparc64-linux-gnu
|
||||
/usr/lib/x86_64-linux-gnux32
|
||||
/usr/lib/x86_64-kfreebsd-gnu
|
||||
/usr/lib/i386-kfreebsd-gnu
|
||||
/usr/local/lib
|
||||
/usr/local/lib64
|
||||
/opt/local/lib
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# This is just to detect presence, include files not required
|
||||
find_package_handle_standard_args(ZEROMQ DEFAULT_MSG ZEROMQ_LIBRARIES)
|
||||
mark_as_advanced(ZEROMQ_LIBRARIES ZEROMQ_INCLUDE_DIRS)
|
||||
|
||||
set_package_properties(ZEROMQ PROPERTIES URL "https://zeromq.org/")
|
||||
if(PC_ZEROMQ_VERSION)
|
||||
set_package_properties(ZEROMQ PROPERTIES
|
||||
DESCRIPTION "An open-source universal messaging library (found: v${PC_ZEROMQ_VERSION})"
|
||||
)
|
||||
else()
|
||||
set_package_properties(ZEROMQ PROPERTIES
|
||||
DESCRIPTION "An open-source universal messaging library"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ZEROMQ_FOUND AND ZEROMQ_INCLUDE_DIRS AND NOT TARGET ZeroMQ::ZeroMQ)
|
||||
add_library(ZeroMQ::ZeroMQ INTERFACE IMPORTED)
|
||||
set_target_properties(ZeroMQ::ZeroMQ PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${ZEROMQ_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${ZEROMQ_LIBRARIES}"
|
||||
)
|
||||
endif()
|
@ -12,13 +12,22 @@
|
||||
# - cmd an additional command to run
|
||||
# - have the result variable to set
|
||||
########################################################################
|
||||
macro(GNSSSDR_PYTHON_CHECK_MODULE_RAW desc python_code have)
|
||||
macro(GNSSSDR_PYTHON_CHECK_MODULE desc mod cmd have)
|
||||
message(STATUS "Python checking for ${desc}")
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c "${python_code}"
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c "
|
||||
#########################################
|
||||
try: import ${mod}
|
||||
except:
|
||||
try: ${mod}
|
||||
except: exit(-1)
|
||||
try: assert ${cmd}
|
||||
except: exit(-1)
|
||||
#########################################"
|
||||
OUTPUT_QUIET ERROR_QUIET
|
||||
RESULT_VARIABLE return_code
|
||||
RESULT_VARIABLE ${have}
|
||||
)
|
||||
if(return_code EQUAL 0)
|
||||
if(${have} EQUAL 0)
|
||||
message(STATUS "Python checking for ${desc} - found")
|
||||
set(${have} TRUE)
|
||||
else()
|
||||
@ -27,19 +36,6 @@ macro(GNSSSDR_PYTHON_CHECK_MODULE_RAW desc python_code have)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(GNSSSDR_PYTHON_CHECK_MODULE desc mod cmd have)
|
||||
gnsssdr_python_check_module_raw(
|
||||
"${desc}" "
|
||||
#########################################
|
||||
try:
|
||||
import ${mod}
|
||||
assert ${cmd}
|
||||
except (ImportError, AssertionError): exit(-1)
|
||||
except: pass
|
||||
#########################################"
|
||||
"${have}")
|
||||
endmacro()
|
||||
|
||||
|
||||
########################################################################
|
||||
# Setup the python interpreter:
|
||||
|
@ -1,115 +0,0 @@
|
||||
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
# This file is part of GNSS-SDR.
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
##############################################################################
|
||||
# check if the compiler defines the architecture as ARM and set the
|
||||
# version, if found.
|
||||
#
|
||||
# - Anthony Arnold
|
||||
##############################################################################
|
||||
|
||||
if(__TEST_FOR_ARM_INCLUDED)
|
||||
return()
|
||||
endif()
|
||||
set(__TEST_FOR_ARM_INCLUDED TRUE)
|
||||
|
||||
# Function checks if the input string defines ARM version and sets the
|
||||
# output variable if found.
|
||||
function(check_arm_version ppdef input_string version output_var)
|
||||
string(REGEX MATCH "${ppdef}" _VERSION_MATCH "${input_string}")
|
||||
if(NOT _VERSION_MATCH STREQUAL "")
|
||||
set(${output_var} "${version}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
message(STATUS "Checking for ARM")
|
||||
|
||||
set(IS_ARM FALSE)
|
||||
set(ARM_VERSION "")
|
||||
|
||||
if(ENABLE_PACKAGING)
|
||||
set(VERBOSE_BUILDING "-v")
|
||||
else()
|
||||
set(VERBOSE_BUILDING "")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
execute_process(COMMAND echo "int main(){}"
|
||||
COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -dM ${VERBOSE_BUILDING} -E -
|
||||
OUTPUT_VARIABLE TEST_FOR_ARM_RESULTS
|
||||
)
|
||||
|
||||
string(REGEX MATCH "__arm" ARM_FOUND "${TEST_FOR_ARM_RESULTS}")
|
||||
if(ARM_FOUND STREQUAL "")
|
||||
string(REGEX MATCH "__aarch64" ARM_FOUND "${TEST_FOR_ARM_RESULTS}")
|
||||
endif()
|
||||
if(ARM_FOUND STREQUAL "")
|
||||
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm")
|
||||
set(ARM_FOUND ${CMAKE_HOST_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT ARM_FOUND STREQUAL "")
|
||||
set(IS_ARM TRUE)
|
||||
message(STATUS "ARM system detected.")
|
||||
|
||||
# detect the version
|
||||
check_arm_version("__ARM_ARCH_2__" ${TEST_FOR_ARM_RESULTS} "armv2" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_2A__" ${TEST_FOR_ARM_RESULTS} "armv2a" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_3__" ${TEST_FOR_ARM_RESULTS} "armv3" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_3M__" ${TEST_FOR_ARM_RESULTS} "armv3m" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_4__" ${TEST_FOR_ARM_RESULTS} "armv4" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_4T__" ${TEST_FOR_ARM_RESULTS} "armv4t" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_5__" ${TEST_FOR_ARM_RESULTS} "armv5" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_5T__" ${TEST_FOR_ARM_RESULTS} "armv5t" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_5E__" ${TEST_FOR_ARM_RESULTS} "armv5e" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_5TE__" ${TEST_FOR_ARM_RESULTS} "armv5te" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_6__" ${TEST_FOR_ARM_RESULTS} "armv6" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_6J__" ${TEST_FOR_ARM_RESULTS} "armv6j" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_6K__" ${TEST_FOR_ARM_RESULTS} "armv6k" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_6T2__" ${TEST_FOR_ARM_RESULTS} "armv6t2" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_6Z__" ${TEST_FOR_ARM_RESULTS} "armv6z" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_6ZK__" ${TEST_FOR_ARM_RESULTS} "armv6zk" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_6M__" ${TEST_FOR_ARM_RESULTS} "armv6-m" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_7__" ${TEST_FOR_ARM_RESULTS} "armv7" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_7A__" ${TEST_FOR_ARM_RESULTS} "armv7-a" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_7M__" ${TEST_FOR_ARM_RESULTS} "armv7-m" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_7R__" ${TEST_FOR_ARM_RESULTS} "armv7-r" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_7EM_" ${TEST_FOR_ARM_RESULTS} "armv7e-m" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_7VE__" ${TEST_FOR_ARM_RESULTS} "armv7ve" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_8A__" ${TEST_FOR_ARM_RESULTS} "armv8-a" ARM_VERSION)
|
||||
check_arm_version("__ARM_ARCH_8A" ${TEST_FOR_ARM_RESULTS} "armv8-a" ARM_VERSION)
|
||||
|
||||
# anything else just define as unknown
|
||||
if(ARM_VERSION STREQUAL "")
|
||||
message(STATUS "Couldn't detect ARM version.")
|
||||
set(ARM_VERSION "unknown")
|
||||
else()
|
||||
message(STATUS "ARM version ${ARM_VERSION} detected.")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "System is not ARM.")
|
||||
endif()
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm")
|
||||
set(IS_ARM TRUE)
|
||||
set(ARM_VERSION ${CMAKE_HOST_SYSTEM_PROCESSOR})
|
||||
message(STATUS "ARM version ${ARM_VERSION} detected.")
|
||||
endif()
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "ARMClang")
|
||||
set(IS_ARM TRUE)
|
||||
set(ARM_VERSION "arm")
|
||||
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm")
|
||||
set(ARM_VERSION ${CMAKE_HOST_SYSTEM_PROCESSOR})
|
||||
message(STATUS "ARM version ${ARM_VERSION} detected.")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Not detecting ARM on non-GNUCXX or non-Clang compiler. Defaulting to false.")
|
||||
message(STATUS "If you are compiling for ARM, set -DIS_ARM=ON manually.")
|
||||
endif()
|
||||
|
||||
set(IS_ARM ${IS_ARM} CACHE BOOL "Compiling for ARM")
|
||||
set(ARM_VERSION ${ARM_VERSION} CACHE STRING "ARM version")
|
@ -14,6 +14,15 @@ All notable changes to GNSS-SDR will be documented in this file.
|
||||
|
||||
## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next)
|
||||
|
||||
### Improvements in Accuracy:
|
||||
|
||||
- Processing and application of the corrections provided by the Galileo High
|
||||
Accuracy Service (HAS) to the PVT solution. It requires at least a Galileo E1
|
||||
(or E5a) + Galileo E6B configuration. A new configuration parameter
|
||||
`PVT.use_has_corrections`, set to `true` by default, can be used to deactivate
|
||||
the application of HAS corrections but still retrieve the HAS data if set to
|
||||
`false`.
|
||||
|
||||
### Improvements in Availability:
|
||||
|
||||
- Fixed bug that made the PVT block to not resolve position anymore after a loss
|
||||
@ -70,11 +79,14 @@ All notable changes to GNSS-SDR will be documented in this file.
|
||||
- Improved passing of compiler flags to `volk_gnsssdr` if the corresponding
|
||||
environment variables are defined. This fixes warnings in some packaging
|
||||
systems.
|
||||
- Improved support for the RISC-V architecture.
|
||||
- Test files are now donwloaded at configuration time instead of being included
|
||||
in the source tree. This allows for a smaller package and fixes Lintian
|
||||
`very-long-line-length-in-source-file` warnings since those files were not
|
||||
recognized as binaries. The configuration flag `-DENABLE_PACKAGING=ON` passed
|
||||
to CMake deactivates file downloading.
|
||||
- The `ENABLE_GENERIC_ARCH` building option was removed, simplifying the process
|
||||
of buiding the software in non-x86 processor architectures.
|
||||
|
||||
### Improvements in Usability:
|
||||
|
||||
@ -96,6 +108,9 @@ All notable changes to GNSS-SDR will be documented in this file.
|
||||
manually set the bandwidth of the bandpass filter on the radio frontend.
|
||||
- The new configuration parameter `Channels_XX.RF_channel_ID` allows to specify
|
||||
the signal source per channel group.
|
||||
- New configuration parameter `PVT.use_unhealthy_sats`, set by default to
|
||||
`false`, allows processing observables of satellites that report an unhealthy
|
||||
status in the navigation message if set to `true`.
|
||||
- Allowed the CMake project to be a sub-project.
|
||||
|
||||
See the definitions of concepts and metrics at
|
||||
|
@ -878,6 +878,10 @@ Rtklib_Pvt::Rtklib_Pvt(const ConfigurationInterface* configuration,
|
||||
|
||||
// Use E6 for PVT
|
||||
pvt_output_parameters.use_e6_for_pvt = configuration->property(role + ".use_e6_for_pvt", pvt_output_parameters.use_e6_for_pvt);
|
||||
pvt_output_parameters.use_has_corrections = configuration->property(role + ".use_has_corrections", pvt_output_parameters.use_has_corrections);
|
||||
|
||||
// Use unhealthy satellites
|
||||
pvt_output_parameters.use_unhealthy_sats = configuration->property(role + ".use_unhealthy_sats", pvt_output_parameters.use_unhealthy_sats);
|
||||
|
||||
// Vector Tracking Loop (VTL)
|
||||
pvt_output_parameters.enable_vtl = configuration->property(role + ".enable_vtl", pvt_output_parameters.enable_vtl);
|
||||
|
@ -178,7 +178,9 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
|
||||
d_log_timetag(conf_.log_source_timetag),
|
||||
d_use_e6_for_pvt(conf_.use_e6_for_pvt),
|
||||
d_enable_vtl(conf_.enable_vtl),
|
||||
d_close_vtl_loop(conf_.close_vtl_loop)
|
||||
d_close_vtl_loop(conf_.close_vtl_loop),
|
||||
d_use_has_corrections(conf_.use_has_corrections),
|
||||
d_use_unhealthy_sats(conf_.use_unhealthy_sats)
|
||||
{
|
||||
// Send feedback message to observables block with the receiver clock offset
|
||||
this->message_port_register_out(pmt::mp("pvt_to_observables"));
|
||||
@ -553,19 +555,6 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
|
||||
d_user_pvt_solver = d_internal_pvt_solver;
|
||||
}
|
||||
|
||||
d_mapStringValues["1C"] = evGPS_1C;
|
||||
d_mapStringValues["2S"] = evGPS_2S;
|
||||
d_mapStringValues["L5"] = evGPS_L5;
|
||||
d_mapStringValues["1B"] = evGAL_1B;
|
||||
d_mapStringValues["5X"] = evGAL_5X;
|
||||
d_mapStringValues["E6"] = evGAL_E6;
|
||||
d_mapStringValues["7X"] = evGAL_7X;
|
||||
d_mapStringValues["1G"] = evGLO_1G;
|
||||
d_mapStringValues["2G"] = evGLO_2G;
|
||||
d_mapStringValues["B1"] = evBDS_B1;
|
||||
d_mapStringValues["B2"] = evBDS_B2;
|
||||
d_mapStringValues["B3"] = evBDS_B3;
|
||||
|
||||
// set the RTKLIB trace (debug) level
|
||||
tracelevel(conf_.rtk_trace_level);
|
||||
|
||||
@ -1209,7 +1198,15 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
if (gps_eph->SV_health != 0)
|
||||
{
|
||||
std::cout << TEXT_RED << "Satellite " << Gnss_Satellite(std::string("GPS"), gps_eph->PRN)
|
||||
<< " is not healthy, not used for navigation" << TEXT_RESET << '\n';
|
||||
<< " reports an unhealthy status,";
|
||||
if (d_use_unhealthy_sats)
|
||||
{
|
||||
std::cout << " use PVT solutions at your own risk" << TEXT_RESET << '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " not used for navigation" << TEXT_RESET << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (msg_type_hash_code == d_gps_iono_sptr_type_hash_code)
|
||||
@ -1269,8 +1266,15 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
if (gps_cnav_ephemeris->signal_health != 0)
|
||||
{
|
||||
std::cout << "Satellite " << Gnss_Satellite(std::string("GPS"), gps_cnav_ephemeris->PRN)
|
||||
<< " does not report a healthy status in the CNAV message,"
|
||||
<< " use PVT solutions at your own risk.\n";
|
||||
<< " reports an unhealthy status in the CNAV message,";
|
||||
if (d_use_unhealthy_sats)
|
||||
{
|
||||
std::cout << " use PVT solutions at your own risk.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " not used for navigation.\n";
|
||||
}
|
||||
}
|
||||
DLOG(INFO) << "New GPS CNAV ephemeris record has arrived";
|
||||
}
|
||||
@ -1356,7 +1360,15 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
((galileo_eph->E5b_HS != 0) || (galileo_eph->E5b_DVS == true)))
|
||||
{
|
||||
std::cout << TEXT_RED << "Satellite " << Gnss_Satellite(std::string("Galileo"), galileo_eph->PRN)
|
||||
<< " is not healthy, not used for navigation" << TEXT_RESET << '\n';
|
||||
<< " reports an unhealthy status,";
|
||||
if (d_use_unhealthy_sats)
|
||||
{
|
||||
std::cout << " use PVT solutions at your own risk" << TEXT_RESET << '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " not used for navigation" << TEXT_RESET << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (msg_type_hash_code == d_galileo_iono_sptr_type_hash_code)
|
||||
@ -1532,7 +1544,15 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
if (bds_dnav_eph->SV_health != 0)
|
||||
{
|
||||
std::cout << TEXT_RED << "Satellite " << Gnss_Satellite(std::string("Beidou"), bds_dnav_eph->PRN)
|
||||
<< " is not healthy, not used for navigation" << TEXT_RESET << '\n';
|
||||
<< " reports an unhealthy status,";
|
||||
if (d_use_unhealthy_sats)
|
||||
{
|
||||
std::cout << " use PVT solutions at your own risk" << TEXT_RESET << '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " not used for navigation" << TEXT_RESET << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (msg_type_hash_code == d_beidou_dnav_iono_sptr_type_hash_code)
|
||||
@ -1580,7 +1600,7 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
|
||||
}
|
||||
|
||||
|
||||
void rtklib_pvt_gs::msg_handler_has_data(const pmt::pmt_t& msg) const
|
||||
void rtklib_pvt_gs::msg_handler_has_data(const pmt::pmt_t& msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -1588,6 +1608,14 @@ void rtklib_pvt_gs::msg_handler_has_data(const pmt::pmt_t& msg) const
|
||||
if (msg_type_hash_code == d_galileo_has_data_sptr_type_hash_code)
|
||||
{
|
||||
const auto has_data = wht::any_cast<std::shared_ptr<Galileo_HAS_data>>(pmt::any_ref(msg));
|
||||
if (d_use_has_corrections && (has_data->has_status == 1)) // operational mode
|
||||
{
|
||||
d_internal_pvt_solver->store_has_data(*has_data);
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
d_user_pvt_solver->store_has_data(*has_data);
|
||||
}
|
||||
}
|
||||
if (d_has_simple_printer)
|
||||
{
|
||||
d_has_simple_printer->print_message(has_data.get());
|
||||
@ -1810,44 +1838,10 @@ void rtklib_pvt_gs::apply_rx_clock_offset(std::map<int, Gnss_Synchro>& observabl
|
||||
// all observables in the map are valid
|
||||
observables_iter->second.RX_time -= rx_clock_offset_s;
|
||||
observables_iter->second.Pseudorange_m -= rx_clock_offset_s * SPEED_OF_LIGHT_M_S;
|
||||
|
||||
switch (d_mapStringValues[observables_iter->second.Signal])
|
||||
const auto it_freq_map = SIGNAL_FREQ_MAP.find(std::string(observables_iter->second.Signal, 2));
|
||||
if (it_freq_map != SIGNAL_FREQ_MAP.cend())
|
||||
{
|
||||
case evGPS_1C:
|
||||
case evSBAS_1C:
|
||||
case evGAL_1B:
|
||||
observables_iter->second.Carrier_phase_rads -= rx_clock_offset_s * FREQ1 * TWO_PI;
|
||||
break;
|
||||
case evGPS_L5:
|
||||
case evGAL_5X:
|
||||
observables_iter->second.Carrier_phase_rads -= rx_clock_offset_s * FREQ5 * TWO_PI;
|
||||
break;
|
||||
case evGAL_E6:
|
||||
observables_iter->second.Carrier_phase_rads -= rx_clock_offset_s * FREQ6 * TWO_PI;
|
||||
break;
|
||||
case evGAL_7X:
|
||||
observables_iter->second.Carrier_phase_rads -= rx_clock_offset_s * FREQ7 * TWO_PI;
|
||||
break;
|
||||
case evGPS_2S:
|
||||
observables_iter->second.Carrier_phase_rads -= rx_clock_offset_s * FREQ2 * TWO_PI;
|
||||
break;
|
||||
case evBDS_B3:
|
||||
observables_iter->second.Carrier_phase_rads -= rx_clock_offset_s * FREQ3_BDS * TWO_PI;
|
||||
break;
|
||||
case evGLO_1G:
|
||||
observables_iter->second.Carrier_phase_rads -= rx_clock_offset_s * FREQ1_GLO * TWO_PI;
|
||||
break;
|
||||
case evGLO_2G:
|
||||
observables_iter->second.Carrier_phase_rads -= rx_clock_offset_s * FREQ2_GLO * TWO_PI;
|
||||
break;
|
||||
case evBDS_B1:
|
||||
observables_iter->second.Carrier_phase_rads -= rx_clock_offset_s * FREQ1_BDS * TWO_PI;
|
||||
break;
|
||||
case evBDS_B2:
|
||||
observables_iter->second.Carrier_phase_rads -= rx_clock_offset_s * FREQ2_BDS * TWO_PI;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
observables_iter->second.Carrier_phase_rads -= rx_clock_offset_s * it_freq_map->second * TWO_PI;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1912,44 +1906,11 @@ void rtklib_pvt_gs::initialize_and_apply_carrier_phase_offset()
|
||||
// it is set to false by the work function if the gnss_synchro is not valid
|
||||
if (d_channel_initialized.at(observables_iter->second.Channel_ID) == false)
|
||||
{
|
||||
double wavelength_m = 0;
|
||||
switch (d_mapStringValues[observables_iter->second.Signal])
|
||||
double wavelength_m = 1.0;
|
||||
const auto it_freq_map = SIGNAL_FREQ_MAP.find(std::string(observables_iter->second.Signal, 2));
|
||||
if (it_freq_map != SIGNAL_FREQ_MAP.cend())
|
||||
{
|
||||
case evGPS_1C:
|
||||
case evSBAS_1C:
|
||||
case evGAL_1B:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ1;
|
||||
break;
|
||||
case evGPS_L5:
|
||||
case evGAL_5X:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ5;
|
||||
break;
|
||||
case evGAL_E6:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ6;
|
||||
break;
|
||||
case evGAL_7X:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ7;
|
||||
break;
|
||||
case evGPS_2S:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ2;
|
||||
break;
|
||||
case evBDS_B3:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ3_BDS;
|
||||
break;
|
||||
case evGLO_1G:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ1_GLO;
|
||||
break;
|
||||
case evGLO_2G:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ2_GLO;
|
||||
break;
|
||||
case evBDS_B1:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ1_BDS;
|
||||
break;
|
||||
case evBDS_B2:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ2_BDS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / it_freq_map->second;
|
||||
}
|
||||
const double wrap_carrier_phase_rad = fmod(observables_iter->second.Carrier_phase_rads, TWO_PI);
|
||||
d_initial_carrier_phase_offset_estimation_rads.at(observables_iter->second.Channel_ID) = TWO_PI * round(observables_iter->second.Pseudorange_m / wavelength_m) - observables_iter->second.Carrier_phase_rads + wrap_carrier_phase_rad;
|
||||
@ -1962,6 +1923,16 @@ void rtklib_pvt_gs::initialize_and_apply_carrier_phase_offset()
|
||||
}
|
||||
|
||||
|
||||
void rtklib_pvt_gs::update_HAS_corrections()
|
||||
{
|
||||
this->d_internal_pvt_solver->update_has_corrections(this->d_gnss_observables_map);
|
||||
if (d_enable_rx_clock_correction == true)
|
||||
{
|
||||
this->d_user_pvt_solver->update_has_corrections(this->d_gnss_observables_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_items,
|
||||
gr_vector_void_star& output_items __attribute__((unused)))
|
||||
{
|
||||
@ -2023,7 +1994,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
if (tmp_eph_iter_gps != d_internal_pvt_solver->gps_ephemeris_map.cend())
|
||||
{
|
||||
const uint32_t prn_aux = tmp_eph_iter_gps->second.PRN;
|
||||
if ((prn_aux == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal) == std::string("1C")) && (tmp_eph_iter_gps->second.SV_health == 0))
|
||||
if ((prn_aux == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal, 2) == std::string("1C")) && (d_use_unhealthy_sats || (tmp_eph_iter_gps->second.SV_health == 0)))
|
||||
{
|
||||
store_valid_observable = true;
|
||||
}
|
||||
@ -2032,9 +2003,9 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
{
|
||||
const uint32_t prn_aux = tmp_eph_iter_gal->second.PRN;
|
||||
if ((prn_aux == in[i][epoch].PRN) &&
|
||||
(((std::string(in[i][epoch].Signal) == std::string("1B")) && (tmp_eph_iter_gal->second.E1B_DVS == false) && (tmp_eph_iter_gal->second.E1B_HS == 0)) ||
|
||||
((std::string(in[i][epoch].Signal) == std::string("5X")) && (tmp_eph_iter_gal->second.E5a_DVS == false) && (tmp_eph_iter_gal->second.E5a_HS == 0)) ||
|
||||
((std::string(in[i][epoch].Signal) == std::string("7X")) && (tmp_eph_iter_gal->second.E5b_DVS == false) && (tmp_eph_iter_gal->second.E5b_HS == 0))))
|
||||
(((std::string(in[i][epoch].Signal, 2) == std::string("1B")) && (d_use_unhealthy_sats || ((tmp_eph_iter_gal->second.E1B_DVS == false) && (tmp_eph_iter_gal->second.E1B_HS == 0)))) ||
|
||||
((std::string(in[i][epoch].Signal, 2) == std::string("5X")) && (d_use_unhealthy_sats || ((tmp_eph_iter_gal->second.E5a_DVS == false) && (tmp_eph_iter_gal->second.E5a_HS == 0)))) ||
|
||||
((std::string(in[i][epoch].Signal, 2) == std::string("7X")) && (d_use_unhealthy_sats || ((tmp_eph_iter_gal->second.E5b_DVS == false) && (tmp_eph_iter_gal->second.E5b_HS == 0))))))
|
||||
{
|
||||
store_valid_observable = true;
|
||||
}
|
||||
@ -2042,7 +2013,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
if (tmp_eph_iter_cnav != d_internal_pvt_solver->gps_cnav_ephemeris_map.cend())
|
||||
{
|
||||
const uint32_t prn_aux = tmp_eph_iter_cnav->second.PRN;
|
||||
if ((prn_aux == in[i][epoch].PRN) && (((std::string(in[i][epoch].Signal) == std::string("2S")) || (std::string(in[i][epoch].Signal) == std::string("L5")))))
|
||||
if ((prn_aux == in[i][epoch].PRN) && (((std::string(in[i][epoch].Signal, 2) == std::string("2S")) || (std::string(in[i][epoch].Signal, 2) == std::string("L5")))))
|
||||
{
|
||||
store_valid_observable = true;
|
||||
}
|
||||
@ -2050,7 +2021,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
if (tmp_eph_iter_glo_gnav != d_internal_pvt_solver->glonass_gnav_ephemeris_map.cend())
|
||||
{
|
||||
const uint32_t prn_aux = tmp_eph_iter_glo_gnav->second.PRN;
|
||||
if ((prn_aux == in[i][epoch].PRN) && ((std::string(in[i][epoch].Signal) == std::string("1G")) || (std::string(in[i][epoch].Signal) == std::string("2G"))))
|
||||
if ((prn_aux == in[i][epoch].PRN) && ((std::string(in[i][epoch].Signal, 2) == std::string("1G")) || (std::string(in[i][epoch].Signal, 2) == std::string("2G"))))
|
||||
{
|
||||
store_valid_observable = true;
|
||||
}
|
||||
@ -2058,12 +2029,12 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
if (tmp_eph_iter_bds_dnav != d_internal_pvt_solver->beidou_dnav_ephemeris_map.cend())
|
||||
{
|
||||
const uint32_t prn_aux = tmp_eph_iter_bds_dnav->second.PRN;
|
||||
if ((prn_aux == in[i][epoch].PRN) && (((std::string(in[i][epoch].Signal) == std::string("B1")) || (std::string(in[i][epoch].Signal) == std::string("B3"))) && (tmp_eph_iter_bds_dnav->second.SV_health == 0)))
|
||||
if ((prn_aux == in[i][epoch].PRN) && (((std::string(in[i][epoch].Signal, 2) == std::string("B1")) || (std::string(in[i][epoch].Signal, 2) == std::string("B3"))) && (d_use_unhealthy_sats || (tmp_eph_iter_bds_dnav->second.SV_health == 0))))
|
||||
{
|
||||
store_valid_observable = true;
|
||||
}
|
||||
}
|
||||
if (std::string(in[i][epoch].Signal) == std::string("E6"))
|
||||
if (std::string(in[i][epoch].Signal, 2) == std::string("E6"))
|
||||
{
|
||||
store_valid_observable = true;
|
||||
}
|
||||
@ -2125,6 +2096,12 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
}
|
||||
}
|
||||
|
||||
// ############ 2. APPLY HAS CORRECTIONS IF AVAILABLE ####
|
||||
if (d_use_has_corrections && !d_gnss_observables_map.empty())
|
||||
{
|
||||
this->update_HAS_corrections();
|
||||
}
|
||||
|
||||
// ############ 2 COMPUTE THE PVT ################################
|
||||
bool flag_pvt_valid = false;
|
||||
if (d_gnss_observables_map.empty() == false)
|
||||
@ -2524,7 +2501,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
// p_time += boost::posix_time::microseconds(round(rtklib_utc_time.sec * 1e6));
|
||||
// std::cout << TEXT_MAGENTA << "Observable RX time (GPST) " << boost::posix_time::to_simple_string(p_time) << TEXT_RESET << '\n';
|
||||
|
||||
DLOG(INFO) << "Position at " << boost::posix_time::to_simple_string(d_user_pvt_solver->get_position_UTC_time())
|
||||
LOG(INFO) << "Position at " << boost::posix_time::to_simple_string(d_user_pvt_solver->get_position_UTC_time())
|
||||
<< " UTC using " << d_user_pvt_solver->get_num_valid_observations() << " observations is Lat = " << d_user_pvt_solver->get_latitude() << " [deg], Long = " << d_user_pvt_solver->get_longitude()
|
||||
<< " [deg], Height = " << d_user_pvt_solver->get_height() << " [m]";
|
||||
|
||||
|
@ -49,6 +49,7 @@ class Beidou_Dnav_Almanac;
|
||||
class Beidou_Dnav_Ephemeris;
|
||||
class Galileo_Almanac;
|
||||
class Galileo_Ephemeris;
|
||||
class Galileo_HAS_data;
|
||||
class GeoJSON_Printer;
|
||||
class Gps_Almanac;
|
||||
class Gps_Ephemeris;
|
||||
@ -140,13 +141,15 @@ private:
|
||||
|
||||
void msg_handler_telemetry(const pmt::pmt_t& msg);
|
||||
|
||||
void msg_handler_has_data(const pmt::pmt_t& msg) const;
|
||||
void msg_handler_has_data(const pmt::pmt_t& msg);
|
||||
|
||||
void initialize_and_apply_carrier_phase_offset();
|
||||
|
||||
void apply_rx_clock_offset(std::map<int, Gnss_Synchro>& observables_map,
|
||||
double rx_clock_offset_s);
|
||||
|
||||
void update_HAS_corrections();
|
||||
|
||||
std::map<int, Gnss_Synchro> interpolate_observables(const std::map<int, Gnss_Synchro>& observables_map_t0,
|
||||
const std::map<int, Gnss_Synchro>& observables_map_t1,
|
||||
double rx_time_s);
|
||||
@ -160,7 +163,7 @@ private:
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long mtype; // NOLINT(google-runtime-int) required by SysV queue messaging
|
||||
long mtype; // NOLINT(google-runtime-int)
|
||||
double ttff;
|
||||
} d_ttff_msgbuf;
|
||||
bool send_sys_v_ttff_msg(d_ttff_msgbuf ttff) const;
|
||||
@ -194,23 +197,6 @@ private:
|
||||
std::vector<bool> d_channel_initialized;
|
||||
std::vector<double> d_initial_carrier_phase_offset_estimation_rads;
|
||||
|
||||
enum StringValue_
|
||||
{
|
||||
evGPS_1C,
|
||||
evGPS_2S,
|
||||
evGPS_L5,
|
||||
evSBAS_1C,
|
||||
evGAL_1B,
|
||||
evGAL_5X,
|
||||
evGAL_E6,
|
||||
evGAL_7X,
|
||||
evGLO_1G,
|
||||
evGLO_2G,
|
||||
evBDS_B1,
|
||||
evBDS_B2,
|
||||
evBDS_B3
|
||||
};
|
||||
std::map<std::string, StringValue_> d_mapStringValues;
|
||||
std::map<int, Gnss_Synchro> d_gnss_observables_map;
|
||||
std::map<int, Gnss_Synchro> d_gnss_observables_map_t0;
|
||||
std::map<int, Gnss_Synchro> d_gnss_observables_map_t1;
|
||||
@ -292,6 +278,8 @@ private:
|
||||
bool d_enable_vtl;
|
||||
bool d_close_vtl_loop;
|
||||
std::map<int, uint64_t> d_last_sent_vtl_cmd_samplestamp_map;
|
||||
bool d_use_has_corrections;
|
||||
bool d_use_unhealthy_sats;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,74 +0,0 @@
|
||||
/*!
|
||||
* \file pvt_conf.cc
|
||||
* \brief Class that contains all the configuration parameters for a PVT block
|
||||
* \author Carles Fernandez, 2018. cfernandez(at)cttc.es
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "pvt_conf.h"
|
||||
|
||||
Pvt_Conf::Pvt_Conf()
|
||||
{
|
||||
type_of_receiver = 0U;
|
||||
observable_interval_ms = 20U;
|
||||
output_rate_ms = 0;
|
||||
display_rate_ms = 0;
|
||||
kml_rate_ms = 1000;
|
||||
gpx_rate_ms = 1000;
|
||||
geojson_rate_ms = 1000;
|
||||
nmea_rate_ms = 1000;
|
||||
|
||||
max_obs_block_rx_clock_offset_ms = 40;
|
||||
rinex_version = 0;
|
||||
rinexobs_rate_ms = 0;
|
||||
rinex_name = std::string("-");
|
||||
|
||||
dump = false;
|
||||
dump_mat = true;
|
||||
|
||||
flag_nmea_tty_port = false;
|
||||
|
||||
flag_rtcm_server = false;
|
||||
flag_rtcm_tty_port = false;
|
||||
rtcm_tcp_port = 0U;
|
||||
rtcm_station_id = 0U;
|
||||
|
||||
output_enabled = true;
|
||||
rinex_output_enabled = true;
|
||||
gpx_output_enabled = true;
|
||||
geojson_output_enabled = true;
|
||||
nmea_output_file_enabled = true;
|
||||
kml_output_enabled = true;
|
||||
xml_output_enabled = true;
|
||||
rtcm_output_file_enabled = true;
|
||||
|
||||
output_path = std::string(".");
|
||||
rinex_output_path = std::string(".");
|
||||
gpx_output_path = std::string(".");
|
||||
geojson_output_path = std::string(".");
|
||||
nmea_output_file_path = std::string(".");
|
||||
kml_output_path = std::string(".");
|
||||
xml_output_path = std::string(".");
|
||||
rtcm_output_file_path = std::string(".");
|
||||
log_source_timetag_file = "PVT_timetag.dat";
|
||||
|
||||
enable_rx_clock_correction = true;
|
||||
monitor_enabled = false;
|
||||
monitor_ephemeris_enabled = false;
|
||||
protobuf_enabled = true;
|
||||
udp_port = 0;
|
||||
udp_eph_port = 0;
|
||||
pre_2009_file = false;
|
||||
show_local_time_zone = false;
|
||||
|
||||
log_source_timetag = false;
|
||||
}
|
@ -94,6 +94,8 @@ public:
|
||||
bool use_e6_for_pvt = true;
|
||||
bool enable_vtl = false;
|
||||
bool close_vtl_loop = true;
|
||||
bool use_has_corrections = true;
|
||||
bool use_unhealthy_sats = false;
|
||||
};
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* data flow and structures
|
||||
* \authors <ul>
|
||||
* <li> 2017-2019, Javier Arribas
|
||||
* <li> 2017-2019, Carles Fernandez
|
||||
* <li> 2017-2023, Carles Fernandez
|
||||
* <li> 2007-2013, T. Takasu
|
||||
* </ul>
|
||||
*
|
||||
@ -23,7 +23,7 @@
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (C) 2007-2013, T. Takasu
|
||||
* Copyright (C) 2017-2019, Javier Arribas
|
||||
* Copyright (C) 2017-2019, Carles Fernandez
|
||||
* Copyright (C) 2017-2023, Carles Fernandez
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
@ -40,6 +40,8 @@
|
||||
#include <glog/logging.h>
|
||||
#include <matio.h>
|
||||
#include "iostream"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <exception>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@ -141,6 +143,8 @@ Rtklib_Solver::Rtklib_Solver(const rtk_t &rtk,
|
||||
d_rtklib_freq_index[1] = 3;
|
||||
break;
|
||||
}
|
||||
// auto empty_map = std::map < int, HAS_obs_corrections >> ();
|
||||
// d_has_obs_corr_map["L1 C/A"] = empty_map;
|
||||
|
||||
// ############# ENABLE DATA FILE LOG #################
|
||||
if (d_flag_dump_enabled == true)
|
||||
@ -210,7 +214,7 @@ bool Rtklib_Solver::save_matfile() const
|
||||
const int32_t number_of_uint8_vars = 3;
|
||||
const int32_t number_of_float_vars = 2;
|
||||
const int32_t epoch_size_bytes = sizeof(double) * number_of_double_vars +
|
||||
sizeof(double) * number_of_double_vars_sat*6+
|
||||
sizeof(double) * number_of_double_vars_sat * 6 +
|
||||
sizeof(uint32_t) * number_of_uint32_vars +
|
||||
sizeof(uint8_t) * number_of_uint8_vars +
|
||||
sizeof(float) * number_of_float_vars;
|
||||
@ -563,6 +567,446 @@ Monitor_Pvt Rtklib_Solver::get_monitor_pvt() const
|
||||
return d_monitor_pvt;
|
||||
}
|
||||
|
||||
void Rtklib_Solver::store_has_data(const Galileo_HAS_data &new_has_data)
|
||||
{
|
||||
// Compute time of application HAS SIS ICD, Issue 1.0, Section 7.7
|
||||
uint16_t toh = new_has_data.header.toh;
|
||||
uint32_t hr = std::floor(new_has_data.tow / 3600);
|
||||
uint32_t tmt = 0;
|
||||
if ((hr * 3600 + toh) <= new_has_data.tow)
|
||||
{
|
||||
tmt = hr * 3600 + toh;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmt = (hr - 1) * 3600 + toh;
|
||||
}
|
||||
|
||||
const std::string gps_str("GPS");
|
||||
const std::string gal_str("Galileo");
|
||||
if (new_has_data.header.orbit_correction_flag)
|
||||
{
|
||||
LOG(INFO) << "Received HAS orbit corrections";
|
||||
// for each satellite in GPS ephemeris
|
||||
for (const auto &gpseph : gps_ephemeris_map)
|
||||
{
|
||||
int prn = gpseph.second.PRN;
|
||||
int32_t sis_iod = gpseph.second.IODE_SF3;
|
||||
uint16_t gnss_iod = new_has_data.get_gnss_iod(gps_str, prn);
|
||||
if (static_cast<int32_t>(gnss_iod) == sis_iod)
|
||||
{
|
||||
float radial_m = new_has_data.get_delta_radial_m(gps_str, prn);
|
||||
if (std::fabs(radial_m + 10.24) < 0.001) // -10.24 means not available
|
||||
{
|
||||
radial_m = 0.0;
|
||||
}
|
||||
float in_track_m = new_has_data.get_delta_in_track_m(gps_str, prn);
|
||||
if (std::fabs(in_track_m + 16.384) < 0.001) // -16.384 means not available
|
||||
{
|
||||
in_track_m = 0.0;
|
||||
}
|
||||
float cross_track_m = new_has_data.get_delta_in_track_m(gps_str, prn);
|
||||
if (std::fabs(cross_track_m + 16.384) < 0.001) // -16.384 means not available
|
||||
{
|
||||
cross_track_m = 0.0;
|
||||
}
|
||||
d_has_orbit_corrections_store_map[gps_str][prn].radial_m = radial_m;
|
||||
d_has_orbit_corrections_store_map[gps_str][prn].in_track_m = in_track_m;
|
||||
d_has_orbit_corrections_store_map[gps_str][prn].cross_track_m = cross_track_m;
|
||||
d_has_orbit_corrections_store_map[gps_str][prn].valid_until = tmt +
|
||||
new_has_data.get_validity_interval_s(new_has_data.validity_interval_index_orbit_corrections);
|
||||
d_has_orbit_corrections_store_map[gps_str][prn].iod = gnss_iod;
|
||||
// TODO: check for end of week
|
||||
}
|
||||
}
|
||||
|
||||
// for each satellite in Galileo ephemeris
|
||||
for (const auto &galeph : galileo_ephemeris_map)
|
||||
{
|
||||
int prn = galeph.second.PRN;
|
||||
int32_t sis_iod = galeph.second.IOD_ephemeris;
|
||||
uint16_t gnss_iod = new_has_data.get_gnss_iod(gal_str, prn);
|
||||
if (static_cast<int32_t>(gnss_iod) == sis_iod)
|
||||
{
|
||||
float radial_m = new_has_data.get_delta_radial_m(gal_str, prn);
|
||||
if (std::fabs(radial_m + 10.24) < 0.001) // -10.24 means not available
|
||||
{
|
||||
radial_m = 0.0;
|
||||
}
|
||||
float in_track_m = new_has_data.get_delta_in_track_m(gal_str, prn);
|
||||
if (std::fabs(in_track_m + 16.384) < 0.001) // -16.384 means not available
|
||||
{
|
||||
in_track_m = 0.0;
|
||||
}
|
||||
float cross_track_m = new_has_data.get_delta_in_track_m(gal_str, prn);
|
||||
if (std::fabs(cross_track_m + 16.384) < 0.001) // -16.384 means not available
|
||||
{
|
||||
cross_track_m = 0.0;
|
||||
}
|
||||
d_has_orbit_corrections_store_map[gal_str][prn].radial_m = radial_m;
|
||||
d_has_orbit_corrections_store_map[gal_str][prn].in_track_m = in_track_m;
|
||||
d_has_orbit_corrections_store_map[gal_str][prn].cross_track_m = cross_track_m;
|
||||
d_has_orbit_corrections_store_map[gal_str][prn].valid_until = tmt +
|
||||
new_has_data.get_validity_interval_s(new_has_data.validity_interval_index_orbit_corrections);
|
||||
d_has_orbit_corrections_store_map[gal_str][prn].iod = gnss_iod;
|
||||
// TODO: check for end of week
|
||||
}
|
||||
}
|
||||
}
|
||||
if (new_has_data.header.clock_fullset_flag)
|
||||
{
|
||||
LOG(INFO) << "Received HAS clock fullset corrections";
|
||||
for (const auto &gpseph : gps_ephemeris_map)
|
||||
{
|
||||
int prn = gpseph.second.PRN;
|
||||
int32_t sis_iod = gpseph.second.IODE_SF3;
|
||||
auto it = d_has_orbit_corrections_store_map[gps_str].find(prn);
|
||||
if (it != d_has_orbit_corrections_store_map[gps_str].end())
|
||||
{
|
||||
uint16_t gnss_iod = it->second.iod;
|
||||
if (static_cast<int32_t>(gnss_iod) == sis_iod)
|
||||
{
|
||||
float clock_correction_mult_m = new_has_data.get_clock_correction_mult_m(gps_str, prn);
|
||||
if ((std::fabs(clock_correction_mult_m + 10.24) < 0.001) ||
|
||||
(std::fabs(clock_correction_mult_m + 20.48) < 0.001) ||
|
||||
(std::fabs(clock_correction_mult_m + 30.72) < 0.001) ||
|
||||
(std::fabs(clock_correction_mult_m + 40.96) < 0.001))
|
||||
{
|
||||
clock_correction_mult_m = 0.0;
|
||||
}
|
||||
if ((std::fabs(clock_correction_mult_m - 10.2375) < 0.001) ||
|
||||
(std::fabs(clock_correction_mult_m - 20.475) < 0.001) ||
|
||||
(std::fabs(clock_correction_mult_m - 30.7125) < 0.001) ||
|
||||
(std::fabs(clock_correction_mult_m - 40.95) < 0.001))
|
||||
{
|
||||
// Satellite should not be used!
|
||||
clock_correction_mult_m = 0.0;
|
||||
}
|
||||
d_has_clock_corrections_store_map[gps_str][prn].clock_correction_m = clock_correction_mult_m;
|
||||
d_has_clock_corrections_store_map[gps_str][prn].valid_until = tmt +
|
||||
new_has_data.get_validity_interval_s(new_has_data.validity_interval_index_clock_fullset_corrections);
|
||||
// TODO: check for end of week
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for each satellite in Galileo ephemeris
|
||||
for (const auto &galeph : galileo_ephemeris_map)
|
||||
{
|
||||
int prn = galeph.second.PRN;
|
||||
int32_t iod_sis = galeph.second.IOD_ephemeris;
|
||||
auto it = d_has_orbit_corrections_store_map[gal_str].find(prn);
|
||||
if (it != d_has_orbit_corrections_store_map[gal_str].end())
|
||||
{
|
||||
uint16_t gnss_iod = it->second.iod;
|
||||
if (static_cast<int32_t>(gnss_iod) == iod_sis)
|
||||
{
|
||||
float clock_correction_mult_m = new_has_data.get_clock_correction_mult_m(gal_str, prn);
|
||||
// std::cout << "Galileo Satellite " << prn
|
||||
// << " clock correction=" << new_has_data.get_clock_correction_mult_m(gal_str, prn)
|
||||
// << std::endl;
|
||||
if ((std::fabs(clock_correction_mult_m + 10.24) < 0.001) ||
|
||||
(std::fabs(clock_correction_mult_m + 20.48) < 0.001) ||
|
||||
(std::fabs(clock_correction_mult_m + 30.72) < 0.001) ||
|
||||
(std::fabs(clock_correction_mult_m + 40.96) < 0.001))
|
||||
{
|
||||
clock_correction_mult_m = 0.0;
|
||||
}
|
||||
d_has_clock_corrections_store_map[gal_str][prn].clock_correction_m = clock_correction_mult_m;
|
||||
d_has_clock_corrections_store_map[gal_str][prn].valid_until = tmt +
|
||||
new_has_data.get_validity_interval_s(new_has_data.validity_interval_index_clock_fullset_corrections);
|
||||
// TODO: check for end of week
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (new_has_data.header.clock_subset_flag)
|
||||
{
|
||||
LOG(INFO) << "Received HAS clock subset corrections";
|
||||
for (const auto &gpseph : gps_ephemeris_map)
|
||||
{
|
||||
int prn = gpseph.second.PRN;
|
||||
int32_t sis_iod = gpseph.second.IODE_SF3;
|
||||
int32_t gnss_iod = d_has_orbit_corrections_store_map[gps_str][prn].iod;
|
||||
if (gnss_iod == sis_iod)
|
||||
{
|
||||
// d_has_clock_corrections_store_map[gps_str][prn].clock_correction_m = new_has_data.get_clock_subset_correction_mult_m(gps_str, prn);
|
||||
// d_has_clock_corrections_store_map[gps_str][prn].valid_until = tmt + new_has_data.get_validity_interval_s(new_has_data.validity_interval_index_clock_subset_corrections);
|
||||
// TODO: check for end of week
|
||||
}
|
||||
}
|
||||
}
|
||||
if (new_has_data.header.code_bias_flag)
|
||||
{
|
||||
LOG(INFO) << "Received HAS code bias corrections";
|
||||
uint32_t valid_until = tmt +
|
||||
new_has_data.get_validity_interval_s(new_has_data.validity_interval_index_code_bias_corrections);
|
||||
auto signals_gal = new_has_data.get_signals_in_mask(gal_str);
|
||||
for (const auto &it : signals_gal)
|
||||
{
|
||||
auto prns = new_has_data.get_PRNs_in_mask(gal_str);
|
||||
for (auto prn : prns)
|
||||
{
|
||||
float code_bias_m = new_has_data.get_code_bias_m(it, prn);
|
||||
if ((std::fabs(code_bias_m + 20.48) < 0.01)) // -20.48 means not available
|
||||
{
|
||||
code_bias_m = 0.0;
|
||||
}
|
||||
d_has_code_bias_store_map[it][prn] = {code_bias_m, valid_until};
|
||||
}
|
||||
}
|
||||
auto signals_gps = new_has_data.get_signals_in_mask(gps_str);
|
||||
for (const auto &it : signals_gps)
|
||||
{
|
||||
auto prns = new_has_data.get_PRNs_in_mask(gps_str);
|
||||
for (auto prn : prns)
|
||||
{
|
||||
float code_bias_m = new_has_data.get_code_bias_m(it, prn);
|
||||
if ((std::fabs(code_bias_m + 20.48) < 0.01)) // -20.48 means not available
|
||||
{
|
||||
code_bias_m = 0.0;
|
||||
}
|
||||
d_has_code_bias_store_map[it][prn] = {code_bias_m, valid_until};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (new_has_data.header.phase_bias_flag)
|
||||
{
|
||||
LOG(INFO) << "Received HAS phase bias corrections";
|
||||
uint32_t valid_until = tmt +
|
||||
new_has_data.get_validity_interval_s(new_has_data.validity_interval_index_phase_bias_corrections);
|
||||
|
||||
auto signals_gal = new_has_data.get_signals_in_mask(gal_str);
|
||||
for (const auto &it : signals_gal)
|
||||
{
|
||||
auto prns = new_has_data.get_PRNs_in_mask(gal_str);
|
||||
for (auto prn : prns)
|
||||
{
|
||||
float phase_bias_correction_cycles = new_has_data.get_phase_bias_cycle(it, prn);
|
||||
if (std::fabs(phase_bias_correction_cycles + 10.24) < 0.001) // -10.24 means not available
|
||||
{
|
||||
phase_bias_correction_cycles = 0.0;
|
||||
}
|
||||
d_has_phase_bias_store_map[it][prn] = {phase_bias_correction_cycles, valid_until};
|
||||
// TODO: process Phase Discontinuity Indicator
|
||||
}
|
||||
}
|
||||
auto signals_gps = new_has_data.get_signals_in_mask(gps_str);
|
||||
for (const auto &it : signals_gps)
|
||||
{
|
||||
auto prns = new_has_data.get_PRNs_in_mask(gps_str);
|
||||
for (auto prn : prns)
|
||||
{
|
||||
float phase_bias_correction_cycles = new_has_data.get_phase_bias_cycle(it, prn);
|
||||
if (std::fabs(phase_bias_correction_cycles + 10.24) < 0.001) // -10.24 means not available
|
||||
{
|
||||
phase_bias_correction_cycles = 0.0;
|
||||
}
|
||||
d_has_phase_bias_store_map[it][prn] = {phase_bias_correction_cycles, valid_until};
|
||||
// TODO: process Phase Discontinuity Indicator
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Rtklib_Solver::update_has_corrections(const std::map<int, Gnss_Synchro> &obs_map)
|
||||
{
|
||||
this->check_has_orbit_clock_validity(obs_map);
|
||||
this->get_has_biases(obs_map);
|
||||
}
|
||||
|
||||
|
||||
void Rtklib_Solver::check_has_orbit_clock_validity(const std::map<int, Gnss_Synchro> &obs_map)
|
||||
{
|
||||
for (const auto &it : obs_map)
|
||||
{
|
||||
uint32_t obs_tow = it.second.interp_TOW_ms / 1000.0;
|
||||
auto prn = static_cast<int>(it.second.PRN);
|
||||
|
||||
if (it.second.System == 'G')
|
||||
{
|
||||
auto it_sys = d_has_orbit_corrections_store_map.find("GPS");
|
||||
if (it_sys != d_has_orbit_corrections_store_map.end())
|
||||
{
|
||||
auto it_map_corr = it_sys->second.find(prn);
|
||||
if (it_map_corr != it_sys->second.end())
|
||||
{
|
||||
auto has_data_valid_until = it_map_corr->second.valid_until;
|
||||
if (has_data_valid_until < obs_tow)
|
||||
{
|
||||
// Delete outdated data
|
||||
it_sys->second.erase(prn);
|
||||
}
|
||||
}
|
||||
}
|
||||
auto it_sys_clock = d_has_clock_corrections_store_map.find("GPS");
|
||||
if (it_sys_clock != d_has_clock_corrections_store_map.end())
|
||||
{
|
||||
auto it_map_corr = it_sys_clock->second.find(prn);
|
||||
if (it_map_corr != it_sys_clock->second.end())
|
||||
{
|
||||
auto has_data_valid_until = it_map_corr->second.valid_until;
|
||||
if (has_data_valid_until < obs_tow)
|
||||
{
|
||||
// Delete outdated data
|
||||
it_sys_clock->second.erase(prn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (it.second.System == 'E')
|
||||
{
|
||||
auto it_sys = d_has_orbit_corrections_store_map.find("Galileo");
|
||||
if (it_sys != d_has_orbit_corrections_store_map.end())
|
||||
{
|
||||
auto it_map_corr = it_sys->second.find(prn);
|
||||
if (it_map_corr != it_sys->second.end())
|
||||
{
|
||||
auto has_data_valid_until = it_map_corr->second.valid_until;
|
||||
if (has_data_valid_until < obs_tow)
|
||||
{
|
||||
// Delete outdated data
|
||||
it_sys->second.erase(prn);
|
||||
}
|
||||
}
|
||||
}
|
||||
auto it_sys_clock = d_has_clock_corrections_store_map.find("Galileo");
|
||||
if (it_sys_clock != d_has_clock_corrections_store_map.end())
|
||||
{
|
||||
auto it_map_corr = it_sys_clock->second.find(prn);
|
||||
if (it_map_corr != it_sys_clock->second.end())
|
||||
{
|
||||
auto has_data_valid_until = it_map_corr->second.valid_until;
|
||||
if (has_data_valid_until < obs_tow)
|
||||
{
|
||||
// Delete outdated data
|
||||
it_sys_clock->second.erase(prn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Rtklib_Solver::get_has_biases(const std::map<int, Gnss_Synchro> &obs_map)
|
||||
{
|
||||
d_has_obs_corr_map.clear();
|
||||
if (!d_has_clock_corrections_store_map.empty() && !d_has_orbit_corrections_store_map.empty())
|
||||
{
|
||||
const std::vector<std::string> e1b_signals = {"E1-B I/NAV OS", "E1-C", "E1-B + E1-C"};
|
||||
const std::vector<std::string> e6_signals = {"E6-B C/NAV HAS", "E6-C", "E6-B + E6-C"};
|
||||
const std::vector<std::string> e5_signals = {"E5a-I F/NAV OS", "E5a-Q", "E5a-I+E5a-Q"};
|
||||
const std::vector<std::string> e7_signals = {"E5bI I/NAV OS", "E5b-Q", "E5b-I+E5b-Q"};
|
||||
const std::vector<std::string> g1c_signals = {"L1 C/A"};
|
||||
const std::vector<std::string> g2s_signals = {"L2 CM", "L2 CL", "L2 CM+CL", "L2 P"};
|
||||
const std::vector<std::string> g5_signals = {"L5 I", "L5 Q", "L5 I + L5 Q"};
|
||||
|
||||
for (const auto &it : obs_map)
|
||||
{
|
||||
uint32_t obs_tow = it.second.interp_TOW_ms / 1000.0;
|
||||
int prn = static_cast<int>(it.second.PRN);
|
||||
std::string sig(it.second.Signal, 2);
|
||||
if (it.second.System == 'E')
|
||||
{
|
||||
auto it_sys_clock = d_has_clock_corrections_store_map.find("Galileo");
|
||||
if (it_sys_clock != d_has_clock_corrections_store_map.end())
|
||||
{
|
||||
auto it_map_corr = it_sys_clock->second.find(prn);
|
||||
if (it_map_corr != it_sys_clock->second.end())
|
||||
{
|
||||
if (sig == "1B")
|
||||
{
|
||||
for (const auto &has_signal : e1b_signals)
|
||||
{
|
||||
this->get_current_has_obs_correction(has_signal, obs_tow, prn);
|
||||
}
|
||||
}
|
||||
else if (sig == "E6")
|
||||
{
|
||||
for (const auto &has_signal : e6_signals)
|
||||
{
|
||||
this->get_current_has_obs_correction(has_signal, obs_tow, prn);
|
||||
}
|
||||
}
|
||||
else if (sig == "5X")
|
||||
{
|
||||
for (const auto &has_signal : e5_signals)
|
||||
{
|
||||
this->get_current_has_obs_correction(has_signal, obs_tow, prn);
|
||||
}
|
||||
}
|
||||
else if (sig == "7X")
|
||||
{
|
||||
for (const auto &has_signal : e7_signals)
|
||||
{
|
||||
this->get_current_has_obs_correction(has_signal, obs_tow, prn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (it.second.System == 'G')
|
||||
{
|
||||
auto it_sys_clock = d_has_clock_corrections_store_map.find("GPS");
|
||||
if (it_sys_clock != d_has_clock_corrections_store_map.end())
|
||||
{
|
||||
auto it_map_corr = it_sys_clock->second.find(prn);
|
||||
if (it_map_corr != it_sys_clock->second.end())
|
||||
{
|
||||
if (sig == "1C")
|
||||
{
|
||||
for (const auto &has_signal : g1c_signals)
|
||||
{
|
||||
this->get_current_has_obs_correction(has_signal, obs_tow, prn);
|
||||
}
|
||||
}
|
||||
else if (sig == "2S")
|
||||
{
|
||||
for (const auto &has_signal : g2s_signals)
|
||||
{
|
||||
this->get_current_has_obs_correction(has_signal, obs_tow, prn);
|
||||
}
|
||||
}
|
||||
else if (sig == "L5")
|
||||
{
|
||||
for (const auto &has_signal : g5_signals)
|
||||
{
|
||||
this->get_current_has_obs_correction(has_signal, obs_tow, prn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Rtklib_Solver::get_current_has_obs_correction(const std::string &signal, uint32_t tow_obs, int prn)
|
||||
{
|
||||
auto code_bias_pair_it = this->d_has_code_bias_store_map[signal].find(prn);
|
||||
if (code_bias_pair_it != this->d_has_code_bias_store_map[signal].end())
|
||||
{
|
||||
uint32_t valid_until = code_bias_pair_it->second.second;
|
||||
if (valid_until > tow_obs)
|
||||
{
|
||||
this->d_has_obs_corr_map[signal][prn].code_bias_m = code_bias_pair_it->second.first;
|
||||
}
|
||||
}
|
||||
auto phase_bias_pair_it = this->d_has_phase_bias_store_map[signal].find(prn);
|
||||
if (phase_bias_pair_it != this->d_has_phase_bias_store_map[signal].end())
|
||||
{
|
||||
uint32_t valid_until = phase_bias_pair_it->second.second;
|
||||
if (valid_until > tow_obs)
|
||||
{
|
||||
this->d_has_obs_corr_map[signal][prn].phase_bias_cycle = phase_bias_pair_it->second.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_map, bool flag_averaging, bool enable_vtl, bool close_vtl_loop)
|
||||
{
|
||||
std::map<int, Gnss_Synchro>::const_iterator gnss_observables_iter;
|
||||
@ -599,7 +1043,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{
|
||||
case 'G':
|
||||
{
|
||||
const std::string sig_(gnss_observables_iter->second.Signal);
|
||||
const std::string sig_(gnss_observables_iter->second.Signal, 2);
|
||||
if (sig_ == "1C")
|
||||
{
|
||||
band1 = true;
|
||||
@ -628,7 +1072,8 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{
|
||||
case 'E':
|
||||
{
|
||||
const std::string sig_(gnss_observables_iter->second.Signal);
|
||||
const std::string gal_str("Galileo");
|
||||
const std::string sig_(gnss_observables_iter->second.Signal, 2);
|
||||
// Galileo E1
|
||||
if (sig_ == "1B")
|
||||
{
|
||||
@ -637,11 +1082,14 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
if (galileo_ephemeris_iter != galileo_ephemeris_map.cend())
|
||||
{
|
||||
// convert ephemeris from GNSS-SDR class to RTKLIB structure
|
||||
eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second);
|
||||
eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second,
|
||||
this->d_has_orbit_corrections_store_map[gal_str],
|
||||
this->d_has_clock_corrections_store_map[gal_str]);
|
||||
// convert observation from GNSS-SDR class to RTKLIB structure
|
||||
obsd_t newobs{};
|
||||
d_obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
d_has_obs_corr_map,
|
||||
galileo_ephemeris_iter->second.WN,
|
||||
d_rtklib_band_index[sig_]);
|
||||
valid_obs++;
|
||||
@ -666,6 +1114,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{
|
||||
d_obs_data[i + glo_valid_obs] = insert_obs_to_rtklib(d_obs_data[i + glo_valid_obs],
|
||||
gnss_observables_iter->second,
|
||||
d_has_obs_corr_map,
|
||||
galileo_ephemeris_iter->second.WN,
|
||||
d_rtklib_band_index[sig_]);
|
||||
found_E1_obs = true;
|
||||
@ -676,7 +1125,9 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{
|
||||
// insert Galileo E5 obs as new obs and also insert its ephemeris
|
||||
// convert ephemeris from GNSS-SDR class to RTKLIB structure
|
||||
eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second);
|
||||
eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second,
|
||||
this->d_has_orbit_corrections_store_map[gal_str],
|
||||
this->d_has_clock_corrections_store_map[gal_str]);
|
||||
// convert observation from GNSS-SDR class to RTKLIB structure
|
||||
const auto default_code_ = static_cast<unsigned char>(CODE_NONE);
|
||||
obsd_t newobs = {{0, 0}, '0', '0', {}, {},
|
||||
@ -684,6 +1135,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{}, {0.0, 0.0, 0.0}, {}};
|
||||
d_obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
d_has_obs_corr_map,
|
||||
galileo_ephemeris_iter->second.WN,
|
||||
d_rtklib_band_index[sig_]);
|
||||
valid_obs++;
|
||||
@ -706,6 +1158,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{
|
||||
d_obs_data[i + glo_valid_obs] = insert_obs_to_rtklib(d_obs_data[i + glo_valid_obs],
|
||||
gnss_observables_iter->second,
|
||||
d_has_obs_corr_map,
|
||||
galileo_ephemeris_iter->second.WN,
|
||||
d_rtklib_band_index[sig_]);
|
||||
found_E1_obs = true;
|
||||
@ -716,7 +1169,9 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{
|
||||
// insert Galileo E6 obs as new obs and also insert its ephemeris
|
||||
// convert ephemeris from GNSS-SDR class to RTKLIB structure
|
||||
eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second);
|
||||
eph_data[valid_obs] = eph_to_rtklib(galileo_ephemeris_iter->second,
|
||||
this->d_has_orbit_corrections_store_map[gal_str],
|
||||
this->d_has_clock_corrections_store_map[gal_str]);
|
||||
// convert observation from GNSS-SDR class to RTKLIB structure
|
||||
const auto default_code_ = static_cast<unsigned char>(CODE_NONE);
|
||||
obsd_t newobs = {{0, 0}, '0', '0', {}, {},
|
||||
@ -724,6 +1179,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{}, {0.0, 0.0, 0.0}, {}};
|
||||
d_obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
d_has_obs_corr_map,
|
||||
galileo_ephemeris_iter->second.WN,
|
||||
d_rtklib_band_index[sig_]);
|
||||
valid_obs++;
|
||||
@ -740,18 +1196,23 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{
|
||||
// GPS L1
|
||||
// 1 GPS - find the ephemeris for the current GPS SV observation. The SV PRN ID is the map key
|
||||
const std::string sig_(gnss_observables_iter->second.Signal);
|
||||
const std::string gps_str("GPS");
|
||||
const std::string sig_(gnss_observables_iter->second.Signal, 2);
|
||||
if (sig_ == "1C")
|
||||
{
|
||||
gps_ephemeris_iter = gps_ephemeris_map.find(gnss_observables_iter->second.PRN);
|
||||
if (gps_ephemeris_iter != gps_ephemeris_map.cend())
|
||||
{
|
||||
// convert ephemeris from GNSS-SDR class to RTKLIB structure
|
||||
eph_data[valid_obs] = eph_to_rtklib(gps_ephemeris_iter->second, this->is_pre_2009());
|
||||
eph_data[valid_obs] = eph_to_rtklib(gps_ephemeris_iter->second,
|
||||
this->d_has_orbit_corrections_store_map[gps_str],
|
||||
this->d_has_clock_corrections_store_map[gps_str],
|
||||
this->is_pre_2009());
|
||||
// convert observation from GNSS-SDR class to RTKLIB structure
|
||||
obsd_t newobs{};
|
||||
d_obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
d_has_obs_corr_map,
|
||||
gps_ephemeris_iter->second.WN,
|
||||
d_rtklib_band_index[sig_],
|
||||
this->is_pre_2009());
|
||||
@ -848,6 +1309,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
{}, {0.0, 0.0, 0.0}, {}};
|
||||
d_obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
|
||||
gnss_observables_iter->second,
|
||||
d_has_obs_corr_map,
|
||||
gps_cnav_ephemeris_iter->second.WN,
|
||||
d_rtklib_band_index[sig_]);
|
||||
valid_obs++;
|
||||
@ -1221,7 +1683,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
//To.Do: check it VTL uses all the information as in rtklib rescode function: v[nv] = P - (r + dtr - SPEED_OF_LIGHT_M_S * dts[i * 2] + dion + dtrp);
|
||||
//corrected pr with code bias, iono and tropo. Still needs the dtr(rx clock bias) and satellite clock bias (dts)
|
||||
vtl_data.pr_m(n) = pr_corrected_code_bias_vec[n] - tropo_vec[n] - iono_vec[n] + SPEED_OF_LIGHT_M_S * dts[n * 2];
|
||||
vtl_data.doppler_hz(n) = d_obs_data.at(n).D[0] - SPEED_OF_LIGHT_M_S *dts[1 + 2 * n] / Lambda_GPS_L1;
|
||||
vtl_data.doppler_hz(n) = d_obs_data.at(n).D[0] - SPEED_OF_LIGHT_M_S * dts[1 + 2 * n] / Lambda_GPS_L1;
|
||||
vtl_data.carrier_phase_rads(n) = d_obs_data.at(n).L[0];
|
||||
vtl_data.pr_res(n) = pr_residual_vec[n];
|
||||
}
|
||||
@ -1259,7 +1721,8 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
// pvt_sol.rr[4] = vtl_data.kf_state[4];
|
||||
// pvt_sol.rr[5] = vtl_data.kf_state[5];
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
//MAGL: the code should not enter here once the vtl has started
|
||||
// .. but it does!
|
||||
//and not only that but pvt_sol.rr seems to have NOT reasonable values
|
||||
@ -1418,7 +1881,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
|
||||
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
|
||||
tmp_double = vtl_data.rx_dts(1);
|
||||
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
|
||||
for (int n = 0; n<6; n++)
|
||||
for (int n = 0; n < 6; n++)
|
||||
{
|
||||
tmp_double = vtl_data.sat_p(n, 0);
|
||||
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
|
||||
|
@ -4,7 +4,7 @@
|
||||
* data flow and structures
|
||||
* \authors <ul>
|
||||
* <li> 2017, Javier Arribas
|
||||
* <li> 2017, Carles Fernandez
|
||||
* <li> 2017-2023, Carles Fernandez
|
||||
* <li> 2007-2013, T. Takasu
|
||||
* </ul>
|
||||
*
|
||||
@ -23,7 +23,7 @@
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (C) 2007-2013, T. Takasu
|
||||
* Copyright (C) 2017-2019, Javier Arribas
|
||||
* Copyright (C) 2017-2019, Carles Fernandez
|
||||
* Copyright (C) 2017-2023, Carles Fernandez
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
@ -41,6 +41,7 @@
|
||||
#include "beidou_dnav_utc_model.h"
|
||||
#include "galileo_almanac.h"
|
||||
#include "galileo_ephemeris.h"
|
||||
#include "galileo_has_data.h"
|
||||
#include "galileo_iono.h"
|
||||
#include "galileo_utc_model.h"
|
||||
#include "glonass_gnav_almanac.h"
|
||||
@ -57,6 +58,7 @@
|
||||
#include "monitor_pvt.h"
|
||||
#include "pvt_solution.h"
|
||||
#include "rtklib.h"
|
||||
#include "rtklib_conversions.h"
|
||||
#include "vtl_data.h"
|
||||
#include "vtl_engine.h"
|
||||
#include <array>
|
||||
@ -64,6 +66,7 @@
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
/** \addtogroup PVT
|
||||
* \{ */
|
||||
@ -95,6 +98,8 @@ public:
|
||||
double get_pdop() const override;
|
||||
double get_gdop() const override;
|
||||
Monitor_Pvt get_monitor_pvt() const;
|
||||
void store_has_data(const Galileo_HAS_data& new_has_data);
|
||||
void update_has_corrections(const std::map<int, Gnss_Synchro>& obs_map);
|
||||
|
||||
sol_t pvt_sol{};
|
||||
std::array<ssat_t, MAXSAT> pvt_ssat{};
|
||||
@ -128,10 +133,23 @@ public:
|
||||
private:
|
||||
bool save_matfile() const;
|
||||
|
||||
void check_has_orbit_clock_validity(const std::map<int, Gnss_Synchro>& obs_map);
|
||||
void get_has_biases(const std::map<int, Gnss_Synchro>& obs_map);
|
||||
void get_current_has_obs_correction(const std::string& signal, uint32_t tow_obs, int prn);
|
||||
|
||||
std::array<obsd_t, MAXOBS> d_obs_data{};
|
||||
std::array<double, 4> d_dop{};
|
||||
std::map<int, int> d_rtklib_freq_index;
|
||||
std::map<std::string, int> d_rtklib_band_index;
|
||||
|
||||
std::map<std::string, std::map<int, HAS_orbit_corrections>> d_has_orbit_corrections_store_map; // first key is system, second key is PRN
|
||||
std::map<std::string, std::map<int, HAS_clock_corrections>> d_has_clock_corrections_store_map; // first key is system, second key is PRN
|
||||
|
||||
std::map<std::string, std::map<int, std::pair<float, uint32_t>>> d_has_code_bias_store_map; // first key is signal, second key is PRN
|
||||
std::map<std::string, std::map<int, std::pair<float, uint32_t>>> d_has_phase_bias_store_map; // first key is signal, second key is PRN
|
||||
|
||||
std::map<std::string, std::map<int, HAS_obs_corrections>> d_has_obs_corr_map; // first key is signal, second key is PRN
|
||||
|
||||
std::string d_dump_filename;
|
||||
std::ofstream d_dump_file;
|
||||
rtk_t d_rtk{};
|
||||
|
@ -4,7 +4,7 @@
|
||||
* \authors <ul>
|
||||
* <li> 2007-2013, T. Takasu
|
||||
* <li> 2017, Javier Arribas
|
||||
* <li> 2017, Carles Fernandez
|
||||
* <li> 2017-2023, Carles Fernandez
|
||||
* </ul>
|
||||
*
|
||||
* This is a derived work from RTKLIB http://www.rtklib.com/
|
||||
@ -22,7 +22,7 @@
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (C) 2007-2013, T. Takasu
|
||||
* Copyright (C) 2017, Javier Arribas
|
||||
* Copyright (C) 2017, Carles Fernandez
|
||||
* Copyright (C) 2017-2023, Carles Fernandez
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
@ -451,6 +451,11 @@ typedef struct
|
||||
/* BDS :tgd[0]=BGD1,tgd[1]=BGD2 */
|
||||
double isc[4]; /* GPS :isc[0]=ISCL1, isc[1]=ISCL2, isc[2]=ISCL5I, isc[3]=ISCL5Q */
|
||||
double Adot, ndot; /* Adot,ndot for CNAV */
|
||||
float has_clock_correction_m; /* Galileo High Accuracy Service clock correction, in [m] */
|
||||
float has_orbit_radial_correction_m; /* Galileo High Accuracy Service orbit radial correction, in [m] */
|
||||
float has_orbit_in_track_correction_m; /* Galileo High Accuracy Service orbit in-track correction, in [m] */
|
||||
float has_orbit_cross_track_correction_m; /* Galileo High Accuracy Service orbit cross-track correction, in [m] */
|
||||
bool apply_has_corrections;
|
||||
} eph_t;
|
||||
|
||||
|
||||
|
@ -28,13 +28,17 @@
|
||||
#include "gps_ephemeris.h" // for Gps_Ephemeris
|
||||
#include "rtklib_rtkcmn.h"
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro, int week, int band, bool pre_2009_file)
|
||||
|
||||
obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs,
|
||||
const Gnss_Synchro& gnss_synchro,
|
||||
const std::map<std::string, std::map<int, HAS_obs_corrections>>& has_obs_corr,
|
||||
int week,
|
||||
int band,
|
||||
bool pre_2009_file)
|
||||
{
|
||||
// Get signal type info to adjust code type based on constellation
|
||||
std::string sig_ = gnss_synchro.Signal;
|
||||
const std::string sig_(gnss_synchro.Signal, 2);
|
||||
|
||||
rtklib_obs.D[band] = gnss_synchro.Carrier_Doppler_hz;
|
||||
rtklib_obs.P[band] = gnss_synchro.Pseudorange_m;
|
||||
@ -127,10 +131,275 @@ obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro
|
||||
}
|
||||
|
||||
rtklib_obs.rcv = 1;
|
||||
|
||||
if (!has_obs_corr.empty())
|
||||
{
|
||||
float has_pseudorange_correction_m = 0.0;
|
||||
float has_bias_correction_cycle = 0.0;
|
||||
switch (gnss_synchro.System)
|
||||
{
|
||||
case 'G':
|
||||
{
|
||||
if (sig_ == "1C")
|
||||
{
|
||||
const auto it = has_obs_corr.find("L1 C/A");
|
||||
if (it != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sig_ == "2S")
|
||||
{
|
||||
const auto it = has_obs_corr.find("L2 CM");
|
||||
if (it != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sig_ == "L5")
|
||||
{
|
||||
// TODO: determine which one
|
||||
const auto it = has_obs_corr.find("L5 I");
|
||||
if (it != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto it_2nd_attempt = has_obs_corr.find("L5 Q");
|
||||
if (it_2nd_attempt != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it_2nd_attempt->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it_2nd_attempt->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto it_3rd_attempt = has_obs_corr.find("L5 I + L5 Q");
|
||||
if (it_3rd_attempt != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it_3rd_attempt->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it_3rd_attempt->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'E':
|
||||
{
|
||||
if (sig_ == "1B")
|
||||
{
|
||||
// TODO: determine which one
|
||||
const auto it = has_obs_corr.find("E1-B I/NAV OS");
|
||||
if (it != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto it_2nd_attempt = has_obs_corr.find("E1-C");
|
||||
if (it_2nd_attempt != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it_2nd_attempt->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it_2nd_attempt->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto it_3rd_attempt = has_obs_corr.find("E1-B + E1-C");
|
||||
if (it_3rd_attempt != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it_3rd_attempt->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it_3rd_attempt->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sig_ == "5X")
|
||||
{
|
||||
// TODO: determine which one
|
||||
const auto it = has_obs_corr.find("E5a-I F/NAV OS");
|
||||
if (it != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto it_2nd_attempt = has_obs_corr.find("E5a-Q");
|
||||
if (it_2nd_attempt != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it_2nd_attempt->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it_2nd_attempt->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto it_3rd_attempt = has_obs_corr.find("E5a-I+E5a-Q");
|
||||
if (it_3rd_attempt != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it_3rd_attempt->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it_3rd_attempt->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (sig_ == "7X")
|
||||
{
|
||||
// TODO: determine which one
|
||||
const auto it = has_obs_corr.find("E5bI I/NAV OS");
|
||||
if (it != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto it_2nd_attempt = has_obs_corr.find("E5b-Q");
|
||||
if (it_2nd_attempt != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it_2nd_attempt->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it_2nd_attempt->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto it_3rd_attempt = has_obs_corr.find("E5b-I+E5b-Q");
|
||||
if (it_3rd_attempt != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it_3rd_attempt->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it_3rd_attempt->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sig_ == "6B")
|
||||
{
|
||||
// TODO: determine which one
|
||||
const auto it = has_obs_corr.find("E6-B C/NAV HAS");
|
||||
if (it != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto it_2nd_attempt = has_obs_corr.find("E6-C");
|
||||
if (it_2nd_attempt != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it_2nd_attempt->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it_2nd_attempt->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto it_3rd_attempt = has_obs_corr.find("E6-B + E6-C");
|
||||
if (it_3rd_attempt != has_obs_corr.cend())
|
||||
{
|
||||
const auto it2 = it_3rd_attempt->second.find(static_cast<int>(gnss_synchro.PRN));
|
||||
if (it2 != it_3rd_attempt->second.cend())
|
||||
{
|
||||
has_pseudorange_correction_m = it2->second.code_bias_m;
|
||||
has_bias_correction_cycle = it2->second.phase_bias_cycle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rtklib_obs.P[band] += has_pseudorange_correction_m;
|
||||
rtklib_obs.L[band] += has_bias_correction_cycle;
|
||||
}
|
||||
return rtklib_obs;
|
||||
}
|
||||
|
||||
|
||||
obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs,
|
||||
const Gnss_Synchro& gnss_synchro,
|
||||
int week,
|
||||
int band,
|
||||
bool pre_2009_file)
|
||||
{
|
||||
std::map<std::string, std::map<int, HAS_obs_corrections>> empty_map;
|
||||
return insert_obs_to_rtklib(rtklib_obs,
|
||||
gnss_synchro,
|
||||
empty_map,
|
||||
week,
|
||||
band,
|
||||
pre_2009_file);
|
||||
}
|
||||
|
||||
|
||||
geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const Glonass_Gnav_Utc_Model& gnav_clock_model)
|
||||
{
|
||||
int week;
|
||||
@ -172,9 +441,19 @@ geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const Glona
|
||||
|
||||
|
||||
eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph)
|
||||
{
|
||||
std::map<int, HAS_orbit_corrections> empty_orbit_map;
|
||||
std::map<int, HAS_clock_corrections> empty_clock_map;
|
||||
return eph_to_rtklib(gal_eph, empty_orbit_map, empty_clock_map);
|
||||
}
|
||||
|
||||
|
||||
eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph,
|
||||
const std::map<int, HAS_orbit_corrections>& orbit_correction_map,
|
||||
const std::map<int, HAS_clock_corrections>& clock_correction_map)
|
||||
{
|
||||
eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
// Galileo is the third satellite system for RTKLIB, so, add the required offset to discriminate Galileo ephemeris
|
||||
rtklib_sat.sat = gal_eph.PRN + NSATGPS + NSATGLO;
|
||||
rtklib_sat.A = gal_eph.sqrtA * gal_eph.sqrtA;
|
||||
@ -226,14 +505,54 @@ eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph)
|
||||
rtklib_sat.toc = gpst2time(rtklib_sat.week, toc);
|
||||
rtklib_sat.ttr = gpst2time(rtklib_sat.week, tow);
|
||||
|
||||
if (!orbit_correction_map.empty() && !clock_correction_map.empty())
|
||||
{
|
||||
int count_has_corrections = 0;
|
||||
const auto it_orbit = orbit_correction_map.find(static_cast<int>(gal_eph.PRN));
|
||||
if (it_orbit != orbit_correction_map.cend())
|
||||
{
|
||||
rtklib_sat.has_orbit_radial_correction_m = it_orbit->second.radial_m;
|
||||
rtklib_sat.has_orbit_in_track_correction_m = it_orbit->second.in_track_m;
|
||||
rtklib_sat.has_orbit_cross_track_correction_m = it_orbit->second.cross_track_m;
|
||||
count_has_corrections++;
|
||||
}
|
||||
|
||||
const auto it_clock = clock_correction_map.find(static_cast<int>(gal_eph.PRN));
|
||||
if (it_clock != clock_correction_map.cend())
|
||||
{
|
||||
rtklib_sat.has_clock_correction_m = it_clock->second.clock_correction_m;
|
||||
count_has_corrections++;
|
||||
}
|
||||
rtklib_sat.apply_has_corrections = (count_has_corrections == 2) ? true : false;
|
||||
if (rtklib_sat.apply_has_corrections)
|
||||
{
|
||||
rtklib_sat.tgd[0] = 0.0;
|
||||
rtklib_sat.tgd[1] = 0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rtklib_sat.apply_has_corrections = false;
|
||||
}
|
||||
return rtklib_sat;
|
||||
}
|
||||
|
||||
|
||||
eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph, bool pre_2009_file)
|
||||
{
|
||||
std::map<int, HAS_orbit_corrections> empty_orbit_map;
|
||||
std::map<int, HAS_clock_corrections> empty_clock_map;
|
||||
return eph_to_rtklib(gps_eph, empty_orbit_map, empty_clock_map, pre_2009_file);
|
||||
}
|
||||
|
||||
|
||||
eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph,
|
||||
const std::map<int, HAS_orbit_corrections>& orbit_correction_map,
|
||||
const std::map<int, HAS_clock_corrections>& clock_correction_map,
|
||||
bool pre_2009_file)
|
||||
{
|
||||
eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
rtklib_sat.sat = gps_eph.PRN;
|
||||
rtklib_sat.A = gps_eph.sqrtA * gps_eph.sqrtA;
|
||||
rtklib_sat.M0 = gps_eph.M_0;
|
||||
@ -284,6 +603,40 @@ eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph, bool pre_2009_file)
|
||||
rtklib_sat.toc = gpst2time(rtklib_sat.week, toc);
|
||||
rtklib_sat.ttr = gpst2time(rtklib_sat.week, tow);
|
||||
|
||||
if (!orbit_correction_map.empty() && !clock_correction_map.empty())
|
||||
{
|
||||
int count_has_corrections = 0;
|
||||
const auto it_orbit = orbit_correction_map.find(static_cast<int>(gps_eph.PRN));
|
||||
if (it_orbit != orbit_correction_map.cend())
|
||||
{
|
||||
rtklib_sat.has_orbit_radial_correction_m = it_orbit->second.radial_m;
|
||||
rtklib_sat.has_orbit_in_track_correction_m = it_orbit->second.in_track_m;
|
||||
rtklib_sat.has_orbit_cross_track_correction_m = it_orbit->second.cross_track_m;
|
||||
count_has_corrections++;
|
||||
}
|
||||
|
||||
const auto it_clock = clock_correction_map.find(static_cast<int>(gps_eph.PRN));
|
||||
if (it_clock != clock_correction_map.cend())
|
||||
{
|
||||
rtklib_sat.has_clock_correction_m = it_clock->second.clock_correction_m;
|
||||
count_has_corrections++;
|
||||
}
|
||||
rtklib_sat.apply_has_corrections = (count_has_corrections == 2) ? true : false;
|
||||
if (rtklib_sat.apply_has_corrections)
|
||||
{
|
||||
rtklib_sat.tgd[0] = 0.0;
|
||||
rtklib_sat.tgd[1] = 0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rtklib_sat.has_orbit_radial_correction_m = 0.0;
|
||||
rtklib_sat.has_orbit_in_track_correction_m = 0.0;
|
||||
rtklib_sat.has_orbit_cross_track_correction_m = 0.0;
|
||||
rtklib_sat.has_clock_correction_m = 0.0;
|
||||
rtklib_sat.apply_has_corrections = false;
|
||||
}
|
||||
|
||||
return rtklib_sat;
|
||||
}
|
||||
|
||||
@ -291,7 +644,7 @@ eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph, bool pre_2009_file)
|
||||
eph_t eph_to_rtklib(const Beidou_Dnav_Ephemeris& bei_eph)
|
||||
{
|
||||
eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
rtklib_sat.sat = bei_eph.PRN + NSATGPS + NSATGLO + NSATGAL + NSATQZS;
|
||||
rtklib_sat.A = bei_eph.sqrtA * bei_eph.sqrtA;
|
||||
rtklib_sat.M0 = bei_eph.M_0;
|
||||
@ -353,6 +706,12 @@ eph_t eph_to_rtklib(const Beidou_Dnav_Ephemeris& bei_eph)
|
||||
rtklib_sat.toc = gpst2time(rtklib_sat.week, toc);
|
||||
rtklib_sat.ttr = gpst2time(rtklib_sat.week, tow);
|
||||
|
||||
rtklib_sat.has_orbit_radial_correction_m = 0.0;
|
||||
rtklib_sat.has_orbit_in_track_correction_m = 0.0;
|
||||
rtklib_sat.has_orbit_cross_track_correction_m = 0.0;
|
||||
rtklib_sat.has_clock_correction_m = 0.0;
|
||||
rtklib_sat.apply_has_corrections = false;
|
||||
|
||||
return rtklib_sat;
|
||||
}
|
||||
|
||||
@ -360,7 +719,7 @@ eph_t eph_to_rtklib(const Beidou_Dnav_Ephemeris& bei_eph)
|
||||
eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph)
|
||||
{
|
||||
eph_t rtklib_sat = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
rtklib_sat.sat = gps_cnav_eph.PRN;
|
||||
rtklib_sat.A = gps_cnav_eph.sqrtA * gps_cnav_eph.sqrtA;
|
||||
rtklib_sat.M0 = gps_cnav_eph.M_0;
|
||||
@ -415,6 +774,12 @@ eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph)
|
||||
rtklib_sat.toc = gpst2time(rtklib_sat.week, toc);
|
||||
rtklib_sat.ttr = gpst2time(rtklib_sat.week, tow);
|
||||
|
||||
rtklib_sat.has_orbit_radial_correction_m = 0.0;
|
||||
rtklib_sat.has_orbit_in_track_correction_m = 0.0;
|
||||
rtklib_sat.has_orbit_cross_track_correction_m = 0.0;
|
||||
rtklib_sat.has_clock_correction_m = 0.0;
|
||||
rtklib_sat.apply_has_corrections = false;
|
||||
|
||||
return rtklib_sat;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,9 @@
|
||||
#define GNSS_SDR_RTKLIB_CONVERSIONS_H
|
||||
|
||||
#include "rtklib.h"
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
/** \addtogroup PVT
|
||||
* \{ */
|
||||
@ -35,8 +38,48 @@ class Gps_Almanac;
|
||||
class Gps_CNAV_Ephemeris;
|
||||
class Gps_Ephemeris;
|
||||
|
||||
class HAS_clock_corrections
|
||||
{
|
||||
public:
|
||||
HAS_clock_corrections() = default;
|
||||
float clock_correction_m{};
|
||||
uint32_t valid_until{};
|
||||
};
|
||||
|
||||
class HAS_orbit_corrections
|
||||
{
|
||||
public:
|
||||
HAS_orbit_corrections() = default;
|
||||
float radial_m{};
|
||||
float in_track_m{};
|
||||
float cross_track_m{};
|
||||
uint32_t valid_until{};
|
||||
uint16_t iod{};
|
||||
};
|
||||
|
||||
class HAS_obs_corrections
|
||||
{
|
||||
public:
|
||||
HAS_obs_corrections() = default;
|
||||
float code_bias_m{};
|
||||
float phase_bias_cycle{};
|
||||
};
|
||||
|
||||
|
||||
eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph);
|
||||
eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph, bool pre_2009_file);
|
||||
|
||||
eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph,
|
||||
const std::map<int, HAS_orbit_corrections>& orbit_correction_map,
|
||||
const std::map<int, HAS_clock_corrections>& clock_correction_map);
|
||||
|
||||
eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph,
|
||||
bool pre_2009_file = false);
|
||||
|
||||
eph_t eph_to_rtklib(const Gps_Ephemeris& gps_eph,
|
||||
const std::map<int, HAS_orbit_corrections>& orbit_correction_map,
|
||||
const std::map<int, HAS_clock_corrections>& clock_correction_map,
|
||||
bool pre_2009_file = false);
|
||||
|
||||
eph_t eph_to_rtklib(const Gps_CNAV_Ephemeris& gps_cnav_eph);
|
||||
eph_t eph_to_rtklib(const Beidou_Dnav_Ephemeris& bei_eph);
|
||||
|
||||
@ -50,6 +93,13 @@ alm_t alm_to_rtklib(const Galileo_Almanac& gal_alm);
|
||||
*/
|
||||
geph_t eph_to_rtklib(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const Glonass_Gnav_Utc_Model& gnav_clock_model);
|
||||
|
||||
obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs,
|
||||
const Gnss_Synchro& gnss_synchro,
|
||||
const std::map<std::string, std::map<int, HAS_obs_corrections>>& has_obs_corr,
|
||||
int week,
|
||||
int band,
|
||||
bool pre_2009_file = false);
|
||||
|
||||
obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro, int week, int band, bool pre_2009_file = false);
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* \authors <ul>
|
||||
* <li> 2007-2013, T. Takasu
|
||||
* <li> 2017, Javier Arribas
|
||||
* <li> 2017, Carles Fernandez
|
||||
* <li> 2017-2023, Carles Fernandez
|
||||
* </ul>
|
||||
*
|
||||
* This is a derived work from RTKLIB http://www.rtklib.com/
|
||||
@ -22,7 +22,7 @@
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (C) 2007-2013, T. Takasu
|
||||
* Copyright (C) 2017, Javier Arribas
|
||||
* Copyright (C) 2017, Carles Fernandez
|
||||
* Copyright (C) 2017-2023, Carles Fernandez
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
@ -231,6 +231,7 @@ void eph2pos(gtime_t time, const eph_t *eph, double *rs, double *dts,
|
||||
int sys;
|
||||
int prn;
|
||||
|
||||
double has_relativistic_correction = 0.0;
|
||||
trace(4, "eph2pos : time=%s sat=%2d\n", time_str(time, 3), eph->sat);
|
||||
|
||||
if (eph->A <= 0.0)
|
||||
@ -307,12 +308,102 @@ void eph2pos(gtime_t time, const eph_t *eph, double *rs, double *dts,
|
||||
rs[0] = x * cosO - y * cosi * sinO;
|
||||
rs[1] = x * sinO + y * cosi * cosO;
|
||||
rs[2] = y * sin(i);
|
||||
// Apply HAS orbit correction if available
|
||||
if (eph->apply_has_corrections)
|
||||
{
|
||||
// HAS SIS ICD, Issue 1.0, Section 7.2
|
||||
double vel_sat[3]{};
|
||||
double cross_pos_vel[3]{};
|
||||
double et[3]{};
|
||||
double ew[3]{};
|
||||
double en[3]{};
|
||||
double R[3][3]{};
|
||||
double corrections[3]{};
|
||||
double rotated_corrections[3]{};
|
||||
// Compute satellite velocity
|
||||
const double OneMinusecosE = 1.0 - (eph->e * cosE);
|
||||
const double ekdot = (sqrt(mu / (eph->A * eph->A * eph->A)) + eph->deln) / OneMinusecosE;
|
||||
const double pkdot = sqrt(1.0 - eph->e * eph->e) * ekdot / OneMinusecosE;
|
||||
const double ukdot = pkdot * (1.0 + 2.0 * (eph->cus * cos2u - eph->cuc * sin2u));
|
||||
const double ikdot = eph->idot + 2.0 * pkdot * (eph->cis * cos2u - eph->cic * sin2u);
|
||||
const double rkdot = eph->A * eph->e * sinE * ekdot + 2.0 * pkdot * (eph->crs * cos2u - eph->crc * sin2u);
|
||||
const double xpkdot = rkdot * cos(u) - y * ukdot;
|
||||
const double ypkdot = rkdot * sin(u) + x * ukdot;
|
||||
const double tmp = ypkdot * cosi - rs[2] * ikdot;
|
||||
|
||||
vel_sat[0] = -(eph->OMGd - omge) * rs[1] + xpkdot * cosO - tmp * sinO;
|
||||
vel_sat[1] = (eph->OMGd - omge) * rs[0] + xpkdot * sinO + tmp * cosO;
|
||||
vel_sat[2] = y * cosi * ikdot + ypkdot * sin(i);
|
||||
|
||||
// Compute HAS relativistic clock correction (HAS SIS ICD, Issue 1.0, Section 7.3)
|
||||
const double pos_by_vel = rs[0] * vel_sat[0] + rs[1] * vel_sat[1] + rs[2] * vel_sat[2];
|
||||
has_relativistic_correction = -(2.0 * pos_by_vel) / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S);
|
||||
|
||||
// Compute rotation matrix
|
||||
const double norm_velocity = sqrt(vel_sat[0] * vel_sat[0] + vel_sat[1] * vel_sat[1] + vel_sat[2] * vel_sat[2]);
|
||||
et[0] = vel_sat[0] / norm_velocity;
|
||||
et[1] = vel_sat[1] / norm_velocity;
|
||||
et[2] = vel_sat[2] / norm_velocity;
|
||||
|
||||
cross_pos_vel[0] = rs[1] * vel_sat[2] - rs[2] * vel_sat[1];
|
||||
cross_pos_vel[1] = rs[2] * vel_sat[0] - rs[0] * vel_sat[2];
|
||||
cross_pos_vel[2] = rs[0] * vel_sat[1] - rs[1] * vel_sat[0];
|
||||
const double norm_cross_pos_vel = sqrt(cross_pos_vel[0] * cross_pos_vel[0] + cross_pos_vel[1] * cross_pos_vel[1] + cross_pos_vel[2] * cross_pos_vel[2]);
|
||||
|
||||
ew[0] = cross_pos_vel[0] / norm_cross_pos_vel;
|
||||
ew[1] = cross_pos_vel[1] / norm_cross_pos_vel;
|
||||
ew[2] = cross_pos_vel[2] / norm_cross_pos_vel;
|
||||
|
||||
en[0] = et[1] * ew[2] - et[2] * ew[1];
|
||||
en[1] = et[2] * ew[0] - et[0] * ew[2];
|
||||
en[2] = et[0] * ew[1] - et[1] * ew[0];
|
||||
|
||||
R[0][0] = en[0];
|
||||
R[0][1] = et[0];
|
||||
R[0][2] = ew[0];
|
||||
|
||||
R[1][0] = en[1];
|
||||
R[1][1] = et[1];
|
||||
R[1][2] = ew[1];
|
||||
|
||||
R[2][0] = en[2];
|
||||
R[2][1] = et[2];
|
||||
R[2][2] = ew[2];
|
||||
|
||||
// Compute rotated corrections
|
||||
corrections[0] = eph->has_orbit_radial_correction_m;
|
||||
corrections[1] = eph->has_orbit_in_track_correction_m;
|
||||
corrections[2] = eph->has_orbit_cross_track_correction_m;
|
||||
|
||||
for (int row = 0; row < 3; row++)
|
||||
{
|
||||
for (int col = 0; col < 3; col++)
|
||||
{
|
||||
rotated_corrections[row] = R[row][col] * corrections[col];
|
||||
}
|
||||
}
|
||||
|
||||
// Apply HAS orbit corrections
|
||||
rs[0] += rotated_corrections[0];
|
||||
rs[1] += rotated_corrections[1];
|
||||
rs[2] += rotated_corrections[2];
|
||||
}
|
||||
}
|
||||
tk = timediffweekcrossover(time, eph->toc);
|
||||
*dts = eph->f0 + eph->f1 * tk + eph->f2 * tk * tk;
|
||||
|
||||
/* relativity correction */
|
||||
*dts -= 2.0 * sqrt(mu * eph->A) * eph->e * sinE / std::pow(SPEED_OF_LIGHT_M_S, 2.0);
|
||||
if (eph->apply_has_corrections)
|
||||
{
|
||||
// Apply HAS clock correction (HAS SIS ICD, Issue 1.0, Section 7.3)
|
||||
*dts += (has_relativistic_correction + (eph->has_clock_correction_m / SPEED_OF_LIGHT_M_S));
|
||||
// Note: This is referred to the GST for Galileo satellites. The user must account for
|
||||
// a possible common offset in the broadcast HAS GPS clock corrections
|
||||
}
|
||||
else
|
||||
{
|
||||
*dts -= 2.0 * sqrt(mu * eph->A) * eph->e * sinE / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S);
|
||||
}
|
||||
|
||||
/* position and clock error variance */
|
||||
*var = var_uraeph(eph->sva);
|
||||
|
@ -49,7 +49,7 @@ int init_rtcm(rtcm_t *rtcm)
|
||||
obsd_t data0 = {{0, 0.0}, 0, 0, {0}, {0}, {0}, {0.0}, {0.0}, {0.0}};
|
||||
eph_t eph0 = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
geph_t geph0 = {0, -1, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0.0}, {0.0}, {0.0},
|
||||
0.0, 0.0, 0.0};
|
||||
ssr_t ssr0 = {{{0, 0.0}}, {0.0}, {0}, 0, 0, 0, 0, {0.0}, {0.0}, {0.0}, 0.0, {0.0}, {0.0}, {0.0}, 0.0, 0.0, '0'};
|
||||
|
@ -228,7 +228,7 @@ int decode_type17(rtcm_t *rtcm, bool pre_2009_file)
|
||||
{
|
||||
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
double toc;
|
||||
double sqrtA;
|
||||
int i = 48;
|
||||
|
@ -1019,7 +1019,7 @@ int decode_type1019(rtcm_t *rtcm, bool pre_2009_file)
|
||||
{
|
||||
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
double toc;
|
||||
double sqrtA;
|
||||
char *msg;
|
||||
@ -1518,7 +1518,7 @@ int decode_type1044(rtcm_t *rtcm, bool pre_2009_file)
|
||||
{
|
||||
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
double toc;
|
||||
double sqrtA;
|
||||
char *msg;
|
||||
@ -1631,7 +1631,7 @@ int decode_type1045(rtcm_t *rtcm)
|
||||
{
|
||||
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
double toc;
|
||||
double sqrtA;
|
||||
char *msg;
|
||||
@ -1745,7 +1745,7 @@ int decode_type1046(rtcm_t *rtcm)
|
||||
{
|
||||
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
double toc;
|
||||
double sqrtA;
|
||||
char *msg;
|
||||
@ -1859,7 +1859,7 @@ int decode_type1047(rtcm_t *rtcm)
|
||||
{
|
||||
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
double toc;
|
||||
double sqrtA;
|
||||
char *msg;
|
||||
@ -1976,7 +1976,7 @@ int decode_type63(rtcm_t *rtcm)
|
||||
{
|
||||
eph_t eph = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
double toc;
|
||||
double sqrtA;
|
||||
char *msg;
|
||||
|
@ -3610,7 +3610,7 @@ int readnav(const char *file, nav_t *nav)
|
||||
{
|
||||
FILE *fp;
|
||||
eph_t eph0 = {0, 0, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
geph_t geph0 = {0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {}, {}, {}, 0.0, 0.0, 0.0};
|
||||
char buff[4096];
|
||||
char *p;
|
||||
|
@ -688,7 +688,7 @@ int rtksvrinit(rtksvr_t *svr)
|
||||
'0', '0', '0', 0, 0, 0};
|
||||
eph_t eph0 = {0, -1, -1, 0, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0, 0.0},
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0};
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {0.0}, {0.0}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false};
|
||||
geph_t geph0 = {0, -1, 0, 0, 0, 0, {0, 0.0}, {0, 0.0}, {0.0}, {0.0}, {0.0},
|
||||
0.0, 0.0, 0.0};
|
||||
seph_t seph0 = {0, {0, 0.0}, {0, 0.0}, 0, 0, {0.0}, {0.0}, {0.0}, 0.0, 0.0};
|
||||
|
@ -258,7 +258,7 @@ endif()
|
||||
|
||||
# cpu_features - sensible defaults, user settable option
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES
|
||||
"(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)")
|
||||
"(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)|^riscv")
|
||||
option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" ON)
|
||||
else()
|
||||
option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" OFF)
|
||||
@ -266,7 +266,13 @@ endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES)
|
||||
find_package(CPUFEATURES)
|
||||
if(CPUFEATURES_FOUND AND (CMAKE_SYSTEM_PROCESSOR MATCHES "(^s390x)|^riscv") AND (CPUFEATURES_VERSION VERSION_LESS "0.8.0"))
|
||||
set(USE_CPU_FEATURES OFF)
|
||||
unset(CPUFEATURES_FOUND CACHE)
|
||||
message(STATUS "Building volk-gnsssdr without cpu_features, installed version v${CPUFEATURES_VERSION} does not support the ${CMAKE_SYSTEM_PROCESSOR} architecture")
|
||||
else()
|
||||
set(USE_CPU_FEATURES ON)
|
||||
endif()
|
||||
if(NOT CPUFEATURES_FOUND)
|
||||
message(STATUS "Building volk-gnsssdr with cpu_features")
|
||||
set(BUILD_TESTING OFF CACHE BOOL "Build cpu_features without tests." FORCE)
|
||||
@ -290,13 +296,8 @@ endif()
|
||||
|
||||
# Python
|
||||
include(VolkPython) # sets PYTHON_EXECUTABLE
|
||||
volk_python_check_module("python >= 2.7" sys "sys.version.split()[0] >= '2.7'" PYTHON_MIN_VER_FOUND)
|
||||
volk_python_check_module("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND)
|
||||
if(Python2_VERSION OR (PYTHON_VERSION_STRING VERSION_LESS "3.0"))
|
||||
volk_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND)
|
||||
endif()
|
||||
|
||||
if(NOT PYTHON_MIN_VER_FOUND)
|
||||
if(NOT PYTHON_EXECUTABLE)
|
||||
message(FATAL_ERROR "Python 2.7 or greater required to build VOLK_GNSSSDR")
|
||||
endif()
|
||||
|
||||
|
@ -16,13 +16,22 @@ set(__INCLUDED_VOLK_PYTHON_CMAKE TRUE)
|
||||
# - cmd an additional command to run
|
||||
# - have the result variable to set
|
||||
########################################################################
|
||||
macro(VOLK_PYTHON_CHECK_MODULE_RAW desc python_code have)
|
||||
macro(VOLK_PYTHON_CHECK_MODULE desc mod cmd have)
|
||||
message(STATUS "Python checking for ${desc}")
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c "${python_code}"
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c "
|
||||
#########################################
|
||||
try: import ${mod}
|
||||
except:
|
||||
try: ${mod}
|
||||
except: exit(-1)
|
||||
try: assert ${cmd}
|
||||
except: exit(-1)
|
||||
#########################################"
|
||||
OUTPUT_QUIET ERROR_QUIET
|
||||
RESULT_VARIABLE return_code
|
||||
RESULT_VARIABLE ${have}
|
||||
)
|
||||
if(return_code EQUAL 0)
|
||||
if(${have} EQUAL 0)
|
||||
message(STATUS "Python checking for ${desc} - found")
|
||||
set(${have} TRUE)
|
||||
else()
|
||||
@ -31,19 +40,6 @@ macro(VOLK_PYTHON_CHECK_MODULE_RAW desc python_code have)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(VOLK_PYTHON_CHECK_MODULE desc mod cmd have)
|
||||
volk_python_check_module_raw(
|
||||
"${desc}" "
|
||||
#########################################
|
||||
try:
|
||||
import ${mod}
|
||||
assert ${cmd}
|
||||
except (ImportError, AssertionError): exit(-1)
|
||||
except: pass
|
||||
#########################################"
|
||||
"${have}")
|
||||
endmacro()
|
||||
|
||||
|
||||
########################################################################
|
||||
# Setup the python interpreter:
|
||||
@ -57,6 +53,9 @@ if(CMAKE_VERSION VERSION_LESS 3.12 OR CMAKE_CROSSCOMPILING)
|
||||
if(PYTHON_EXECUTABLE)
|
||||
message(STATUS "User set python executable ${PYTHON_EXECUTABLE}")
|
||||
find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION} REQUIRED)
|
||||
if(PYTHON_VERSION_STRING VERSION_LESS "3.0")
|
||||
volk_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND)
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "PYTHON_EXECUTABLE not set - trying by default python3")
|
||||
message(STATUS "Use -DPYTHON_EXECUTABLE=/path/to/python to build for python 2.7")
|
||||
@ -65,12 +64,18 @@ if(CMAKE_VERSION VERSION_LESS 3.12 OR CMAKE_CROSSCOMPILING)
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
message(STATUS "python3 not found - trying with python2.7")
|
||||
find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION} REQUIRED)
|
||||
volk_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND)
|
||||
endif()
|
||||
endif()
|
||||
volk_python_check_module("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND)
|
||||
else()
|
||||
if(PYTHON_EXECUTABLE)
|
||||
message(STATUS "User set python executable ${PYTHON_EXECUTABLE}")
|
||||
find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION} REQUIRED)
|
||||
volk_python_check_module("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND)
|
||||
if(PYTHON_VERSION_STRING VERSION_LESS "3.0")
|
||||
volk_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND)
|
||||
endif()
|
||||
else()
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(_previous ${CMAKE_FIND_FRAMEWORK})
|
||||
@ -98,6 +103,7 @@ else()
|
||||
if(NOT MAKO_FOUND OR NOT SIX_FOUND)
|
||||
unset(PYTHON_EXECUTABLE)
|
||||
find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION})
|
||||
volk_python_check_module("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
@ -56,6 +56,7 @@ set(PROCESSOR_IS_AARCH64 FALSE)
|
||||
set(PROCESSOR_IS_X86 FALSE)
|
||||
set(PROCESSOR_IS_POWER FALSE)
|
||||
set(PROCESSOR_IS_S390X FALSE)
|
||||
set(PROCESSOR_IS_RISCV FALSE)
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
|
||||
set(PROCESSOR_IS_MIPS TRUE)
|
||||
@ -69,6 +70,8 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
|
||||
set(PROCESSOR_IS_POWER TRUE)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)")
|
||||
set(PROCESSOR_IS_S390X TRUE)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv")
|
||||
set(PROCESSOR_IS_RISCV TRUE)
|
||||
endif()
|
||||
|
||||
macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
|
||||
@ -90,6 +93,8 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
|
||||
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h)
|
||||
elseif(PROCESSOR_IS_S390X)
|
||||
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_s390x.h)
|
||||
elseif(PROCESSOR_IS_RISCV)
|
||||
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_riscv.h)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
@ -158,14 +158,14 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
|
||||
|
||||
## What's supported
|
||||
|
||||
| | x86³ | AArch64 | ARM | MIPS⁴ | s390x | POWER |
|
||||
| ------- | :--: | :-----: | :-----: | :-----: | :-----: | :-----: |
|
||||
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ |
|
||||
| FreeBSD | yes² | not yet | not yet | not yet | not yet | not yet |
|
||||
| MacOs | yes² | not yet | N/A | N/A | no | no |
|
||||
| Windows | yes² | not yet | not yet | N/A | N/A | N/A |
|
||||
| Android | yes² | yes¹ | yes¹ | yes¹ | N/A | N/A |
|
||||
| iOS | N/A | not yet | not yet | N/A | N/A | N/A |
|
||||
| | x86³ | AArch64 | ARM | MIPS⁴ | POWER | RISCV | s390x |
|
||||
| ------- | :--: | :-----: | :-----: | :-----: | :-----: | :---: | :-----: |
|
||||
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ |
|
||||
| FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet |
|
||||
| MacOs | yes² | not yet | N/A | N/A | no | N/A | no |
|
||||
| Windows | yes² | not yet | not yet | N/A | N/A | N/A | N/A |
|
||||
| Android | yes² | yes¹ | yes¹ | yes¹ | N/A | N/A | N/A |
|
||||
| iOS | N/A | not yet | not yet | N/A | N/A | N/A | N/A |
|
||||
|
||||
1. **Features revealed from Linux.** We gather data from several sources
|
||||
depending on availability:
|
||||
|
@ -0,0 +1,62 @@
|
||||
// SPDX-FileCopyrightText: 2022 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_RISCV_H_
|
||||
#define CPU_FEATURES_INCLUDE_CPUINFO_RISCV_H_
|
||||
|
||||
#include "cpu_features_cache_info.h"
|
||||
#include "cpu_features_macros.h"
|
||||
|
||||
#if !defined(CPU_FEATURES_ARCH_RISCV)
|
||||
#error "Including cpuinfo_riscv.h from a non-riscv target."
|
||||
#endif
|
||||
|
||||
CPU_FEATURES_START_CPP_NAMESPACE
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Base
|
||||
int RV32I : 1; // Base Integer Instruction Set, 32-bit
|
||||
int RV64I : 1; // Base Integer Instruction Set, 64-bit
|
||||
|
||||
// Extension
|
||||
int M : 1; // Standard Extension for Integer Multiplication/Division
|
||||
int A : 1; // Standard Extension for Atomic Instructions
|
||||
int F : 1; // Standard Extension for Single-Precision Floating-Point
|
||||
int D : 1; // Standard Extension for Double-Precision Floating-Point
|
||||
int Q : 1; // Standard Extension for Quad-Precision Floating-Point
|
||||
int C : 1; // Standard Extension for Compressed Instructions
|
||||
int Zicsr : 1; // Control and Status Register (CSR)
|
||||
int Zifencei : 1; // Instruction-Fetch Fence
|
||||
} RiscvFeatures;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RiscvFeatures features;
|
||||
char uarch[64]; // 0 terminated string
|
||||
char vendor[64]; // 0 terminated string
|
||||
} RiscvInfo;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RISCV_RV32I,
|
||||
RISCV_RV64I,
|
||||
RISCV_M,
|
||||
RISCV_A,
|
||||
RISCV_F,
|
||||
RISCV_D,
|
||||
RISCV_Q,
|
||||
RISCV_C,
|
||||
RISCV_Zicsr,
|
||||
RISCV_Zifencei,
|
||||
RISCV_LAST_,
|
||||
} RiscvFeaturesEnum;
|
||||
|
||||
RiscvInfo GetRiscvInfo(void);
|
||||
int GetRiscvFeaturesEnumValue(const RiscvFeatures* features,
|
||||
RiscvFeaturesEnum value);
|
||||
const char* GetRiscvFeaturesEnumName(RiscvFeaturesEnum);
|
||||
|
||||
CPU_FEATURES_END_CPP_NAMESPACE
|
||||
|
||||
#endif // CPU_FEATURES_INCLUDE_CPUINFO_RISCV_H_
|
@ -193,15 +193,15 @@ CPU_FEATURES_START_CPP_NAMESPACE
|
||||
#define HWCAP_S390_SIE 4194304
|
||||
|
||||
// https://elixir.bootlin.com/linux/latest/source/arch/riscv/include/uapi/asm/hwcap.h
|
||||
#define RISCV_HWCAP_A (1UL << ('A' - 'A'))
|
||||
#define RISCV_HWCAP_C (1UL << ('C' - 'A'))
|
||||
#define RISCV_HWCAP_D (1UL << ('D' - 'A'))
|
||||
#define RISCV_HWCAP_E (1UL << ('E' - 'A'))
|
||||
#define RISCV_HWCAP_F (1UL << ('F' - 'A'))
|
||||
#define RISCV_HWCAP_I (1UL << ('I' - 'A'))
|
||||
#define RISCV_HWCAP_32 0x32
|
||||
#define RISCV_HWCAP_64 0x64
|
||||
#define RISCV_HWCAP_128 0x128
|
||||
#define RISCV_HWCAP_M (1UL << ('M' - 'A'))
|
||||
#define RISCV_HWCAP_V (1UL << ('V' - 'A'))
|
||||
#define RISCV_HWCAP_A (1UL << ('A' - 'A'))
|
||||
#define RISCV_HWCAP_F (1UL << ('F' - 'A'))
|
||||
#define RISCV_HWCAP_D (1UL << ('D' - 'A'))
|
||||
#define RISCV_HWCAP_Q (1UL << ('Q' - 'A'))
|
||||
#define RISCV_HWCAP_C (1UL << ('C' - 'A'))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -0,0 +1,109 @@
|
||||
// SPDX-FileCopyrightText: 2022 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "cpu_features_macros.h"
|
||||
|
||||
#ifdef CPU_FEATURES_ARCH_RISCV
|
||||
#if defined(CPU_FEATURES_OS_LINUX)
|
||||
|
||||
#include "cpuinfo_riscv.h"
|
||||
|
||||
// According to
|
||||
// https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/riscv/cpus.yaml
|
||||
// isa string should match the following regex
|
||||
// ^rv(?:64|32)imaf?d?q?c?b?v?k?h?(?:_[hsxz](?:[a-z])+)*$
|
||||
//
|
||||
// This means we can test for features in this exact order except for Z
|
||||
// extensions.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Definitions for introspection.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define INTROSPECTION_TABLE \
|
||||
LINE(RISCV_RV32I, RV32I, "rv32i", RISCV_HWCAP_32, 0) \
|
||||
LINE(RISCV_RV64I, RV64I, "rv64i", RISCV_HWCAP_64, 0) \
|
||||
LINE(RISCV_M, M, "m", RISCV_HWCAP_M, 0) \
|
||||
LINE(RISCV_A, A, "a", RISCV_HWCAP_A, 0) \
|
||||
LINE(RISCV_F, F, "f", RISCV_HWCAP_F, 0) \
|
||||
LINE(RISCV_D, D, "d", RISCV_HWCAP_D, 0) \
|
||||
LINE(RISCV_Q, Q, "q", RISCV_HWCAP_Q, 0) \
|
||||
LINE(RISCV_C, C, "c", RISCV_HWCAP_C, 0) \
|
||||
LINE(RISCV_Zicsr, Zicsr, "_zicsr", 0, 0) \
|
||||
LINE(RISCV_Zifencei, Zifencei, "_zifencei", 0, 0)
|
||||
#define INTROSPECTION_PREFIX Riscv
|
||||
#define INTROSPECTION_ENUM_PREFIX RISCV
|
||||
#include "define_introspection_and_hwcaps.inl"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "internal/filesystem.h"
|
||||
#include "internal/stack_line_reader.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static const RiscvInfo kEmptyRiscvInfo;
|
||||
|
||||
static void HandleRiscVIsaLine(StringView line, RiscvFeatures* const features)
|
||||
{
|
||||
for (size_t i = 0; i < RISCV_LAST_; ++i)
|
||||
{
|
||||
StringView flag = str(kCpuInfoFlags[i]);
|
||||
int index_of_flag = CpuFeatures_StringView_IndexOf(line, flag);
|
||||
bool is_set = index_of_flag != -1;
|
||||
kSetters[i](features, is_set);
|
||||
if (is_set)
|
||||
line = CpuFeatures_StringView_PopFront(line, index_of_flag + flag.size);
|
||||
}
|
||||
}
|
||||
|
||||
static bool HandleRiscVLine(const LineResult result, RiscvInfo* const info)
|
||||
{
|
||||
StringView line = result.line;
|
||||
StringView key, value;
|
||||
if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value))
|
||||
{
|
||||
if (CpuFeatures_StringView_IsEquals(key, str("isa")))
|
||||
{
|
||||
HandleRiscVIsaLine(value, &info->features);
|
||||
}
|
||||
else if (CpuFeatures_StringView_IsEquals(key, str("uarch")))
|
||||
{
|
||||
int index = CpuFeatures_StringView_IndexOfChar(value, ',');
|
||||
if (index == -1) return true;
|
||||
StringView vendor = CpuFeatures_StringView_KeepFront(value, index);
|
||||
StringView uarch = CpuFeatures_StringView_PopFront(value, index + 1);
|
||||
CpuFeatures_StringView_CopyString(vendor, info->vendor,
|
||||
sizeof(info->vendor));
|
||||
CpuFeatures_StringView_CopyString(uarch, info->uarch,
|
||||
sizeof(info->uarch));
|
||||
}
|
||||
}
|
||||
return !result.eof;
|
||||
}
|
||||
|
||||
static void FillProcCpuInfoData(RiscvInfo* const info)
|
||||
{
|
||||
const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
|
||||
if (fd >= 0)
|
||||
{
|
||||
StackLineReader reader;
|
||||
StackLineReader_Initialize(&reader, fd);
|
||||
for (;;)
|
||||
{
|
||||
if (!HandleRiscVLine(StackLineReader_NextLine(&reader), info)) break;
|
||||
}
|
||||
CpuFeatures_CloseFile(fd);
|
||||
}
|
||||
}
|
||||
|
||||
RiscvInfo GetRiscvInfo(void)
|
||||
{
|
||||
RiscvInfo info = kEmptyRiscvInfo;
|
||||
FillProcCpuInfoData(&info);
|
||||
return info;
|
||||
}
|
||||
|
||||
#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
|
||||
#endif // CPU_FEATURES_ARCH_RISCV
|
@ -25,6 +25,8 @@
|
||||
#include "cpuinfo_ppc.h"
|
||||
#elif defined(CPU_FEATURES_ARCH_S390X)
|
||||
#include "cpuinfo_s390x.h"
|
||||
#elif defined(CPU_FEATURES_ARCH_RISCV)
|
||||
#include "cpuinfo_riscv.h"
|
||||
#endif
|
||||
|
||||
// Design principles
|
||||
@ -217,6 +219,9 @@ DEFINE_ADD_FLAGS(GetPPCFeaturesEnumValue, GetPPCFeaturesEnumName, PPCFeatures,
|
||||
#elif defined(CPU_FEATURES_ARCH_S390X)
|
||||
DEFINE_ADD_FLAGS(GetS390XFeaturesEnumValue, GetS390XFeaturesEnumName, S390XFeatures,
|
||||
S390X_LAST_)
|
||||
#elif defined(CPU_FEATURES_ARCH_RISCV)
|
||||
DEFINE_ADD_FLAGS(GetRiscvFeaturesEnumValue, GetRiscvFeaturesEnumName, RiscvFeatures,
|
||||
RISCV_LAST_)
|
||||
#endif
|
||||
|
||||
// Prints a json string with characters escaping.
|
||||
@ -447,6 +452,12 @@ static Node* CreateTree(void)
|
||||
AddMapEntry(root, "model", CreateString(strings.type.platform));
|
||||
AddMapEntry(root, "# processors", CreateInt(strings.num_processors));
|
||||
AddFlags(root, &info.features);
|
||||
#elif defined(CPU_FEATURES_ARCH_RISCV)
|
||||
const RiscvInfo info = GetRiscvInfo();
|
||||
AddMapEntry(root, "arch", CreateString("risc-v"));
|
||||
AddMapEntry(root, "vendor", CreateString(info.vendor));
|
||||
AddMapEntry(root, "microarchitecture", CreateString(info.uarch));
|
||||
AddFlags(root, &info.features);
|
||||
#endif
|
||||
return root;
|
||||
}
|
||||
|
@ -99,3 +99,10 @@ if(PROCESSOR_IS_S390X)
|
||||
target_link_libraries(cpuinfo_s390x_test all_libraries)
|
||||
add_test(NAME cpuinfo_s390x_test COMMAND cpuinfo_s390x_test)
|
||||
endif()
|
||||
##------------------------------------------------------------------------------
|
||||
## cpuinfo_riscv_test
|
||||
if(PROCESSOR_IS_RISCV)
|
||||
add_executable(cpuinfo_riscv_test cpuinfo_riscv_test.cc ../src/impl_riscv_linux.c)
|
||||
target_link_libraries(cpuinfo_riscv_test all_libraries)
|
||||
add_test(NAME cpuinfo_riscv_test COMMAND cpuinfo_riscv_test)
|
||||
endif()
|
@ -0,0 +1,141 @@
|
||||
// SPDX-FileCopyrightText: 2022 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "cpuinfo_riscv.h"
|
||||
#include "filesystem_for_testing.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "hwcaps_for_testing.h"
|
||||
|
||||
namespace cpu_features
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
TEST(CpuinfoRiscvTest, Sipeed_Lichee_RV_FromCpuInfo)
|
||||
{
|
||||
ResetHwcaps();
|
||||
auto& fs = GetEmptyFilesystem();
|
||||
fs.CreateFile("/proc/cpuinfo", R"(processor : 0
|
||||
hart : 0
|
||||
isa : rv64imafdc
|
||||
mmu : sv39
|
||||
uarch : thead,c906)");
|
||||
const auto info = GetRiscvInfo();
|
||||
EXPECT_STREQ(info.uarch, "c906");
|
||||
EXPECT_STREQ(info.vendor, "thead");
|
||||
|
||||
EXPECT_FALSE(info.features.RV32I);
|
||||
EXPECT_TRUE(info.features.RV64I);
|
||||
EXPECT_TRUE(info.features.M);
|
||||
EXPECT_TRUE(info.features.A);
|
||||
EXPECT_TRUE(info.features.F);
|
||||
EXPECT_TRUE(info.features.D);
|
||||
EXPECT_FALSE(info.features.Q);
|
||||
EXPECT_TRUE(info.features.C);
|
||||
}
|
||||
|
||||
// https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/Kendryte-K510-4.17.0.cpuinfo
|
||||
TEST(CpuinfoRiscvTest, Kendryte_K510_FromCpuInfo)
|
||||
{
|
||||
ResetHwcaps();
|
||||
auto& fs = GetEmptyFilesystem();
|
||||
fs.CreateFile("/proc/cpuinfo", R"(
|
||||
hart : 0
|
||||
isa : rv64i2p0m2p0a2p0f2p0d2p0c2p0xv5-0p0
|
||||
mmu : sv39
|
||||
|
||||
hart : 1
|
||||
isa : rv64i2p0m2p0a2p0f2p0d2p0c2p0xv5-0p0
|
||||
mmu : sv39");
|
||||
const auto info = GetRiscvInfo();
|
||||
EXPECT_STREQ(info.uarch, "");
|
||||
EXPECT_STREQ(info.vendor, "");
|
||||
EXPECT_FALSE(info.features.RV32I);
|
||||
EXPECT_TRUE(info.features.RV64I);
|
||||
EXPECT_TRUE(info.features.M);
|
||||
EXPECT_TRUE(info.features.A);
|
||||
EXPECT_TRUE(info.features.F);
|
||||
EXPECT_TRUE(info.features.D);
|
||||
EXPECT_FALSE(info.features.Q);
|
||||
EXPECT_TRUE(info.features.C);
|
||||
}
|
||||
|
||||
// https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/T-Head-C910-5.10.4.cpuinfo
|
||||
TEST(CpuinfoRiscvTest, T_Head_C910_FromCpuInfo) {
|
||||
ResetHwcaps();
|
||||
auto& fs = GetEmptyFilesystem();
|
||||
fs.CreateFile("/proc/cpuinfo", R"(
|
||||
processor : 0
|
||||
hart : 0
|
||||
isa : rv64imafdcsu
|
||||
mmu : sv39
|
||||
cpu-freq : 1.2Ghz
|
||||
cpu-icache : 64KB
|
||||
cpu-dcache : 64KB
|
||||
cpu-l2cache : 2MB
|
||||
cpu-tlb : 1024 4-ways
|
||||
cpu-cacheline : 64Bytes
|
||||
cpu-vector : 0.7.1
|
||||
processor : 1
|
||||
hart : 1
|
||||
isa : rv64imafdcsu
|
||||
mmu : sv39
|
||||
cpu-freq : 1.2Ghz
|
||||
cpu-icache : 64KB
|
||||
cpu-dcache : 64KB
|
||||
cpu-l2cache : 2MB
|
||||
cpu-tlb : 1024 4-ways
|
||||
cpu-cacheline : 64Bytes
|
||||
cpu-vector : 0.7.1");
|
||||
const auto info = GetRiscvInfo();
|
||||
EXPECT_STREQ(info.uarch, "");
|
||||
EXPECT_STREQ(info.vendor, "");
|
||||
EXPECT_FALSE(info.features.RV32I);
|
||||
EXPECT_TRUE(info.features.RV64I);
|
||||
EXPECT_TRUE(info.features.M);
|
||||
EXPECT_TRUE(info.features.A);
|
||||
EXPECT_TRUE(info.features.F);
|
||||
EXPECT_TRUE(info.features.D);
|
||||
EXPECT_FALSE(info.features.Q);
|
||||
EXPECT_TRUE(info.features.C);
|
||||
}
|
||||
TEST(CpuinfoRiscvTest, UnknownFromCpuInfo) {
|
||||
ResetHwcaps();
|
||||
auto& fs = GetEmptyFilesystem();
|
||||
fs.CreateFile("/proc/cpuinfo", R"(
|
||||
processor : 0
|
||||
hart : 2
|
||||
isa : rv64imafdc
|
||||
mmu : sv39
|
||||
uarch : sifive,bullet0
|
||||
processor : 1
|
||||
hart : 1
|
||||
isa : rv64imafdc
|
||||
mmu : sv39
|
||||
uarch : sifive,bullet0
|
||||
processor : 2
|
||||
hart : 3
|
||||
isa : rv64imafdc
|
||||
mmu : sv39
|
||||
uarch : sifive,bullet0
|
||||
processor : 3
|
||||
hart : 4
|
||||
isa : rv64imafdc
|
||||
mmu : sv39
|
||||
uarch : sifive,bullet0)");
|
||||
const auto info = GetRiscvInfo();
|
||||
EXPECT_STREQ(info.uarch, "bullet0");
|
||||
EXPECT_STREQ(info.vendor, "sifive");
|
||||
|
||||
EXPECT_FALSE(info.features.RV32I);
|
||||
EXPECT_TRUE(info.features.RV64I);
|
||||
EXPECT_TRUE(info.features.M);
|
||||
EXPECT_TRUE(info.features.A);
|
||||
EXPECT_TRUE(info.features.F);
|
||||
EXPECT_TRUE(info.features.D);
|
||||
EXPECT_FALSE(info.features.Q);
|
||||
EXPECT_TRUE(info.features.C);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace cpu_features
|
@ -23,7 +23,6 @@
|
||||
\li \subpage volk_gnsssdr_8ic_magnitude_squared_8i
|
||||
\li \subpage volk_gnsssdr_8ic_x2_dot_prod_8ic
|
||||
\li \subpage volk_gnsssdr_8ic_x2_multiply_8ic
|
||||
\li \subpage volk_gnsssdr_8ic_s8ic_multiply_8ic
|
||||
\li \subpage volk_gnsssdr_8i_accumulator_s8i
|
||||
\li \subpage volk_gnsssdr_8i_index_max_16u
|
||||
\li \subpage volk_gnsssdr_8i_max_s8i
|
||||
|
@ -1,27 +0,0 @@
|
||||
#
|
||||
# ORC implementation: calculates the conjugate of a 16 bits vector
|
||||
#
|
||||
# Andres Cecilia, 2014. a.cecilia.luque(at)gmail.com
|
||||
#
|
||||
# ORC code that calculates the conjugate of a
|
||||
# 16 bits vector (8 bits the real part and 8 bits the imaginary part)
|
||||
# result = (real*real) + (imag*imag)
|
||||
#
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
#
|
||||
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
# This file is part of GNSS-SDR.
|
||||
#
|
||||
# Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
.function volk_gnsssdr_8ic_conjugate_8ic_a_orc_impl
|
||||
.source 2 src1
|
||||
.dest 2 dst
|
||||
.temp 2 merged
|
||||
mergebw merged, 1, -1
|
||||
x2 mullb dst, merged, src1
|
@ -1,39 +0,0 @@
|
||||
#
|
||||
# ORC implementation: multiplies a group of 16 bits vectors by one constant vector
|
||||
#
|
||||
# Andres Cecilia, 2014. a.cecilia.luque(at)gmail.com
|
||||
#
|
||||
#
|
||||
# ORC code that multiplies a group of 16 bits vectors
|
||||
# (8 bits the real part and 8 bits the imaginary part) by one constant vector
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
#
|
||||
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
# This file is part of GNSS-SDR.
|
||||
#
|
||||
# Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
.function volk_gnsssdr_8ic_s8ic_multiply_8ic_a_orc_impl
|
||||
.source 2 src1
|
||||
.param 2 src2real
|
||||
.param 2 src2imag
|
||||
.dest 2 dst
|
||||
.temp 2 iqprod
|
||||
.temp 1 real
|
||||
.temp 1 imag
|
||||
.temp 1 rr
|
||||
.temp 1 ii
|
||||
.temp 1 ri
|
||||
.temp 1 ir
|
||||
x2 mullb iqprod, src1, src2real
|
||||
splitwb ir, rr, iqprod
|
||||
x2 mullb iqprod, src1, src2imag
|
||||
splitwb ii, ri, iqprod
|
||||
subb real, rr, ii
|
||||
addb imag, ri, ir
|
||||
mergebw dst, real, imag
|
@ -324,16 +324,6 @@ static inline void volk_gnsssdr_8ic_conjugate_8ic_a_sse3(lv_8sc_t* cVector, cons
|
||||
#endif /* LV_HAVE_SSE3 */
|
||||
|
||||
|
||||
#ifdef LV_HAVE_ORC
|
||||
|
||||
extern void volk_gnsssdr_8ic_conjugate_8ic_a_orc_impl(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points);
|
||||
static inline void volk_gnsssdr_8ic_conjugate_8ic_u_orc(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points)
|
||||
{
|
||||
volk_gnsssdr_8ic_conjugate_8ic_a_orc_impl(cVector, aVector, num_points);
|
||||
}
|
||||
#endif /* LV_HAVE_ORC */
|
||||
|
||||
|
||||
#ifdef LV_HAVE_NEON
|
||||
#include <arm_neon.h>
|
||||
|
||||
|
@ -1,205 +0,0 @@
|
||||
/*!
|
||||
* \file volk_gnsssdr_8ic_s8ic_multiply_8ic.h
|
||||
* \brief VOLK_GNSSSDR kernel: multiplies a group of 16 bits vectors by one constant vector.
|
||||
* \authors <ul>
|
||||
* <li> Andres Cecilia, 2014. a.cecilia.luque(at)gmail.com
|
||||
* </ul>
|
||||
*
|
||||
* VOLK_GNSSSDR kernel that multiplies a group of 16 bits vectors
|
||||
* (8 bits the real part and 8 bits the imaginary part) by one constant vector
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \page volk_gnsssdr_8ic_s8ic_multiply_8ic
|
||||
*
|
||||
* \b Overview
|
||||
*
|
||||
* Multiplies the input vector by a scalar and stores the results in the third vector
|
||||
*
|
||||
* <b>Dispatcher Prototype</b>
|
||||
* \code
|
||||
* void volk_gnsssdr_8ic_s8ic_multiply_8ic(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t scalar, unsigned int num_points);
|
||||
* \endcode
|
||||
*
|
||||
* \b Inputs
|
||||
* \li aVector: The vector to be multiplied.
|
||||
* \li scalar The complex scalar to multiply \p aVector
|
||||
* \li num_points: The number of complex values in \p aVector to be multiplied by \p scalar and stored into \p cVector.
|
||||
*
|
||||
* \b Outputs
|
||||
* \li cVector: The vector where the results will be stored
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_volk_gnsssdr_8ic_s8ic_multiply_8ic_H
|
||||
#define INCLUDED_volk_gnsssdr_8ic_s8ic_multiply_8ic_H
|
||||
|
||||
#include <volk_gnsssdr/volk_gnsssdr_complex.h>
|
||||
|
||||
#ifdef LV_HAVE_SSE3
|
||||
#include <pmmintrin.h>
|
||||
|
||||
static inline void volk_gnsssdr_8ic_s8ic_multiply_8ic_u_sse3(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t scalar, unsigned int num_points)
|
||||
{
|
||||
unsigned int number = 0;
|
||||
const unsigned int sse_iters = num_points / 8;
|
||||
|
||||
__m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc;
|
||||
|
||||
lv_8sc_t* c = cVector;
|
||||
const lv_8sc_t* a = aVector;
|
||||
|
||||
mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
|
||||
|
||||
y = _mm_set1_epi16(*(short*)&scalar);
|
||||
imagy = _mm_srli_si128(y, 1);
|
||||
imagy = _mm_and_si128(imagy, mult1);
|
||||
realy = _mm_and_si128(y, mult1);
|
||||
|
||||
for (; number < sse_iters; number++)
|
||||
{
|
||||
x = _mm_lddqu_si128((__m128i*)a);
|
||||
|
||||
imagx = _mm_srli_si128(x, 1);
|
||||
imagx = _mm_and_si128(imagx, mult1);
|
||||
realx = _mm_and_si128(x, mult1);
|
||||
|
||||
realx_mult_realy = _mm_mullo_epi16(realx, realy);
|
||||
imagx_mult_imagy = _mm_mullo_epi16(imagx, imagy);
|
||||
realx_mult_imagy = _mm_mullo_epi16(realx, imagy);
|
||||
imagx_mult_realy = _mm_mullo_epi16(imagx, realy);
|
||||
|
||||
realc = _mm_sub_epi16(realx_mult_realy, imagx_mult_imagy);
|
||||
realc = _mm_and_si128(realc, mult1);
|
||||
imagc = _mm_add_epi16(realx_mult_imagy, imagx_mult_realy);
|
||||
imagc = _mm_and_si128(imagc, mult1);
|
||||
imagc = _mm_slli_si128(imagc, 1);
|
||||
|
||||
totalc = _mm_or_si128(realc, imagc);
|
||||
|
||||
_mm_storeu_si128((__m128i*)c, totalc);
|
||||
|
||||
a += 8;
|
||||
c += 8;
|
||||
}
|
||||
|
||||
for (number = sse_iters * 8; number < num_points; ++number)
|
||||
{
|
||||
*c++ = (*a++) * scalar;
|
||||
}
|
||||
}
|
||||
#endif /* LV_HAVE_SSE3 */
|
||||
|
||||
|
||||
#ifdef LV_HAVE_GENERIC
|
||||
|
||||
static inline void volk_gnsssdr_8ic_s8ic_multiply_8ic_generic(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t scalar, unsigned int num_points)
|
||||
{
|
||||
/*lv_8sc_t* cPtr = cVector;
|
||||
const lv_8sc_t* aPtr = aVector;
|
||||
|
||||
for (int i = 0; i<num_points; ++i)
|
||||
{
|
||||
*cPtr++ = (*aPtr++) * scalar;
|
||||
}*/
|
||||
|
||||
lv_8sc_t* cPtr = cVector;
|
||||
const lv_8sc_t* aPtr = aVector;
|
||||
unsigned int number = num_points;
|
||||
|
||||
// unwrap loop
|
||||
while (number >= 8)
|
||||
{
|
||||
*cPtr++ = (*aPtr++) * scalar;
|
||||
*cPtr++ = (*aPtr++) * scalar;
|
||||
*cPtr++ = (*aPtr++) * scalar;
|
||||
*cPtr++ = (*aPtr++) * scalar;
|
||||
*cPtr++ = (*aPtr++) * scalar;
|
||||
*cPtr++ = (*aPtr++) * scalar;
|
||||
*cPtr++ = (*aPtr++) * scalar;
|
||||
*cPtr++ = (*aPtr++) * scalar;
|
||||
number -= 8;
|
||||
}
|
||||
|
||||
// clean up any remaining
|
||||
while (number-- > 0)
|
||||
*cPtr++ = *aPtr++ * scalar;
|
||||
}
|
||||
#endif /* LV_HAVE_GENERIC */
|
||||
|
||||
|
||||
#ifdef LV_HAVE_SSE3
|
||||
#include <pmmintrin.h>
|
||||
|
||||
static inline void volk_gnsssdr_8ic_s8ic_multiply_8ic_a_sse3(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t scalar, unsigned int num_points)
|
||||
{
|
||||
unsigned int number = 0;
|
||||
const unsigned int sse_iters = num_points / 8;
|
||||
|
||||
__m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc;
|
||||
|
||||
lv_8sc_t* c = cVector;
|
||||
const lv_8sc_t* a = aVector;
|
||||
|
||||
mult1 = _mm_set_epi8(0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF);
|
||||
|
||||
y = _mm_set1_epi16(*(short*)&scalar);
|
||||
imagy = _mm_srli_si128(y, 1);
|
||||
imagy = _mm_and_si128(imagy, mult1);
|
||||
realy = _mm_and_si128(y, mult1);
|
||||
|
||||
for (; number < sse_iters; number++)
|
||||
{
|
||||
x = _mm_load_si128((__m128i*)a);
|
||||
|
||||
imagx = _mm_srli_si128(x, 1);
|
||||
imagx = _mm_and_si128(imagx, mult1);
|
||||
realx = _mm_and_si128(x, mult1);
|
||||
|
||||
realx_mult_realy = _mm_mullo_epi16(realx, realy);
|
||||
imagx_mult_imagy = _mm_mullo_epi16(imagx, imagy);
|
||||
realx_mult_imagy = _mm_mullo_epi16(realx, imagy);
|
||||
imagx_mult_realy = _mm_mullo_epi16(imagx, realy);
|
||||
|
||||
realc = _mm_sub_epi16(realx_mult_realy, imagx_mult_imagy);
|
||||
realc = _mm_and_si128(realc, mult1);
|
||||
imagc = _mm_add_epi16(realx_mult_imagy, imagx_mult_realy);
|
||||
imagc = _mm_and_si128(imagc, mult1);
|
||||
imagc = _mm_slli_si128(imagc, 1);
|
||||
|
||||
totalc = _mm_or_si128(realc, imagc);
|
||||
|
||||
_mm_store_si128((__m128i*)c, totalc);
|
||||
|
||||
a += 8;
|
||||
c += 8;
|
||||
}
|
||||
|
||||
for (number = sse_iters * 8; number < num_points; ++number)
|
||||
{
|
||||
*c++ = (*a++) * scalar;
|
||||
}
|
||||
}
|
||||
#endif /* LV_HAVE_SSE3 */
|
||||
|
||||
|
||||
#ifdef LV_HAVE_ORC
|
||||
|
||||
extern void volk_gnsssdr_8ic_s8ic_multiply_8ic_a_orc_impl(lv_8sc_t* cVector, const lv_8sc_t* aVector, const char scalarreal, const char scalarimag, unsigned int num_points);
|
||||
static inline void volk_gnsssdr_8ic_s8ic_multiply_8ic_u_orc(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t scalar, unsigned int num_points)
|
||||
{
|
||||
volk_gnsssdr_8ic_s8ic_multiply_8ic_a_orc_impl(cVector, aVector, lv_creal(scalar), lv_cimag(scalar), num_points);
|
||||
}
|
||||
#endif /* LV_HAVE_ORC */
|
||||
|
||||
#endif /* INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_H */
|
@ -51,7 +51,8 @@ std::vector<volk_gnsssdr_test_case_t> init_test_list(volk_gnsssdr_test_params_t
|
||||
volk_gnsssdr_test_params_t test_params_inacc2 = volk_gnsssdr_test_params_t(2e-1, test_params.scalar(),
|
||||
test_params.vlen(), test_params.iter(), test_params.benchmark_mode(), test_params.kernel_regex());
|
||||
|
||||
std::vector<volk_gnsssdr_test_case_t> test_cases;
|
||||
std::vector<volk_gnsssdr_test_case_t>
|
||||
test_cases;
|
||||
|
||||
QA(VOLK_INIT_TEST(volk_gnsssdr_8i_accumulator_s8i, test_params_more_iters))
|
||||
QA(VOLK_INIT_TEST(volk_gnsssdr_8i_index_max_16u, test_params_more_iters))
|
||||
@ -61,7 +62,6 @@ std::vector<volk_gnsssdr_test_case_t> init_test_list(volk_gnsssdr_test_params_t
|
||||
QA(VOLK_INIT_TEST(volk_gnsssdr_8ic_magnitude_squared_8i, test_params_more_iters))
|
||||
QA(VOLK_INIT_TEST(volk_gnsssdr_8ic_x2_dot_prod_8ic, test_params))
|
||||
QA(VOLK_INIT_TEST(volk_gnsssdr_8ic_x2_multiply_8ic, test_params))
|
||||
QA(VOLK_INIT_TEST(volk_gnsssdr_8ic_s8ic_multiply_8ic, test_params))
|
||||
QA(VOLK_INIT_TEST(volk_gnsssdr_8u_x2_multiply_8u, test_params_more_iters))
|
||||
QA(VOLK_INIT_TEST(volk_gnsssdr_64f_accumulator_64f, test_params))
|
||||
QA(VOLK_INIT_TEST(volk_gnsssdr_32f_sincos_32fc, test_params_inacc))
|
||||
|
@ -26,6 +26,10 @@
|
||||
#include "cpuinfo_mips.h"
|
||||
#elif defined(CPU_FEATURES_ARCH_PPC)
|
||||
#include "cpuinfo_ppc.h"
|
||||
#elif defined(CPU_FEATURES_ARCH_S390X)
|
||||
#include "cpuinfo_s390x.h"
|
||||
#elif defined(CPU_FEATURES_ARCH_RISCV)
|
||||
#include "cpuinfo_riscv.h"
|
||||
#endif
|
||||
|
||||
// This is required for MSVC
|
||||
@ -44,6 +48,22 @@ static int i_can_has_${arch.name} (void) {
|
||||
%if "neon" in arch.name:
|
||||
#if defined(CPU_FEATURES_ARCH_ARM)
|
||||
if (GetArmInfo().features.${check} == 0){ return 0; }
|
||||
#endif
|
||||
%elif "mips" in arch.name:
|
||||
#if defined(CPU_FEATURES_ARCH_MIPS)
|
||||
if (GetMipsInfo().features.${check} == 0){ return 0; }
|
||||
#endif
|
||||
%elif "ppc" in arch.name:
|
||||
#if defined(CPU_FEATURES_ARCH_PPC)
|
||||
if (GetPPCInfo().features.${check} == 0){ return 0; }
|
||||
#endif
|
||||
%elif "s390x" in arch.name:
|
||||
#if defined(CPU_FEATURES_ARCH_S390X)
|
||||
if (GetS390XInfo().features.${check} == 0){ return 0; }
|
||||
#endif
|
||||
%elif "riscv" in arch.name:
|
||||
#if defined(CPU_FEATURES_ARCH_RISCV)
|
||||
if (GetRiscvInfo().features.${check} == 0){ return 0; }
|
||||
#endif
|
||||
%else:
|
||||
#if defined(CPU_FEATURES_ARCH_X86)
|
||||
|
@ -100,19 +100,6 @@ hybrid_observables_gs::hybrid_observables_gs(const Obs_Conf &conf_)
|
||||
d_channel_last_pseudorange_smooth = std::vector<double>(d_nchannels_out, 0.0);
|
||||
d_channel_last_carrier_phase_rads = std::vector<double>(d_nchannels_out, 0.0);
|
||||
|
||||
d_mapStringValues["1C"] = evGPS_1C;
|
||||
d_mapStringValues["2S"] = evGPS_2S;
|
||||
d_mapStringValues["L5"] = evGPS_L5;
|
||||
d_mapStringValues["1B"] = evGAL_1B;
|
||||
d_mapStringValues["5X"] = evGAL_5X;
|
||||
d_mapStringValues["E6"] = evGAL_E6;
|
||||
d_mapStringValues["7X"] = evGAL_7X;
|
||||
d_mapStringValues["1G"] = evGLO_1G;
|
||||
d_mapStringValues["2G"] = evGLO_2G;
|
||||
d_mapStringValues["B1"] = evBDS_B1;
|
||||
d_mapStringValues["B2"] = evBDS_B2;
|
||||
d_mapStringValues["B3"] = evBDS_B3;
|
||||
|
||||
d_SourceTagTimestamps = std::vector<std::queue<GnssTime>>(d_nchannels_out);
|
||||
|
||||
set_tag_propagation_policy(TPP_DONT); // no tag propagation, the time tag will be adjusted and regenerated in work()
|
||||
@ -581,44 +568,11 @@ void hybrid_observables_gs::smooth_pseudoranges(std::vector<Gnss_Synchro> &data)
|
||||
if (it->Flag_valid_pseudorange)
|
||||
{
|
||||
// 0. get wavelength for the current signal
|
||||
double wavelength_m = 0;
|
||||
switch (d_mapStringValues[it->Signal])
|
||||
double wavelength_m = 0.0;
|
||||
const auto it_freq_map = SIGNAL_FREQ_MAP.find(std::string(it->Signal, 2));
|
||||
if (it_freq_map != SIGNAL_FREQ_MAP.cend())
|
||||
{
|
||||
case evGPS_1C:
|
||||
case evSBAS_1C:
|
||||
case evGAL_1B:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ1;
|
||||
break;
|
||||
case evGPS_L5:
|
||||
case evGAL_5X:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ5;
|
||||
break;
|
||||
case evGAL_E6:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ6;
|
||||
break;
|
||||
case evGAL_7X:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ7;
|
||||
break;
|
||||
case evGPS_2S:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ2;
|
||||
break;
|
||||
case evBDS_B3:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ3_BDS;
|
||||
break;
|
||||
case evGLO_1G:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ1_GLO;
|
||||
break;
|
||||
case evGLO_2G:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ2_GLO;
|
||||
break;
|
||||
case evBDS_B1:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ1_BDS;
|
||||
break;
|
||||
case evBDS_B2:
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / FREQ2_BDS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
wavelength_m = SPEED_OF_LIGHT_M_S / it_freq_map->second;
|
||||
}
|
||||
|
||||
// todo: propagate the PLL lock status in Gnss_Synchro
|
||||
|
@ -29,9 +29,8 @@
|
||||
#include <cstddef> // for size_t
|
||||
#include <cstdint> // for int32_t
|
||||
#include <fstream> // for std::ofstream
|
||||
#include <map> // for std::map
|
||||
#include <memory> // for std::shared, std:unique_ptr
|
||||
#include <queue>
|
||||
#include <queue> // for std::queue
|
||||
#include <string> // for std::string
|
||||
#include <typeinfo> // for typeid
|
||||
#include <vector> // for std::vector
|
||||
@ -84,24 +83,6 @@ private:
|
||||
|
||||
Obs_Conf d_conf;
|
||||
|
||||
enum StringValue_
|
||||
{
|
||||
evGPS_1C,
|
||||
evGPS_2S,
|
||||
evGPS_L5,
|
||||
evSBAS_1C,
|
||||
evGAL_1B,
|
||||
evGAL_5X,
|
||||
evGAL_E6,
|
||||
evGAL_7X,
|
||||
evGLO_1G,
|
||||
evGLO_2G,
|
||||
evBDS_B1,
|
||||
evBDS_B2,
|
||||
evBDS_B3
|
||||
};
|
||||
std::map<std::string, StringValue_> d_mapStringValues;
|
||||
|
||||
std::unique_ptr<Gnss_circular_deque<Gnss_Synchro>> d_gnss_synchro_history; // Tracking observable history
|
||||
|
||||
boost::circular_buffer<uint64_t> d_Rx_clock_buffer; // time history
|
||||
|
@ -44,6 +44,7 @@ ZmqSignalSource::ZmqSignalSource(const ConfigurationInterface* configuration,
|
||||
LOG(INFO) << "Connecting to ZMQ pub at " << endpoint;
|
||||
// work around gnuradio interface deficiency
|
||||
d_source_block = gr::zeromq::sub_source::make(d_item_size, vlen, const_cast<char*>(endpoint.data()), timeout_ms, pass_tags, hwm);
|
||||
d_source_block->set_tag_propagation_policy(gr::block::TPP_DONT); // GNSS-SDR doesn't do well with tags/
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -94,9 +95,13 @@ auto ZmqSignalSource::get_right_block() -> gr::basic_block_sptr
|
||||
auto result = gr::basic_block_sptr();
|
||||
|
||||
if (d_vec_block)
|
||||
result = d_vec_block; // NOLINT
|
||||
{
|
||||
result = d_vec_block;
|
||||
}
|
||||
else
|
||||
result = d_source_block; // NOLINT
|
||||
{
|
||||
result = d_source_block;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#ifndef GNSS_SDR_FPGA_SWITCH_H
|
||||
#define GNSS_SDR_FPGA_SWITCH_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
/** \addtogroup Signal_Source
|
||||
|
@ -664,6 +664,7 @@ void galileo_telemetry_decoder_gs::set_satellite(const Gnss_Satellite &satellite
|
||||
d_received_tow_ms = std::numeric_limits<uint32_t>::max();
|
||||
d_E6_TOW_set = false;
|
||||
d_valid_timetag = false;
|
||||
d_inav_nav.init_PRN(d_satellite.get_PRN());
|
||||
if (d_there_are_e6_channels)
|
||||
{
|
||||
const std::pair<uint32_t, uint64_t> tow_and_sample{d_received_tow_ms, 0ULL};
|
||||
@ -684,6 +685,7 @@ void galileo_telemetry_decoder_gs::reset()
|
||||
d_fnav_nav.set_flag_TOW_set(false);
|
||||
d_inav_nav.set_flag_TOW_set(false);
|
||||
d_inav_nav.set_TOW0_flag(false);
|
||||
d_inav_nav.init_PRN(d_satellite.get_PRN());
|
||||
d_last_valid_preamble = d_symbol_counter;
|
||||
d_sent_tlm_failed_msg = false;
|
||||
d_E6_TOW_set = false;
|
||||
|
@ -149,7 +149,7 @@ std::shared_ptr<Galileo_HAS_data> galileo_e6_has_msg_receiver::process_test_page
|
||||
{
|
||||
d_HAS_data.has_status = d_current_has_status;
|
||||
d_HAS_data.message_id = d_current_message_id;
|
||||
d_HAS_data.tow = tow - static_cast<uint32_t>(std::remainder(tow, 3600)) + d_HAS_data.header.toh;
|
||||
d_HAS_data.tow = tow;
|
||||
auto has_data_ptr = std::make_shared<Galileo_HAS_data>(d_HAS_data);
|
||||
d_new_message = false;
|
||||
d_printed_mids[d_current_message_id] = true;
|
||||
@ -201,7 +201,7 @@ void galileo_e6_has_msg_receiver::msg_handler_galileo_e6_has(const pmt::pmt_t& m
|
||||
{
|
||||
d_HAS_data.has_status = d_current_has_status;
|
||||
d_HAS_data.message_id = d_current_message_id;
|
||||
d_HAS_data.tow = tow - static_cast<uint32_t>(std::remainder(tow, 3600)) + d_HAS_data.header.toh;
|
||||
d_HAS_data.tow = tow;
|
||||
d_printed_mids[d_current_message_id] = true;
|
||||
d_printed_timestamps[d_current_message_id] = timestamp;
|
||||
auto has_data_ptr = std::make_shared<Galileo_HAS_data>(d_HAS_data);
|
||||
@ -699,8 +699,7 @@ void galileo_e6_has_msg_receiver::read_MT1_body(const std::string& message_body)
|
||||
|
||||
// count satellites in the mask
|
||||
std::bitset<HAS_MSG_SATELLITE_MASK_LENGTH> satellite_mask_bits(satellite_mask);
|
||||
std::string satellite_mask_string = satellite_mask_bits.to_string();
|
||||
int number_sats_this_gnss_id = std::count(satellite_mask_string.begin(), satellite_mask_string.end(), '1');
|
||||
int number_sats_this_gnss_id = satellite_mask_bits.count();
|
||||
|
||||
d_HAS_data.satellite_submask[i] = read_has_message_body_uint64(message.substr(0, number_sats_this_gnss_id));
|
||||
message = std::string(message.begin() + number_sats_this_gnss_id, message.end());
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -53,9 +53,12 @@ public:
|
||||
Galileo_HAS_data() = default;
|
||||
|
||||
std::vector<std::string> get_signals_in_mask(uint8_t nsys) const; //!< Get a vector of Nsys std::string with signals in mask for system nsys, with 0 <= nsys < Nsys
|
||||
std::vector<std::string> get_signals_in_mask(const std::string& system) const; //!< Get a vector of Nsys std::string with signals in mask for system ("GPS"/"Galileo")
|
||||
std::vector<std::string> get_systems_string() const; //!< Get Nsys system name strings
|
||||
std::vector<std::string> get_systems_subset_string() const; //!< Get Nsat system name strings present in clock corrections subset
|
||||
std::vector<std::vector<float>> get_code_bias_m() const; //!< Get Nsat x Ncodes code biases in [m]
|
||||
std::vector<std::vector<float>> get_phase_bias_cycle() const; //!< Get Nsat x Nphases phase biases in [cycles]
|
||||
std::vector<std::vector<float>> get_delta_clock_subset_correction_m() const; //!< Get Nsys_sub vectors with Nsat_sub delta clock C0 corrections in [m]
|
||||
std::vector<float> get_delta_radial_m() const; //!< Get Nsat delta radial corrections in [m]
|
||||
std::vector<float> get_delta_radial_m(uint8_t nsys) const; //!< Get delta radial corrections in [m] for system nsys, with 0 <= nsys < Nsys
|
||||
std::vector<float> get_delta_in_track_m() const; //!< Get Nsat delta in-track corrections in [m]
|
||||
@ -64,13 +67,24 @@ public:
|
||||
std::vector<float> get_delta_cross_track_m(uint8_t nsys) const; //!< Get delta cross-track corrections in [m] for system nsys, with 0 <= nsys < Nsys
|
||||
std::vector<float> get_delta_clock_correction_m() const; //!< Get Nsat delta clock C0 corrections in [m]
|
||||
std::vector<float> get_delta_clock_correction_m(uint8_t nsys) const; //!< Get delta clock C0 corrections in [m] for system nsys, with 0 <= nsys < Nsys
|
||||
std::vector<float> get_delta_clock_subset_correction_m(uint8_t nsys) const; //!< Get delta clock C0 subset corrections in [m] for system nsys, with 0 <= nsys < Nsys
|
||||
std::vector<int> get_PRNs_in_mask(uint8_t nsys) const; //!< Get PRNs in mask for system nsys, with 0 <= nsys < Nsys
|
||||
std::vector<int> get_PRNs_in_mask(const std::string& system) const; //!< Get PRNs in mask for system ("GPS"/"Galileo")
|
||||
std::vector<int> get_PRNs_in_submask(uint8_t nsys) const; //!< Get PRNs in submask for system nsys, with 0 <= nsys < Nsys
|
||||
std::vector<uint16_t> get_gnss_iod(uint8_t nsys) const; //!< Get GNSS IODs for for system nsys, with 0 <= nsys < Nsys
|
||||
std::vector<uint8_t> get_num_satellites() const; //!< Get Nsys number of satellites
|
||||
std::vector<uint8_t> get_num_subset_satellites() const; //!< Get Nsys_sub number of satellites
|
||||
float get_code_bias_m(const std::string& signal, int PRN) const; //!< Get code bias in [m] for a given signal and PRN satellite
|
||||
float get_phase_bias_cycle(const std::string& signal, int PRN) const; //!< Get phase bias in [cycles] for a given signal and PRN satellite
|
||||
float get_delta_radial_m(const std::string& system, int prn) const; //!< Get orbital radial correction in [m] for a given system ("GPS"/"Galileo") and PRN
|
||||
float get_delta_in_track_m(const std::string& system, int prn) const; //!< Get orbital in_track correction in [m] for a given system ("GPS"/"Galileo") and PRN
|
||||
float get_delta_cross_track_m(const std::string& system, int prn) const; //!< Get orbital cross_track correction in [m] for a given system ("GPS"/"Galileo") and PRN
|
||||
float get_clock_correction_mult_m(const std::string& system, int prn) const; //!< Get clock correction in [m], already multiplied by its Delta Clock Multiplier, for a given system ("GPS"/"Galileo") and PRN
|
||||
float get_clock_subset_correction_mult_m(const std::string& system, int prn) const; //!< Get clock correction subset in [m], already multiplied by its Delta Clock Multiplier
|
||||
uint16_t get_nsat() const; //!< Get total number of satellites with corrections
|
||||
uint16_t get_nsat_sub() const; //!< Get number of satellites in clock subset corrections
|
||||
uint16_t get_validity_interval_s(uint8_t validity_interval_index) const; //!< Get validity interval in [s] from the validity_interval_index
|
||||
uint16_t get_gnss_iod(const std::string& system, int prn) const; //!< Get GNSS IOD from a given system ("GPS"/"Galileo") and PRN
|
||||
uint8_t get_gnss_id(int nsat) const; //!< Get GNSS ID from the nsat satellite
|
||||
|
||||
// Mask
|
||||
|
@ -19,6 +19,9 @@
|
||||
#ifndef GNSS_SDR_GNSS_FREQUENCIES_H
|
||||
#define GNSS_SDR_GNSS_FREQUENCIES_H
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
/** \addtogroup Core
|
||||
* \{ */
|
||||
/** \addtogroup System_Parameters
|
||||
@ -41,6 +44,21 @@ constexpr double FREQ1_BDS = 1.561098e9; //!< BeiDou B1 frequency (Hz)
|
||||
constexpr double FREQ2_BDS = 1.20714e9; //!< BeiDou B2 frequency (Hz)
|
||||
constexpr double FREQ3_BDS = 1.26852e9; //!< BeiDou B3 frequency (Hz)
|
||||
|
||||
const std::unordered_map<std::string, double> SIGNAL_FREQ_MAP = {
|
||||
{"1C", FREQ1},
|
||||
{"2S", FREQ2},
|
||||
{"L5", FREQ5},
|
||||
{"1B", FREQ1},
|
||||
{"5X", FREQ5},
|
||||
{"E6", FREQ6},
|
||||
{"7X", FREQ7},
|
||||
{"1G", FREQ1_GLO},
|
||||
{"2G", FREQ2_GLO},
|
||||
{"B1", FREQ1_BDS},
|
||||
{"B2", FREQ2_BDS},
|
||||
{"B3", FREQ3_BDS},
|
||||
};
|
||||
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
|
@ -11,7 +11,7 @@
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
|
||||
* Copyright (C) 2010-2013 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
@ -65,9 +65,11 @@ Concurrent_Map<Gps_Acq_Assist> global_gps_acq_assist_map;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
const std::string intro_help(
|
||||
std::string("\nGNSS-SDR is an Open Source GNSS Software Defined Receiver\n") +
|
||||
"Copyright (C) 2010-2022 (see AUTHORS file for a list of contributors)\n" +
|
||||
"Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors)\n" +
|
||||
"This program comes with ABSOLUTELY NO WARRANTY;\n" +
|
||||
"See COPYING file to see a copy of the General Public License\n \n");
|
||||
|
||||
@ -76,6 +78,13 @@ int main(int argc, char** argv)
|
||||
gflags::SetVersionString(gnss_sdr_version);
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
std::cout << "Initializing GNSS-SDR v" << gnss_sdr_version << " ... Please wait.\n";
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
std::cout << "GNSS-SDR program ended.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if CUDA_GPU_ACCEL
|
||||
// Reset the device
|
||||
@ -99,6 +108,8 @@ int main(int argc, char** argv)
|
||||
<< "Use gnss-sdr --log_dir=/path/to/log to change that.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
const fs::path p(FLAGS_log_dir);
|
||||
if (!fs::exists(p))
|
||||
@ -116,6 +127,14 @@ int main(int argc, char** argv)
|
||||
}
|
||||
std::cout << "Logging will be written at " << FLAGS_log_dir << '\n';
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
std::cerr << "Could not create the " << FLAGS_log_dir << " folder. GNSS-SDR program ended.\n";
|
||||
gflags::ShutDownCommandLineFlags();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> start;
|
||||
@ -132,9 +151,7 @@ int main(int argc, char** argv)
|
||||
catch (const boost::thread_resource_error& e)
|
||||
{
|
||||
std::cerr << "Failed to create boost thread.\n";
|
||||
gflags::ShutDownCommandLineFlags();
|
||||
std::cout << "GNSS-SDR program ended.\n";
|
||||
return 1;
|
||||
return_code = 1;
|
||||
}
|
||||
catch (const boost::exception& e)
|
||||
{
|
||||
@ -147,9 +164,7 @@ int main(int argc, char** argv)
|
||||
{
|
||||
std::cerr << "Boost exception: " << boost::diagnostic_information(e) << '\n';
|
||||
}
|
||||
gflags::ShutDownCommandLineFlags();
|
||||
std::cout << "GNSS-SDR program ended.\n";
|
||||
return 1;
|
||||
return_code = 1;
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
@ -162,9 +177,7 @@ int main(int argc, char** argv)
|
||||
{
|
||||
std::cerr << "C++ Standard Library exception: " << ex.what() << '\n';
|
||||
}
|
||||
gflags::ShutDownCommandLineFlags();
|
||||
std::cout << "GNSS-SDR program ended.\n";
|
||||
return 1;
|
||||
return_code = 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -177,9 +190,7 @@ int main(int argc, char** argv)
|
||||
{
|
||||
std::cerr << "Unexpected catch. This should not happen.\n";
|
||||
}
|
||||
gflags::ShutDownCommandLineFlags();
|
||||
std::cout << "GNSS-SDR program ended.\n";
|
||||
return 1;
|
||||
return_code = 1;
|
||||
}
|
||||
|
||||
// report the elapsed time
|
||||
|
@ -37,12 +37,6 @@ if(NOT GOOGLETEST_FOUND)
|
||||
if(CMAKE_GENERATOR STREQUAL Xcode)
|
||||
set(GTEST_BUILD_COMMAND "xcodebuild" "-configuration" $<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel> "-target" "gtest_main")
|
||||
endif()
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) OR
|
||||
(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))
|
||||
set(GOOGLETEST_GIT_TAG v${GNSSSDR_GTEST_LOCAL_VERSION})
|
||||
else()
|
||||
set(GOOGLETEST_GIT_TAG release-${GNSSSDR_GTEST_LOCAL_VERSION})
|
||||
endif()
|
||||
if(GNSSSDR_GTEST_LOCAL_VERSION VERSION_LESS 1.12.0)
|
||||
set(DEBUG_DECORATION "d")
|
||||
else()
|
||||
@ -51,7 +45,7 @@ if(NOT GOOGLETEST_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.2)
|
||||
ExternalProject_Add(gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
|
||||
GIT_REPOSITORY https://github.com/google/googletest
|
||||
GIT_TAG ${GOOGLETEST_GIT_TAG}
|
||||
GIT_TAG v${GNSSSDR_GTEST_LOCAL_VERSION}
|
||||
SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gtest/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
|
||||
BINARY_DIR ${GNSSSDR_BINARY_DIR}/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
|
||||
CMAKE_ARGS ${GTEST_COMPILER}
|
||||
@ -80,7 +74,7 @@ if(NOT GOOGLETEST_FOUND)
|
||||
endif()
|
||||
ExternalProject_Add(gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
|
||||
GIT_REPOSITORY https://github.com/google/googletest
|
||||
GIT_TAG ${GOOGLETEST_GIT_TAG}
|
||||
GIT_TAG v${GNSSSDR_GTEST_LOCAL_VERSION}
|
||||
SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gtest/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
|
||||
BINARY_DIR ${GNSSSDR_BINARY_DIR}/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
|
||||
CMAKE_ARGS ${GTEST_COMPILER}
|
||||
@ -369,12 +363,14 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA)
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.17.0)
|
||||
set(GNSSTK_PATCH_COMMAND
|
||||
cd ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION} &&
|
||||
${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/CMakeLists.txt < ${GNSSSDR_SOURCE_DIR}/src/tests/data/gnsstk_static14.patch
|
||||
${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/CMakeLists.txt < ${GNSSSDR_SOURCE_DIR}/src/tests/data/gnsstk_static14.patch &&
|
||||
${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/core/lib/GNSSCore/ObsID.hpp < ${GNSSSDR_SOURCE_DIR}/src/tests/data/gnsstk_gcc13.patch
|
||||
)
|
||||
else()
|
||||
set(GNSSTK_PATCH_COMMAND
|
||||
cd ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION} &&
|
||||
${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/CMakeLists.txt < ${GNSSSDR_SOURCE_DIR}/src/tests/data/gnsstk_static13.patch
|
||||
${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/CMakeLists.txt < ${GNSSSDR_SOURCE_DIR}/src/tests/data/gnsstk_static13.patch &&
|
||||
${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/core/lib/GNSSCore/ObsID.hpp < ${GNSSSDR_SOURCE_DIR}/src/tests/data/gnsstk_gcc13.patch
|
||||
)
|
||||
endif()
|
||||
# Patch only once
|
||||
@ -408,6 +404,9 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA)
|
||||
set(GNSSTK_PARALLEL_BUILD "-j${NUMBER_OF_PROCESSORS}")
|
||||
endif()
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(GNSSTK_FLAGS "-DCMAKE_CXX_FLAGS:STRING=-w") # Fix for clang in aarch64
|
||||
endif()
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.17.0)
|
||||
ExternalProject_Add(gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}
|
||||
GIT_REPOSITORY https://github.com/SGL-UT/gnsstk
|
||||
@ -425,6 +424,7 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA)
|
||||
-DCMAKE_CXX_EXTENSIONS=ON
|
||||
-DCMAKE_C_STANDARD=11
|
||||
-DCMAKE_C_EXTENSIONS=ON
|
||||
"${GNSSTK_FLAGS}"
|
||||
BUILD_COMMAND ${GNSSTK_BUILD_COMMAND} ${GNSSTK_PARALLEL_BUILD}
|
||||
BUILD_BYPRODUCTS ${GNSSSDR_BINARY_DIR}/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gnsstk${CMAKE_STATIC_LIBRARY_SUFFIX}
|
||||
UPDATE_COMMAND ""
|
||||
|
12
src/tests/data/gnsstk_gcc13.patch
Normal file
12
src/tests/data/gnsstk_gcc13.patch
Normal file
@ -0,0 +1,12 @@
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
SPDX-FileCopyrightText: 2022 Carles Fernandez-Prades <carles.fernandez@cttc.es>
|
||||
--- ObsID.hpp 2023-01-23 16:53:25.000000000 +0100
|
||||
+++ ObsID.hpp 2023-01-23 16:55:14.000000000 +0100
|
||||
@@ -47,6 +47,7 @@
|
||||
#ifndef OBSID_HPP
|
||||
#define OBSID_HPP
|
||||
|
||||
+#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
@ -353,6 +353,10 @@ TEST(HAS_Test, Decoder)
|
||||
EXPECT_EQ(has_message->phase_discontinuity_indicator[has_message->get_PRNs_in_mask(0).size() + i][2], phase_discontinuity_indicator_expected_gal[i]);
|
||||
EXPECT_EQ(has_message->phase_discontinuity_indicator[has_message->get_PRNs_in_mask(0).size() + i][3], phase_discontinuity_indicator_expected_gal[i]);
|
||||
}
|
||||
EXPECT_FLOAT_EQ(has_message->get_code_bias_m("L1 C/A", 10), -2.64 * HAS_MSG_CODE_BIAS_SCALE_FACTOR);
|
||||
EXPECT_FLOAT_EQ(has_message->get_code_bias_m("L1 C/A", 11), 0.0);
|
||||
EXPECT_FLOAT_EQ(has_message->get_code_bias_m("E1-C", 36), -1.98 * HAS_MSG_CODE_BIAS_SCALE_FACTOR);
|
||||
EXPECT_FLOAT_EQ(has_message->get_code_bias_m("E1-C", 37), 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user