Go to the documentation of this file.
8 #include <unordered_map>
9 #include <unordered_set>
12 #include CXX_FILESYSTEM_INCLUDE
14 #include <gnsstk/MultiFormatNavDataFactory.hpp>
15 #include <gnsstk/NavDataFactoryStoreCallback.hpp>
16 #include <gnsstk/NavDataFactoryWithStoreFile.hpp>
17 #include <gnsstk/NavLibrary.hpp>
18 #include <gnsstk/OrbitData.hpp>
19 #include <gnsstk/Position.hpp>
20 #include <jsoncpp/json/json.h>
27 #include <gnss_info_msgs/Enums.h>
34 namespace fs = CXX_FILESYSTEM_NAMESPACE;
48 const auto rhs = std::dynamic_pointer_cast<TLEOrbitData>(right);
53 this->
tle.
name == rhs->tle.name &&
60 this->
tle.
ndot == rhs->tle.ndot &&
65 this->
tle.
inc == rhs->tle.inc &&
66 this->
tle.
OMG == rhs->tle.OMG &&
67 this->
tle.
ecc == rhs->tle.ecc &&
68 this->
tle.
omg == rhs->tle.omg &&
69 this->
tle.
M == rhs->tle.M &&
70 this->
tle.
n == rhs->tle.n &&
71 this->
tle.
rev == rhs->tle.rev;
77 const auto rhs = std::dynamic_pointer_cast<TLEOrbitData>(right);
80 res.emplace_back(
"CLASS");
84 if (strcmp(this->
tle.
name, rhs->tle.name) != 0)
85 res.emplace_back(
"name");
86 if (strcmp(this->
tle.
alias, rhs->tle.alias) != 0)
87 res.emplace_back(
"alias");
88 if (strcmp(this->
tle.
satno, rhs->tle.satno) != 0)
89 res.emplace_back(
"satno");
91 res.emplace_back(
"satclass");
92 if (strcmp(this->
tle.
desig, rhs->tle.desig) != 0)
93 res.emplace_back(
"desig");
94 if (this->
tle.
epoch.
sec != rhs->tle.epoch.sec || this->tle.epoch.time != rhs->tle.epoch.time)
95 res.emplace_back(
"epoch");
96 if (this->
tle.
ndot != rhs->tle.ndot)
97 res.emplace_back(
"ndot");
98 if (this->
tle.
nddot != rhs->tle.nddot)
99 res.emplace_back(
"nddot");
100 if (this->
tle.
bstar != rhs->tle.bstar)
101 res.emplace_back(
"bstar");
102 if (this->
tle.
etype != rhs->tle.etype)
103 res.emplace_back(
"etype");
104 if (this->
tle.
eleno != rhs->tle.eleno)
105 res.emplace_back(
"eleno");
106 if (this->
tle.
inc != rhs->tle.inc)
107 res.emplace_back(
"inc");
108 if (this->
tle.
OMG != rhs->tle.OMG)
109 res.emplace_back(
"OMG");
110 if (this->
tle.
ecc != rhs->tle.ecc)
111 res.emplace_back(
"ecc");
112 if (this->
tle.
omg != rhs->tle.omg)
113 res.emplace_back(
"omg");
114 if (this->
tle.
M != rhs->tle.M)
115 res.emplace_back(
"M");
116 if (this->
tle.
n != rhs->tle.n)
117 res.emplace_back(
"n");
118 if (this->
tle.
rev != rhs->tle.rev)
119 res.emplace_back(
"rev");
126 return std::make_shared<TLEOrbitData>(this->
tle);
136 const tle_t tleList{1, 1, &this->
tle};
140 gtime_t gtime {rosWhen.
sec, rosWhen.nsec * 1e-9};
143 ROS_WARN_THROTTLE(1.0,
"Failed to compute ECEF position of satellite %s (%s) at time %s.",
148 Position pos {rs, Position::CoordinateSystem::Cartesian};
149 if (
pos.radius() <
pos.radiusEarth())
151 ROS_WARN_THROTTLE(1.0,
"Invalid satellite position. Satellite %s (%s) is underground at time %s!",
156 xvt.
x =
Triple(rs[0], rs[1], rs[2]);
157 xvt.
v =
Triple(rs[3], rs[4], rs[5]);
187 return this->
process(filename, cb);
199 if (!
tle_read(filename.c_str(), &tles))
201 ROS_ERROR(
"Failed reading TLE file %s.", filename.c_str());
205 const std::vector<tled_t> tlesVec(tles.data, tles.data + tles.n);
206 std::free(tles.data);
208 for (
const auto& tle : tlesVec)
210 std::shared_ptr<TLEOrbitData> alm;
213 if (alm !=
nullptr && !cb.
process(alm))
232 auto satno = std::string(navIn.
satno);
233 while (!satno.empty() && satno[0] ==
'0')
234 satno = satno.substr(1);
241 if (!satId.has_value())
244 navOut = std::make_shared<TLEOrbitData>(navIn);
245 navOut->signal.sat = navOut->signal.xmitSat = *satId;
246 navOut->signal.system = satId->system;
255 catch (
const std::invalid_argument&)
262 static std::unordered_map<uint32_t, gnss_info_msgs::SatelliteInfo>
satelliteInfo;
278 std::string
urlFormat {
"https://satdb.ethz.ch/api/satellitedata/?object-name=%s&"
279 "start-datetime=%sT0000&end-datetime=%sT0000&before=3&after=3&"
280 "without-frequency-data=True"};
286 {gnss_info_msgs::Enums::CONSTELLATION_GPS,
"NAVSTAR"},
287 {gnss_info_msgs::Enums::CONSTELLATION_GALILEO,
"GSAT0"},
288 {gnss_info_msgs::Enums::CONSTELLATION_BEIDOU,
"BEIDOU"},
289 {gnss_info_msgs::Enums::CONSTELLATION_GLONASS,
"COSMOS"}
312 std::stringstream ss;
313 size_t numSatellites {0u};
317 ROS_INFO(
"Downloading orbits from %s.", url.c_str());
320 if (!maybeReadBuffer.has_value())
321 return cras::make_unexpected(maybeReadBuffer.error());
323 auto& readBuffer = *maybeReadBuffer;
326 if (!reader.parse(readBuffer, root))
328 return cras::make_unexpected(
cras::format(
"Error parsing data downloaded from URL %s: %s.",
329 url.c_str(), reader.getFormattedErrorMessages().c_str()));
332 const auto& results = root[
"results"];
333 for (
int index = 0; index < results.size(); ++index)
338 if (numSatellites == 0)
339 return cras::make_unexpected(
"Determining satellite orbits failed.");
343 std::ofstream outFile;
344 outFile.open(cacheFile.c_str());
345 outFile << ss.rdbuf();
347 catch (
const std::exception& e)
349 return cras::make_unexpected(e.what());
352 ROS_DEBUG(
"Saved orbits to %s.", cacheFile.c_str());
357 const std::unordered_map<uint32_t, gnss_info_msgs::SatelliteInfo>& satelliteInfo) :
362 this->
data->constellations =
364 gnss_info_msgs::Enums::CONSTELLATION_GPS,
365 gnss_info_msgs::Enums::CONSTELLATION_GLONASS,
366 gnss_info_msgs::Enums::CONSTELLATION_GALILEO,
367 gnss_info_msgs::Enums::CONSTELLATION_BEIDOU,
373 static auto registered {
false};
386 return this->
data->timeRange;
391 return this->
data->constellations;
401 auto endTime2 = endTime;
405 std::list<DayIndex> days;
407 days.emplace_back(
time);
408 days.remove_if([
this](
const auto&
day) {
return this->
data->loadedDays.count(
day) > 0;});
413 const auto numDays = days.size();
414 if (numDays > 2 * this->
data->maxDownloadDays)
416 ROS_ERROR(
"Not loading %zu orbits, it is too much.", numDays);
420 size_t numToDownload {0u};
421 for (
const auto&
day : days)
428 if (numToDownload > this->
data->maxDownloadDays)
430 ROS_ERROR(
"Not downloading %zu orbits, it is too much.", numToDownload);
434 if (numToDownload > 0)
449 auto hadError {
false};
450 size_t numLoaded {0u};
451 for (
const auto&
day : days)
456 const auto maybeDownloaded = this->
data->download(
day);
457 if (!maybeDownloaded.has_value())
459 ROS_ERROR(
"%s", maybeDownloaded.error().c_str());
465 if (!cb(
file.string()))
467 ROS_ERROR(
"Error processing TLE data file %s.",
file.c_str());
473 this->
data->loadedDays.insert(
day);
476 ROS_INFO(
"Successfully loaded orbits for %zu days.", numLoaded);
492 return "ETH Zurich Satellite DB";
bool isApproximate() const override
Return whether this datasource works with approximate orbit data.
std::shared_ptr< NavData > NavDataPtr
int tle_read(const char *file, tle_t *tle)
static std::unordered_map< uint32_t, gnss_info_msgs::SatelliteInfo > satelliteInfo
std::string getName() const override
Get human-readable name of the data source.
std::list< std::string > compare(const NavDataPtr &right) const override
page HOWTO subpage DoxygenGuide Documenting Your Code page DoxygenGuide Documenting Your Code todo Flesh out this document section doctips Tips for Documenting When defining make sure that the prototype is identical between the cpp and hpp file
virtual bool process(const NavDataPtr &navOut)
bool convertToOrbit(const tled_t &navIn, std::shared_ptr< TLEOrbitData > &navOut)
virtual std::list< std::string > compare(const NavDataPtr &right) const
bool isPrecise() const override
Return whether this datasource works with precise orbit data.
static void addSatelliteInfo(const std::unordered_map< uint32_t, gnss_info_msgs::SatelliteInfo > &satelliteInfo)
std::map< TimeCvtKey, OffsetEpochMap > OffsetCvtMap
bool isSameData(const NavDataPtr &right) const override
std::map< NavMessageType, NavSatMap > NavMessageMap
#define ROS_WARN_THROTTLE(period,...)
std::unordered_set< std::string > getConstellations() const override
Get the constellations handled by this data source.
static const Duration DAY
cras::optional< gnsstk::SatID > satelliteInfoToSatID(const gnss_info_msgs::SatelliteInfo &info)
gnsstk::Position convert(const geographic_msgs::GeoPoint &position)
gtime_t utc2gpst(gtime_t t)
std::unique_ptr< EthzSatdbDataSourcePrivate > data
Private implementation data (PIMPL).
cras::expected< bool, std::string > download(const DayIndex &day)
NavDataPtr clone() const override
uint8_t day
Day (starting with 1).
std::shared_ptr< NavDataFactory > NavDataFactoryPtr
Object that can be used as an index into a cache and assigns all times from the same day the same cac...
int tle_pos(gtime_t time, const char *name, const char *satno, const char *desig, const tle_t *tle, const erp_t *erp, double *rs)
void replace(::std::string &str, const ::std::string &from, const ::std::string &to, const ::cras::ReplacePosition &where=::cras::ReplacePosition::EVERYWHERE)
NavValidityType navValidity
bool isCacheFileValid(const std::string &file)
Return whether the given cache file can be used.
EthzSatdbDataSource(const std::unordered_map< uint32_t, gnss_info_msgs::SatelliteInfo > &satelliteInfo)
std::pair< ros::Time, ros::Time > timeRange
uint8_t month
Month (starting with 1).
EnumIterator< SatelliteSystem, SatelliteSystem::Unknown, SatelliteSystem::Last > SatelliteSystemIterator
~EthzSatdbDataSource() override
std::unordered_set< std::string > constellations
std::pair< ros::Time, ros::Time > getTimeRange() const override
Get the time range in which this datasource can provide information.
std::string getCacheDir()
Return path to a directory where cache files should be stored. Also make sure the directory exists.
std::string getFactoryFormats() const override
#define ROS_LOG(level, name,...)
std::unordered_map< std::string, std::string > satdbConstellations
std::unordered_set< DayIndex > loadedDays
TLEOrbitData(const tled_t &tle)
bool find(const NavMessageID &nmid, const CommonTime &when, NavDataPtr &navOut, SVHealth xmitHealth, NavValidityType valid, NavSearchOrder order) override
bool validate() const override
std::function< bool(const std::string &file)> DataSourceLoadCb
Callback to be called when a new source file is introduced.
bool loadIntoMap(const std::string &filename, NavMessageMap &navMap, NavNearMessageMap &navNearMap, OffsetCvtMap &ofsMap) override
bool getXvt(const CommonTime &when, Xvt &xvt, const ObsID &oid) override
bool load(const ros::Time &time, const DataSourceLoadCb &cb) override
Load data for the given time instant.
cras::expected< std::stringstream, std::string > download(const std::string &url, const std::function< void(CURL *)> &curlOptions={})
Download the given URL to a stringstream.
uint32_t parseUInt32(const char *string)
NavSignalSet supportedSignals
bool process(const std::string &filename, NavDataFactoryCallback &cb) override
inline ::std::string format(::std::string format, ::va_list args)
#define ROSCONSOLE_DEFAULT_NAME
std::map< NavMessageType, NavNearSatMap > NavNearMessageMap
NavMessageTypeSet procNavTypes
virtual bool isSameData(const NavDataPtr &right) const
std::string asString(AngleType e) noexcept
inline ::std::string to_string(char *value)
fs::path getCacheFile(const DayIndex &day) const
gnss_info
Author(s): Martin Pecka
autogenerated on Fri Nov 24 2023 03:50:35