diff --git a/CMakeLists.txt b/CMakeLists.txt
index 62f3cec71..15432d2d3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1216,6 +1216,11 @@ 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)
+
################################################################################
# USRP Hardware Driver (UHD) - OPTIONAL
diff --git a/README.md b/README.md
index 6624d618d..c632b9ab2 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:
diff --git a/cmake/Modules/FindPugiXML.cmake b/cmake/Modules/FindPugiXML.cmake
new file mode 100644
index 000000000..f60b441c8
--- /dev/null
+++ b/cmake/Modules/FindPugiXML.cmake
@@ -0,0 +1,67 @@
+# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors)
+#
+# This file is part of GNSS-SDR.
+#
+# GNSS-SDR is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GNSS-SDR is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNSS-SDR. If not, see .
+
+
+# Find the pugixml XML parsing library.
+#
+# Sets the usual variables expected for find_package scripts:
+#
+# PUGIXML_INCLUDE_DIR - header location
+# PUGIXML_LIBRARIES - library to link against
+# PUGIXML_FOUND - true if pugixml was found.
+
+
+find_path (PUGIXML_INCLUDE_DIR
+ NAMES pugixml.hpp
+ PATHS ${PUGIXML_HOME}/include
+ /usr/include
+ /usr/local/include
+ /opt/local/include)
+
+find_library (PUGIXML_LIBRARY
+ NAMES pugixml
+ PATHS ${PUGIXML_HOME}/lib
+ /usr/lib/x86_64-linux-gnu
+ /usr/lib/aarch64-linux-gnu
+ /usr/lib/arm-linux-gnueabi
+ /usr/lib/arm-linux-gnueabihf
+ /usr/lib/i386-linux-gnu
+ /usr/lib/mips-linux-gnu
+ /usr/lib/mips64el-linux-gnuabi64
+ /usr/lib/mipsel-linux-gnu
+ /usr/lib/powerpc64le-linux-gnu
+ /usr/lib/s390x-linux-gnu
+ /usr/local/lib
+ /opt/local/lib
+ /usr/lib )
+
+# 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..c901ea715 100644
--- a/src/core/libs/CMakeLists.txt
+++ b/src/core/libs/CMakeLists.txt
@@ -35,6 +35,14 @@ set(CORE_LIBS_HEADERS
string_converter.h
gnss_sdr_supl_client.h
)
+
+if(PugiXML_FOUND)
+ message(STATUS "PugiXML has been found. Reading of GSA Galileo almanac XML files enabled.")
+ add_definitions( -DPUGIXML_FOUND=1 )
+else(PugiXML_FOUND)
+ set(PUGIXML_INCLUDE_DIR "")
+ set(PUGIXML_LIBRARIES "")
+endif(PugiXML_FOUND)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
@@ -45,6 +53,7 @@ include_directories(
${GLOG_INCLUDE_DIRS}
${GFlags_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
+ ${PUGIXML_INCLUDE_DIR}
)
list(SORT CORE_LIBS_HEADERS)
@@ -52,4 +61,4 @@ 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_LIBRARIES})
diff --git a/src/core/libs/gnss_sdr_supl_client.cc b/src/core/libs/gnss_sdr_supl_client.cc
index 7494d2f3f..30de44cdf 100644
--- a/src/core/libs/gnss_sdr_supl_client.cc
+++ b/src/core/libs/gnss_sdr_supl_client.cc
@@ -32,6 +32,9 @@
*/
#include "gnss_sdr_supl_client.h"
+#ifdef PUGIXML_FOUND
+#include
+#endif
#include
#include
@@ -842,14 +845,68 @@ 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)
+{
+#ifdef PUGIXML_FOUND
+ 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;
+#else
+ return false;
+#endif
}
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/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;