9 #include <unordered_map>
10 #include <unordered_set>
13 #include <gnsstk/MultiFormatNavDataFactory.hpp>
14 #include <gnsstk/NavLibrary.hpp>
15 #include <gnsstk/Position.hpp>
19 #include <gnsstk/OrbitData.hpp>
34 std::list<std::shared_ptr<NavLibraryDataSource>>
sources;
41 std::unordered_map<gnsstk::NavMessageType, double>
posCov = {
45 std::unordered_map<gnsstk::NavMessageType, double>
velCov = {
53 this->
data->factory = std::make_shared<gnsstk::MultiFormatNavDataFactory>();
54 this->
data->navLibrary.addFactory(this->
data->factory);
61 this->
data->sources.push_back(source);
63 for (
const auto&
s : this->
data->sources)
65 const auto&
range =
s->getTimeRange();
68 this->
data->timeRange.first =
range.first;
70 this->
data->timeRange.first = std::min(this->
data->timeRange.first,
range.first);
73 this->
data->timeRange.second =
range.second;
75 this->
data->timeRange.second = std::max(this->
data->timeRange.second,
range.second);
77 this->
data->constellations.insert(
s->getConstellations().begin(),
s->getConstellations().end());
83 return this->
data->timeRange;
88 return this->
data->constellations;
94 for (
const auto& source : this->
data->sources)
96 if (precise.has_value() && *precise && !source->isPrecise())
98 if (precise.has_value() && !*precise && !source->isApproximate())
100 success |= source->load(
101 time, [
this](
const std::string&
file) {
return this->
data->factory->addDataSource(file);});
107 const cras::optional<bool>& precise)
109 bool success {
false};
110 for (
const auto& source : this->
data->sources)
112 if (precise.has_value() && *precise && !source->isPrecise())
114 if (precise.has_value() && !*precise && !source->isApproximate())
116 success |= source->load(startTime, endTime,
117 [
this](
const std::string&
file) {
return this->
data->factory->addDataSource(file);});
122 cras::expected<std::unordered_map<uint32_t, gnss_info_msgs::SatellitePosition>, std::string>
124 const ros::Time& time,
const std::unordered_map<uint32_t, gnss_info_msgs::SatelliteInfo>& satellites)
128 auto when1 = when, when2 = when;
131 const auto availableSats = this->
data->navLibrary.getAvailableSats(when1, when2);
132 if (availableSats.empty())
133 return cras::make_unexpected(
"No matching satellite data found.");
135 std::unordered_map<uint32_t, gnss_info_msgs::SatellitePosition> positions;
136 if (satellites.empty())
139 std::list<std::string> errors;
140 for (
const auto& [satcatID, info] : satellites)
143 if (!maybeSatID.has_value())
145 errors.push_back(
cras::format(
"Failed to determine PRN of satellite %u (%s) at time %s.",
151 if (availableSats.find(navId) == availableSats.cend())
154 std::array<gnsstk::NavMessageID, 2> searchTerms {{
160 bool success {
false};
161 for (
const auto& searchTerm : searchTerms)
163 if (this->
data->navLibrary.find(searchTerm, when,
navData,
167 foundMessageType = searchTerm.messageType;
172 if (!success ||
navData ==
nullptr)
174 errors.push_back(
cras::format(
"No position data for satellite %u (%s) at time %s.",
181 success = orbitData->getXvt(when, xvt);
185 errors.push_back(
cras::format(
"Failed to compute ECEF position of satellite %u (%s) at time %s.",
190 xvt, satcatID, this->
data->posCov[foundMessageType], this->data->velCov[foundMessageType]);
193 if (!errors.empty() && positions.empty())
194 return cras::make_unexpected(
cras::join(errors,
" "));
195 if (positions.empty())
196 return cras::make_unexpected(
"No matching satellite data found.");
203 cras::expected<std::unordered_map<uint32_t, gnss_info_msgs::SatelliteSkyPosition>, std::string>
205 const geographic_msgs::GeoPoint& position,
206 const std::unordered_map<uint32_t, gnss_info_msgs::SatellitePosition>& positions,
207 const double elevationMaskDeg)
211 recPos.
transformTo(gnsstk::Position::CoordinateSystem::Cartesian);
213 std::unordered_map<uint32_t, gnss_info_msgs::SatelliteSkyPosition> skyView;
214 for (
const auto& [satcatID, ecefPose] : positions)
217 const auto elDeg = recPos.
elevation(satPos);
218 if (elDeg < elevationMaskDeg)
220 const auto azDeg = recPos.
azimuth(satPos);
222 auto& skyPosition = skyView[satcatID];
223 skyPosition.satcat_id = satcatID;
224 skyPosition.azimuth_deg = azDeg;
225 skyPosition.elevation_deg = elDeg;
226 skyPosition.distance = distance;
234 return std::any_of(this->
data->sources.cbegin(), this->data->sources.cend(),
235 [](
const std::shared_ptr<NavLibraryDataSource>&
s) {return s->isPrecise();});
240 return std::any_of(this->
data->sources.cbegin(), this->data->sources.cend(),
241 [](
const std::shared_ptr<NavLibraryDataSource>&
s) {return s->isApproximate();});
246 std::list<std::string> names;
247 std::transform(this->
data->sources.cbegin(), this->data->sources.cend(),
248 std::back_inserter(names), [](
auto s) {return s->getName();});
249 return "GNSSTk NavLibrary (" +
cras::join(names,
", ") +
")";