diff --git a/CMakeLists.txt b/CMakeLists.txt index 62f3cec71..e2f33d0c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -352,7 +352,7 @@ set(GNSSSDR_GTEST_LOCAL_VERSION "1.8.1") set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master") set(GNSSSDR_GPSTK_LOCAL_VERSION "2.10.6") set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.13") - +set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.9") ################################################################################ @@ -1216,6 +1216,53 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS endif(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERSION}) +################################################################################ +# PugiXML - https://pugixml.org/ +################################################################################ +find_package(PugiXML QUIET) +if(PugiXML_FOUND) + message(STATUS "PugiXML has been found. Reading of GSA Galileo almanac XML files enabled.") +else(PugiXML_FOUND) + message(STATUS " PugiXML v${GNSSSDR_PUGIXML_LOCAL_VERSION} will be downloaded and built automatically when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'.") + set(PUGIXML_COMPILER -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}) + set(TOOLCHAIN_ARG "") + if(EXISTS $ENV{OECORE_TARGET_SYSROOT}) + set(PUGIXML_COMPILER "") + set(TOOLCHAIN_ARG "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/Toolchains/oe-sdk_cross.cmake") + endif(EXISTS $ENV{OECORE_TARGET_SYSROOT}) + if(CMAKE_VERSION VERSION_LESS 3.2) + ExternalProject_Add( + pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/pugixml + GIT_REPOSITORY https://github.com/zeux/pugixml + GIT_TAG v${GNSSSDR_PUGIXML_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/pugixml/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + CMAKE_ARGS ${PUGIXML_COMPILER} ${TOOLCHAIN_ARG} + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + else(CMAKE_VERSION VERSION_LESS 3.2) + ExternalProject_Add( + pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/pugixml + GIT_REPOSITORY https://github.com/zeux/pugixml + GIT_TAG v${GNSSSDR_PUGIXML_LOCAL_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/pugixml/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION} + CMAKE_ARGS ${PUGIXML_COMPILER} ${TOOLCHAIN_ARG} + UPDATE_COMMAND "" + PATCH_COMMAND "" + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}pugixml${CMAKE_STATIC_LIBRARY_SUFFIX} + INSTALL_COMMAND "" + ) + endif(CMAKE_VERSION VERSION_LESS 3.2) + set(PUGIXML_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}pugixml${CMAKE_STATIC_LIBRARY_SUFFIX} ) + set(PUGIXML_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/pugixml/pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION}/src ) + set(PUGIXML_LOCAL true) +endif(PugiXML_FOUND) + ################################################################################ # USRP Hardware Driver (UHD) - OPTIONAL diff --git a/README.md b/README.md index 6624d618d..d783c0858 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,8 @@ $ sudo apt-get install build-essential cmake git libboost-dev libboost-date-time libboost-system-dev libboost-filesystem-dev libboost-thread-dev libboost-chrono-dev \ libboost-serialization-dev liblog4cpp5-dev libuhd-dev gnuradio-dev gr-osmosdr \ libblas-dev liblapack-dev libarmadillo-dev libgflags-dev libgoogle-glog-dev \ - libgnutls-openssl-dev libpcap-dev python-mako python-six libmatio-dev libgtest-dev + libgnutls-openssl-dev libpcap-dev python-mako python-six libmatio-dev libpugixml-dev \ + libgtest-dev ~~~~~~ Please note that the required files from `libgtest-dev` were moved to `googletest` in Debian 9 "stretch" and Ubuntu 18.04 "bionic", and moved back again to `libgtest-dev` in Debian 10 "buster" and Ubuntu 18.10 "cosmic". @@ -85,7 +86,7 @@ $ sudo yum install make automake gcc gcc-c++ kernel-devel cmake git boost-devel boost-date-time boost-system boost-filesystem boost-thread boost-chrono \ boost-serialization log4cpp-devel gnuradio-devel gr-osmosdr-devel \ blas-devel lapack-devel matio-devel armadillo-devel gflags-devel \ - glog-devel openssl-devel libpcap-devel python-mako python-six + glog-devel openssl-devel libpcap-devel python-mako python-six pugixml-devel ~~~~~~ Once you have installed these packages, you can jump directly to [download the source code and build GNSS-SDR](#download-and-build-linux). @@ -102,7 +103,7 @@ $ sudo yum install make automake gcc gcc-c++ kernel-devel libtool \ hdf5-devel cmake git boost-devel boost-date-time boost-system \ boost-filesystem boost-thread boost-chrono boost-serialization \ log4cpp-devel gnuradio-devel gr-osmosdr-devel blas-devel lapack-devel \ - armadillo-devel openssl-devel libpcap-devel python-mako python-six + armadillo-devel openssl-devel libpcap-devel python-mako python-six pugixml-devel ~~~~~~ Once you have installed these packages, you can jump directly to [download the source code and build GNSS-SDR](#download-and-build-linux). @@ -113,7 +114,7 @@ If you are using Arch Linux (with base-devel group installed): ~~~~~~ $ pacman -S cmake git boost boost-libs log4cpp libvolk gnuradio gnuradio-osmosdr \ - blas lapack gflags google-glog openssl python2-mako python2-six \ + blas lapack gflags google-glog openssl pugixml python2-mako python2-six \ libmatio libpcap gtest ~~~~~~ @@ -547,6 +548,7 @@ $ sudo port install google-glog +gflags $ sudo port install py27-mako $ sudo port install py27-six $ sudo port install matio +$ sudo port install pugixml ~~~~~~ You also might need to activate a Python installation. The list of installed versions can be retrieved with: @@ -586,6 +588,7 @@ $ brew install armadillo $ brew install glog gflags gnutls $ brew install gnuradio $ brew install libmatio +$ brew install pugixml $ pip install mako $ pip install six ~~~~~~ diff --git a/cmake/Modules/FindPugiXML.cmake b/cmake/Modules/FindPugiXML.cmake new file mode 100644 index 000000000..e1e8df872 --- /dev/null +++ b/cmake/Modules/FindPugiXML.cmake @@ -0,0 +1,69 @@ +# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors) +# +# This file is part of GNSS-SDR. +# +# GNSS-SDR is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GNSS-SDR is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNSS-SDR. If not, see . + + +# Find the pugixml XML parsing library. +# +# Sets the usual variables expected for find_package scripts: +# +# PUGIXML_INCLUDE_DIR - header location +# PUGIXML_LIBRARIES - library to link against +# PUGIXML_FOUND - true if pugixml was found. + + +find_path (PUGIXML_INCLUDE_DIR + NAMES pugixml.hpp + PATHS ${PUGIXML_HOME}/include + /usr/include + /usr/local/include + /opt/local/include) + +find_library (PUGIXML_LIBRARY + NAMES pugixml + PATHS ${PUGIXML_HOME}/lib + /usr/lib/x86_64-linux-gnu + /usr/lib/aarch64-linux-gnu + /usr/lib/arm-linux-gnueabi + /usr/lib/arm-linux-gnueabihf + /usr/lib/i386-linux-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/mipsel-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/local/lib + /opt/local/lib + /usr/lib + /usr/lib64 + /usr/local/lib64 ) + +# Support the REQUIRED and QUIET arguments, and set PUGIXML_FOUND if found. +include (FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS (PugiXML DEFAULT_MSG PUGIXML_LIBRARY + PUGIXML_INCLUDE_DIR) + +if (PUGIXML_FOUND) + set (PUGIXML_LIBRARIES ${PUGIXML_LIBRARY}) + if (NOT PugiXML_FIND_QUIETLY) + message (STATUS "PugiXML include = ${PUGIXML_INCLUDE_DIR}") + message (STATUS "PugiXML library = ${PUGIXML_LIBRARY}") + endif (NOT PugiXML_FIND_QUIETLY) +else (PUGIXML_FOUND) + message (STATUS "PugiXML not found.") +endif(PUGIXML_FOUND) + +mark_as_advanced (PUGIXML_LIBRARY PUGIXML_INCLUDE_DIR) \ No newline at end of file diff --git a/src/core/libs/CMakeLists.txt b/src/core/libs/CMakeLists.txt index f8b7f7dc0..45c7477ab 100644 --- a/src/core/libs/CMakeLists.txt +++ b/src/core/libs/CMakeLists.txt @@ -45,6 +45,7 @@ include_directories( ${GLOG_INCLUDE_DIRS} ${GFlags_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} + ${PUGIXML_INCLUDE_DIR} ) list(SORT CORE_LIBS_HEADERS) @@ -52,4 +53,8 @@ list(SORT CORE_LIBS_SOURCES) add_library(rx_core_lib ${CORE_LIBS_SOURCES} ${CORE_LIBS_HEADERS}) source_group(Headers FILES ${CORE_LIBS_HEADERS}) -target_link_libraries(rx_core_lib supl_library) +target_link_libraries(rx_core_lib supl_library ${PUGIXML_LIBRARY}) + +if(PUGIXML_LOCAL) + add_dependencies(rx_core_lib pugixml-${GNSSSDR_PUGIXML_LOCAL_VERSION}) +endif(PUGIXML_LOCAL) diff --git a/src/core/libs/gnss_sdr_supl_client.cc b/src/core/libs/gnss_sdr_supl_client.cc index 7494d2f3f..1b9646de0 100644 --- a/src/core/libs/gnss_sdr_supl_client.cc +++ b/src/core/libs/gnss_sdr_supl_client.cc @@ -32,6 +32,7 @@ */ #include "gnss_sdr_supl_client.h" +#include #include #include @@ -842,11 +843,61 @@ bool gnss_sdr_supl_client::load_gal_almanac_xml(const std::string file_name) boost::archive::xml_iarchive xml(ifs); gal_almanac_map.clear(); xml >> boost::serialization::make_nvp("GNSS-SDR_gal_almanac_map", this->gal_almanac_map); - LOG(INFO) << "Loaded Galileo almanac map data with " << this->gal_almanac_map.size() << " satellites"; } catch (std::exception& e) { - LOG(WARNING) << e.what() << "File: " << file_name; + // Maybe the file is from https://www.gsc-europa.eu/system-status/almanac-data ? + return this->read_gal_almanac_from_gsa(file_name); + } + LOG(INFO) << "Loaded Galileo almanac map data with " << this->gal_almanac_map.size() << " satellites"; + return true; +} + + +bool gnss_sdr_supl_client::read_gal_almanac_from_gsa(const std::string file_name) +{ + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(file_name.c_str()); + if (!result) + { + LOG(WARNING) << "Error loading file " << file_name << ":" << result.description(); + return false; + } + for (pugi::xml_node almanac : doc.child("signalData") + .child("body") + .child("Almanacs") + .children("svAlmanac")) + { + Galileo_Almanac gal_alm; + try + { + uint32_t prn = static_cast(std::stoi(almanac.child_value("SVID"))); + gal_alm.i_satellite_PRN = prn; + gal_alm.i_Toa = std::stoi(almanac.child("almanac").child_value("t0a")); + gal_alm.i_WNa = std::stoi(almanac.child("almanac").child_value("wna")); + gal_alm.i_IODa = std::stoi(almanac.child("almanac").child_value("iod")); + gal_alm.d_Delta_i = std::stod(almanac.child("almanac").child_value("deltai")); + gal_alm.d_M_0 = std::stod(almanac.child("almanac").child_value("deltai")); + gal_alm.d_e_eccentricity = std::stod(almanac.child("almanac").child_value("ecc")); + gal_alm.d_Delta_sqrt_A = std::stod(almanac.child("almanac").child_value("aSqRoot")); + gal_alm.d_OMEGA0 = std::stod(almanac.child("almanac").child_value("omega0")); + gal_alm.d_OMEGA = std::stod(almanac.child("almanac").child_value("w")); + gal_alm.d_OMEGA_DOT = std::stod(almanac.child("almanac").child_value("omegaDot")); + gal_alm.d_A_f0 = std::stod(almanac.child("almanac").child_value("af0")); + gal_alm.d_A_f1 = std::stod(almanac.child("almanac").child_value("af1")); + gal_alm.E5b_HS = std::stoi(almanac.child("svINavSignalStatus").child_value("statusE5b")); + gal_alm.E1B_HS = std::stoi(almanac.child("svINavSignalStatus").child_value("statusE1B")); + gal_alm.E5a_HS = std::stoi(almanac.child("svFNavSignalStatus").child_value("statusE5a")); + + this->gal_almanac_map[static_cast(prn)] = gal_alm; + } + catch (const std::exception& e) + { + std::cerr << e.what() << std::endl; + } + } + if (this->gal_almanac_map.empty()) + { return false; } return true; diff --git a/src/core/libs/gnss_sdr_supl_client.h b/src/core/libs/gnss_sdr_supl_client.h index 52e4ed371..d20779d33 100644 --- a/src/core/libs/gnss_sdr_supl_client.h +++ b/src/core/libs/gnss_sdr_supl_client.h @@ -77,6 +77,7 @@ private: supl_ctx_t ctx; // assistance data supl_assist_t assist; + bool read_gal_almanac_from_gsa(const std::string file_name); public: // SUPL SERVER INFO diff --git a/src/core/receiver/CMakeLists.txt b/src/core/receiver/CMakeLists.txt index e0246a06f..461320653 100644 --- a/src/core/receiver/CMakeLists.txt +++ b/src/core/receiver/CMakeLists.txt @@ -157,6 +157,7 @@ include_directories( ${GFlags_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${PUGIXML_INCLUDE_DIR} ${OPT_RECEIVER_INCLUDE_DIRS} ${VOLK_GNSSSDR_INCLUDE_DIRS} ) diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index b21f68ff8..e4e6ce91d 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -241,8 +241,8 @@ bool ControlThread::read_assistance_from_XML() std::string cnav_utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_cnav_utc_model_xml", cnav_utc_default_xml_filename); std::string eph_glo_xml_filename = configuration_->property("GNSS-SDR.SUPL_glo_ephemeris_xml", eph_glo_gnav_default_xml_filename); std::string glo_utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_glo_utc_model_xml", glo_utc_default_xml_filename); - std::string gal_almanac_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_almanacl_xml", gal_almanac_default_xml_filename); - std::string gps_almanac_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_almanacl_xml", gps_almanac_default_xml_filename); + std::string gal_almanac_xml_filename = configuration_->property("GNSS-SDR.SUPL_gal_almanac_xml", gal_almanac_default_xml_filename); + std::string gps_almanac_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_almanac_xml", gps_almanac_default_xml_filename); if (configuration_->property("GNSS-SDR.AGNSS_XML_enabled", false) == true) { @@ -258,7 +258,8 @@ bool ControlThread::read_assistance_from_XML() cnav_utc_xml_filename = configuration_->property("GNSS-SDR.AGNSS_cnav_utc_model_xml", cnav_utc_default_xml_filename); eph_glo_xml_filename = configuration_->property("GNSS-SDR.AGNSS_glo_ephemeris_xml", eph_glo_gnav_default_xml_filename); glo_utc_xml_filename = configuration_->property("GNSS-SDR.AGNSS_glo_utc_model_xml", glo_utc_default_xml_filename); - gal_almanac_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gal_almanacl_xml", gal_almanac_default_xml_filename); + gal_almanac_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gal_almanac_xml", gal_almanac_default_xml_filename); + gps_almanac_xml_filename = configuration_->property("GNSS-SDR.AGNSS_gps_almanac_xml", gps_almanac_default_xml_filename); } std::cout << "Trying to read GNSS ephemeris from XML file(s)..." << std::endl; diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt index 701f8ca95..eaf6eff43 100644 --- a/src/main/CMakeLists.txt +++ b/src/main/CMakeLists.txt @@ -61,6 +61,7 @@ include_directories( ${ARMADILLO_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${PUGIXML_INCLUDE_DIR} ${GNSS_SDR_OPTIONAL_HEADERS} ${VOLK_GNSSSDR_INCLUDE_DIRS} ${OPT_GNSSSDR_INCLUDE_DIRS} diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 9e8d519b6..5bcd5729f 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -376,6 +376,7 @@ set(LIST_INCLUDE_DIRS ${VOLK_INCLUDE_DIRS} ${VOLK_GNSSSDR_INCLUDE_DIRS} ${MATIO_INCLUDE_DIRS} + ${PUGIXML_INCLUDE_DIR} ${GNSS_SDR_TEST_OPTIONAL_HEADERS} ) diff --git a/src/utils/front-end-cal/CMakeLists.txt b/src/utils/front-end-cal/CMakeLists.txt index 6f0b15acb..151acf2b0 100644 --- a/src/utils/front-end-cal/CMakeLists.txt +++ b/src/utils/front-end-cal/CMakeLists.txt @@ -43,6 +43,7 @@ include_directories( ${GNURADIO_BLOCKS_INCLUDE_DIRS} ${ARMADILLO_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} + ${PUGIXML_INCLUDE_DIR} ${VOLK_GNSSSDR_INCLUDE_DIRS} )