Skip to content

Commit

Permalink
gnss_info: Refactored out NavLibraryOrbitalDataProvider.
Browse files Browse the repository at this point in the history
  • Loading branch information
peci1 committed Nov 13, 2023
1 parent 5be66c7 commit deb800a
Show file tree
Hide file tree
Showing 12 changed files with 585 additions and 163 deletions.
2 changes: 1 addition & 1 deletion gnss_info/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ if (CXX_FILESYSTEM_TYPE STREQUAL "Boost")
add_compile_definitions(satellite_metadata PRIVATE -DCXX_FILESYSTEM_IS_BOOST=1)
endif()

add_library(orbital_data src/ethz_satdb_provider.cpp src/orbital_data_manager.cpp src/tle.c)
add_library(orbital_data src/ethz_satdb_datasource.cpp src/nav_library_orbital_data_provider.cpp src/orbital_data_manager.cpp src/tle.c)
add_dependencies(orbital_data ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(orbital_data PUBLIC ${catkin_LIBRARIES} PRIVATE Eigen3::Eigen ${PROJECT_NAME}_common gnsstk jsoncpp_lib std::filesystem)

Expand Down
2 changes: 1 addition & 1 deletion gnss_info/include/gnss_info/cache_index.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ struct DayIndex
template<> struct std::hash<gnss_info::DayIndex>
{
std::size_t operator()(const gnss_info::DayIndex& k) const noexcept;
};
};
45 changes: 45 additions & 0 deletions gnss_info/include/gnss_info/ethz_satdb_datasource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: Czech Technical University in Prague

#pragma once

#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>

#include <gnss_info/nav_library_data_source.h>
#include <gnss_info_msgs/SatelliteInfo.h>

#include <ros/time.h>

namespace gnss_info
{

struct EthzSatdbDataSourcePrivate;

/**
* \brief GNSSTk NavLibrary data source downloading TLE data from ETHZ Satellite Database.
*/
class EthzSatdbDataSource : public NavLibraryDataSource
{
public:
explicit EthzSatdbDataSource(const std::unordered_map<uint32_t, gnss_info_msgs::SatelliteInfo>& satelliteInfo);
~EthzSatdbDataSource() override;

std::string getName() const override;
bool isPrecise() const override;
bool isApproximate() const override;

std::pair<ros::Time, ros::Time> getTimeRange() const override;
std::unordered_set<std::string> getConstellations() const override;

bool load(const ros::Time& time, const DataSourceLoadCb& cb) override;
bool load(const ros::Time& startTime, const ros::Time& endTime, const DataSourceLoadCb& cb) override;

private:
std::unique_ptr<EthzSatdbDataSourcePrivate> data; //!< Private implementation data (PIMPL).
};

}
3 changes: 2 additions & 1 deletion gnss_info/include/gnss_info/igs_satellite_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>

