8 #include <unordered_map>
10 #include <Eigen/Eigen>
18 #include <gnss_info_msgs/SatellitesList.h>
19 #include <gnss_info_msgs/SatellitesPositions.h>
20 #include <gnss_info_msgs/SkyView.h>
28 std::list<std::shared_ptr<OrbitalDataProvider>>
providers;
31 const ros::Time& time,
const cras::optional<bool>& precise)
const;
34 const ros::Time& startTime,
const ros::Time& endTime,
const cras::optional<bool>& precise)
const;
38 const ros::Time& time,
const cras::optional<bool>& precise)
const
44 const ros::Time& startTime,
const ros::Time& endTime,
const cras::optional<bool>& precise)
const
46 std::list<std::shared_ptr<OrbitalDataProvider>> result;
47 for (
const auto& provider : this->
providers)
49 if (precise.has_value() && *precise && !provider->isPrecise())
51 if (precise.has_value() && !*precise && !provider->isApproximate())
53 if (startTime > provider->getTimeRange().second)
55 if (endTime < provider->getTimeRange().first)
57 result.push_back(provider);
70 return this->
load(time, cras::nullopt);
75 for (
const auto& provider : this->
data->getRelevantProviders(time, precise))
77 if (provider->load(
time, precise))
86 return this->
load(startTime, endTime, cras::nullopt);
90 const ros::Time& startTime,
const ros::Time& endTime,
const cras::optional<bool>& precise)
92 for (
const auto& provider : this->
data->getRelevantProviders(startTime, endTime, precise))
94 if (provider->load(startTime, endTime, precise))
103 const ros::Time& time,
const gnss_info_msgs::SatellitesList& satellites)
105 return this->
getPositions(time, satellites, cras::nullopt);
109 const ros::Time& time,
const gnss_info_msgs::SatellitesList& satellites,
const cras::optional<bool>& precise)
111 this->
load(time, precise);
112 const auto providers = this->
data->getRelevantProviders(time, precise);
113 if (providers.empty())
114 return cras::make_unexpected(
"No satellite data was found");
116 std::unordered_map<uint32_t, gnss_info_msgs::SatelliteInfo> sats;
117 for (
const auto& sat : satellites.satellites)
118 sats[sat.satcat_id] = sat;
120 for (
const auto& provider : providers)
122 const auto maybePositions = provider->getECEFPositions(
time, sats);
123 if (!maybePositions.has_value())
125 ROS_DEBUG(
"Failed getting positions from provider %s at time %s: %s",
126 provider->getName().c_str(),
cras::to_string(
time).c_str(), maybePositions.error().c_str());
130 const auto& positions = *maybePositions;
131 if (positions.empty())
134 gnss_info_msgs::SatellitesPositions
msg;
136 msg.header.frame_id =
"ecef";
137 for (
const auto& [satcatId,
pos] : positions)
138 msg.satellites.push_back(
pos);
141 return cras::make_unexpected(
"Could not find a provider for satellite ECEF positions.");
145 const geographic_msgs::GeoPoint& position,
const gnss_info_msgs::SatellitesPositions& positions,
146 const double elevationMaskDeg)
148 return this->
getSkyView(position, positions, elevationMaskDeg, cras::nullopt);
152 const geographic_msgs::GeoPoint& position,
const gnss_info_msgs::SatellitesPositions& positions,
153 const double elevationMaskDeg,
const cras::optional<bool>& precise)
155 this->
load(positions.header.stamp, precise);
156 const auto providers = this->
data->getRelevantProviders(positions.header.stamp, precise);
157 if (providers.empty())
158 return cras::make_unexpected(
"No satellite data was found");
160 std::unordered_map<uint32_t, gnss_info_msgs::SatellitePosition> positionsMap;
161 for (
const auto&
pos : positions.satellites)
162 positionsMap[
pos.satcat_id] =
pos;
164 for (
const auto& provider : providers)
166 const auto maybeSkyView = provider->getSkyView(position, positionsMap, elevationMaskDeg);
167 if (!maybeSkyView.has_value())
169 ROS_DEBUG(
"Failed getting sky view from provider %s at time %s: %s",
174 const auto& skyView = *maybeSkyView;
175 gnss_info_msgs::SkyView
msg;
176 msg.header.stamp = positions.header.stamp;
177 msg.header.frame_id =
"WGS84";
178 msg.elevation_mask_deg = elevationMaskDeg;
179 msg.reference_position = position;
180 for (
const auto& [satcatId, sat] : skyView)
181 msg.satellites.push_back(sat);
186 return cras::make_unexpected(
"Could not find a provider for satellite sky positions.");
190 const std::unordered_map<uint32_t, gnss_info_msgs::SatelliteSkyPosition>& skyView)
const
195 gnss_info_msgs::DOP dop;
197 if (skyView.size() < 4)
199 dop.gdop = dop.pdop = dop.hdop = dop.vdop = dop.tdop = std::numeric_limits<float>::infinity();
203 Eigen::MatrixX4d A(skyView.size(), 4);
205 for (
const auto& [satcatId, skyPos] : skyView)
216 const Eigen::Matrix4d Q = (A.transpose() * A).
inverse();
217 dop.tdop = std::sqrt(Q(3, 3));
218 dop.vdop = std::sqrt(Q(2, 2));
219 dop.hdop = std::sqrt(Q(0, 0) + Q(1, 1));
220 dop.pdop = std::sqrt(Q(0, 0) + Q(1, 1) + Q(2, 2));
221 dop.gdop = std::sqrt(Q(0, 0) + Q(1, 1) + Q(2, 2) + Q(3, 3));
228 this->
data->providers.push_back(provider);