#include <cras_cpp_common/optional.hpp>
#include <gnss_info_msgs/SatelliteInfo.h>
Expand Down Expand Up @@ -73,6 +72,8 @@ class IGSSatelliteMetadata
* list will be returned.
* \param[in] time The reference time (epoch).
* \param[in] onlyActive If true, only active satellites will be returned.
* \param[in] onlyConstellations If set, only satellites from the given constellations will be returned.
* \param[in] onlySignals If set, only satellites transmitting the given signals will be returned.
* \return Mapping Satcat ID => known valid satellite.
*/
std::unordered_map<uint32_t, gnss_info_msgs::SatelliteInfo> getSatellites(
Expand Down
87 changes: 87 additions & 0 deletions gnss_info/include/gnss_info/nav_library_data_source.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: Czech Technical University in Prague

#pragma once

#include <functional>
#include <string>
#include <unordered_set>
#include <utility>

#include <ros/time.h>


namespace gnss_info
{

/**
* \brief Generic interface for various data sources for gnsstk::NavLibrary.
*/
class NavLibraryDataSource
{
public:
/**
* \brief Callback to be called when a new source file is introduced.
* \param[in] file Path to the source file.
* \return Whether reading the source file succeeded.
*/
typedef std::function<bool(const std::string& file)> DataSourceLoadCb;

/**
* \brief Construct the data source.
*
* Also make sure the data source is registered via gnsstk::MultiFormatNavDataFactory::addFactory() (but only once).
*/
NavLibraryDataSource() = default;

virtual ~NavLibraryDataSource() = default;

/**
* \brief Get human-readable name of the data source.
* \return The name.
*/
virtual std::string getName() const = 0;

/**
* \brief Return whether this datasource works with precise orbit data.
* \return Whether this datasource works with precise orbit data.
*/
virtual bool isPrecise() const = 0;

/**
* \brief Return whether this datasource works with approximate orbit data.
* \return Whether this datasource works with approximate orbit data.
*/
virtual bool isApproximate() const = 0;

/**
* \brief Get the time range in which this datasource can provide information.
* \return The time range (first, latest).
*/
virtual std::pair<ros::Time, ros::Time> getTimeRange() const = 0;

/**
* \brief Get the constellations handled by this data source.
* \return The constellations.
*/
virtual std::unordered_set<std::string> getConstellations() const = 0;

/**
* \brief Load data for the given time instant.
* \param[in] time The time to load at.
* \param[in] cb Callback to call for each found and downloaded data file.
* \return Whether loading succeeded.
*/
virtual bool load(const ros::Time& time, const DataSourceLoadCb& cb) = 0;

/**
* \brief Load data for the given time interval.
* \param[in] startTime The time to start loading at.
* \param[in] endTime The time to stop loading at.
* \param[in] cb Callback to call for each found and downloaded data file.
* \return Whether loading succeeded.
*/
virtual bool load(const ros::Time& startTime, const ros::Time& endTime, const DataSourceLoadCb& cb) = 0;
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,30 @@
#include <utility>

#include <cras_cpp_common/expected.hpp>
#include <gnss_info/nav_library_data_source.h>
#include <gnss_info/orbital_data_provider.h>
#include <gnss_info_msgs/SatelliteInfo.h>
#include <gnss_info_msgs/SatellitePosition.h>
#include <gnss_info_msgs/SatelliteSkyPosition.h>
#include <ros/ros.h>

#include <ros/time.h>

namespace gnss_info
{

struct EthzSatdbProviderPrivate;
struct NavLibraryOrbitalDataProviderPrivate;

/**
* \brief Generic interface for various providers of GNSS satellite orbital data.
* \brief GNSS satellite orbits provider based on gnsstk::NavLibrary with multi-format data source.
*/
class EthzSatdbProvider : public OrbitalDataProvider
class NavLibraryOrbitalDataProvider : public OrbitalDataProvider
{
public:
explicit EthzSatdbProvider(const std::unordered_map<uint32_t, gnss_info_msgs::SatelliteInfo>& satelliteInfo);
~EthzSatdbProvider() override;
NavLibraryOrbitalDataProvider();
~NavLibraryOrbitalDataProvider() override;

/**
* \brief Add data source.
* \param[in] source The data source to add.
*/
virtual void addDataSource(const std::shared_ptr<NavLibraryDataSource>& source);

std::string getName() const override;
bool isPrecise() const override;
Expand All @@ -38,17 +42,19 @@ class EthzSatdbProvider : public OrbitalDataProvider
std::pair<ros::Time, ros::Time> getTimeRange() const override;
std::unordered_set<std::string> getConstellations() const override;

bool preload(const ros::Time& startTime, const ros::Time& endTime) override;
bool load(const ros::Time& time, const cras::optional<bool>& precise) override;
bool load(const ros::Time& startTime, const ros::Time& endTime, const cras::optional<bool>& precise) override;

cras::expected<std::unordered_map<uint32_t, gnss_info_msgs::SatellitePosition>, std::string> getECEFPositions(
const ros::Time& time, const std::unordered_map<uint32_t, gnss_info_msgs::SatelliteInfo>& satellites) override;

cras::expected<std::unordered_map<uint32_t, gnss_info_msgs::SatelliteSkyPosition>, std::string> getSkyView(
const ros::Time& time, const geographic_msgs::GeoPoint& receiverPosition, double elevationMaskDeg,
const std::unordered_map<uint32_t, gnss_info_msgs::SatellitePosition>& satelliteECEFPositions) override;
const geographic_msgs::GeoPoint& position,
const std::unordered_map<uint32_t, gnss_info_msgs::SatellitePosition>& positions,
double elevationMaskDeg) override;

private:
std::unique_ptr<EthzSatdbProviderPrivate> data; //!< Private implementation data (PIMPL).
std::unique_ptr<NavLibraryOrbitalDataProviderPrivate> data; //!< Private implementation data (PIMPL).
};

}
78 changes: 72 additions & 6 deletions gnss_info/include/gnss_info/orbital_data_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,107 @@
#include <gnss_info_msgs/SatellitesList.h>
#include <gnss_info_msgs/SatellitesPositions.h>
#include <gnss_info_msgs/SkyView.h>

#include <ros/time.h>

namespace gnss_info
{

struct OrbitalDataManagerPrivate;

/**
* \brief Manager of multiple providers of satellite orbital data.
*/
class OrbitalDataManager
{
public:
OrbitalDataManager();
virtual ~OrbitalDataManager();

/**
* \brief Add the given provider to this manager and make its data available.
* \param[in] provider The provider to add.
*/
void addProvider(const std::shared_ptr<OrbitalDataProvider>& provider);

bool preload(const ros::Time& time);
bool preload(const ros::Time& time, const cras::optional<bool>& precise);
bool preload(const ros::Time& startTime, const ros::Time& endTime);
virtual bool preload(const ros::Time& startTime, const ros::Time& endTime, const cras::optional<bool>& precise);

/**
* \brief Load (and possibly download) data for the given time instant.
* \param[in] time The time instant to load for.
* \return Whether the loading succeeded.
*/
bool load(const ros::Time& time);

/**
* \brief Load (and possibly download) data for the given time instant.
* \param[in] time The time instant to load for.
* \param[in] precise If set, selects whether precise or approximate data should be loaded.
* \return Whether the loading succeeded.
*/
virtual bool load(const ros::Time& time, const cras::optional<bool>& precise);

/**
* \brief Load (and possibly download) data for the given time interval.
* \param[in] startTime Earliest time to load.
* \param[in] endTime Latest time to load.
* \return Whether the loading succeeded.
*/
bool load(const ros::Time& startTime, const ros::Time& endTime);

/**
* \brief Load (and possibly download) data for the given time interval.
* \param[in] startTime Earliest time to load.
* \param[in] endTime Latest time to load.
* \param[in] precise If set, selects whether precise or approximate data should be loaded.
* \return Whether the loading succeeded.
*/
virtual bool load(const ros::Time& startTime, const ros::Time& endTime, const cras::optional<bool>& precise);

/**
* \brief Compute ECEF positions of the satellites at the given time.
* \param[in] time The time to get positions for.
* \param[in] satellites The satellites to get positions for.
* \return ECEF positions of the satellites, or an error string.
*/
cras::expected<gnss_info_msgs::SatellitesPositions, std::string> getPositions(
const ros::Time& time, const gnss_info_msgs::SatellitesList& satellites);

/**
* \brief Compute ECEF positions of the satellites at the given time.
* \param[in] time The time to get positions for.
* \param[in] satellites The satellites to get positions for.
* \param[in] precise If set, selects whether precise or approximate positions should be computed.
* \return ECEF positions of the satellites, or an error string.
*/
virtual cras::expected<gnss_info_msgs::SatellitesPositions, std::string> getPositions(
const ros::Time& time, const gnss_info_msgs::SatellitesList& satellites, const cras::optional<bool>& precise);

/**
* \brief Compute sky view (azimuths, elevations and distances) of satellites from the given receiver position.
* \param[in] position Geographic position of the receiver.
* \param[in] positions ECEF positions of the satellites.
* \param[in] elevationMaskDeg Minimum elevation of satellites to return (in degrees).
* \return Sky view corresponding to the given configuration, or an error string.
*/
cras::expected<gnss_info_msgs::SkyView, std::string> getSkyView(
const geographic_msgs::GeoPoint& position, const gnss_info_msgs::SatellitesPositions& positions,
double elevationMaskDeg);

/**
* \brief Compute sky view (azimuths, elevations and distances) of satellites from the given receiver position.
* \param[in] position Geographic position of the receiver.
* \param[in] positions ECEF positions of the satellites.
* \param[in] elevationMaskDeg Minimum elevation of satellites to return (in degrees).
* \param[in] precise If set, selects whether precise or approximate positions should be computed.
* \return Sky view corresponding to the given configuration, or an error string.
*/
virtual cras::expected<gnss_info_msgs::SkyView, std::string> getSkyView(
const geographic_msgs::GeoPoint& position, const gnss_info_msgs::SatellitesPositions& positions,
double elevationMaskDeg, const cras::optional<bool>& precise);

/**
* \brief Compute Dilution of Precision for the given sky view.
* \param[in] skyView The sky view to compute DOP for.
* \return The dilution of precision for the given sky view.
*/
virtual gnss_info_msgs::DOP computeDOP(
const std::unordered_map<uint32_t, gnss_info_msgs::SatelliteSkyPosition>& skyView) const;

Expand Down
Loading

0 comments on commit deb800a

Please sign in to comment.