Nav2 Navigation Stack - lyrical  lyrical
ROS 2 Navigation Stack
graph_loader.cpp
1 // Copyright (c) 2025, Open Navigation LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <memory>
16 
17 #include "nav2_route/graph_loader.hpp"
18 #include "nav2_ros_common/tf2_factories.hpp"
19 
20 namespace nav2_route
21 {
22 
24  nav2::LifecycleNode::SharedPtr node,
25  nav2::TransformBuffer::SharedPtr tf,
26  const std::string frame)
27 : plugin_loader_("nav2_route", "nav2_route::GraphFileLoader"),
28  default_plugin_id_("GeoJsonGraphFileLoader")
29 {
30  logger_ = node->get_logger();
31  tf_ = tf;
32  route_frame_ = frame;
33 
34  graph_filepath_ = node->declare_or_get_parameter(
35  "graph_filepath", std::string(""));
36 
37  // Default Graph Parser
38  auto graph_file_loader_id = node->declare_or_get_parameter(
39  "graph_file_loader", default_plugin_id_);
40  if (graph_file_loader_id == default_plugin_id_) {
41  nav2::declare_parameter_if_not_declared(
42  node, default_plugin_id_ + ".plugin",
43  rclcpp::ParameterValue("nav2_route::GeoJsonGraphFileLoader"));
44  }
45 
46  // Create graph file loader plugin
47  try {
48  plugin_type_ = nav2::get_plugin_type_param(node, graph_file_loader_id);
49  graph_file_loader_ = plugin_loader_.createSharedInstance((plugin_type_));
50  RCLCPP_INFO(
51  logger_, "Created GraphFileLoader %s of type %s",
52  graph_file_loader_id.c_str(), plugin_type_.c_str());
53  graph_file_loader_->configure(node);
54  } catch (pluginlib::PluginlibException & ex) {
55  RCLCPP_FATAL(
56  logger_,
57  "Failed to create GraphFileLoader. Exception: %s", ex.what());
58  throw ex;
59  }
60 }
61 
63  Graph & graph,
64  GraphToIDMap & graph_to_id_map,
65  const std::string & filepath)
66 {
67  if (filepath.empty()) {
68  RCLCPP_ERROR(
69  logger_, "The graph filepath was not provided.");
70  return false;
71  }
72 
73  RCLCPP_INFO(
74  logger_,
75  "Loading graph file from %s, by parser %s", filepath.c_str(), plugin_type_.c_str());
76 
77  if (!graph_file_loader_->loadGraphFromFile(graph, graph_to_id_map, filepath)) {
78  return false;
79  }
80 
81  if (!transformGraph(graph)) {
82  RCLCPP_WARN(
83  logger_,
84  "Failed to transform nodes graph file (%s) to %s!", filepath.c_str(), route_frame_.c_str());
85  return false;
86  }
87 
88  return true;
89 }
90 
92  Graph & graph,
93  GraphToIDMap & graph_to_id_map)
94 {
95  if (graph_filepath_.empty()) {
96  RCLCPP_INFO(logger_, "No graph file provided to load yet.");
97  return true;
98  }
99 
100  RCLCPP_INFO(
101  logger_,
102  "Loading graph file from %s, by parser %s", graph_filepath_.c_str(), plugin_type_.c_str());
103 
104  if (!graph_file_loader_->loadGraphFromFile(graph, graph_to_id_map, graph_filepath_)) {
105  return false;
106  }
107 
108  if (!transformGraph(graph)) {
109  RCLCPP_WARN(
110  logger_,
111  "Failed to transform nodes graph file (%s) to %s!",
112  graph_filepath_.c_str(), route_frame_.c_str());
113  return false;
114  }
115 
116  return true;
117 }
118 
119 bool GraphLoader::transformGraph(Graph & graph)
120 {
121  std::unordered_map<std::string, tf2::Transform> cached_transforms;
122  for (auto & node : graph) {
123  std::string node_frame = node.coords.frame_id;
124  if (node_frame.empty() || node_frame == route_frame_) {
125  continue;
126  }
127 
128  if (cached_transforms.find(node_frame) == cached_transforms.end()) {
129  tf2::Transform tf_transform;
130  bool got_transform = nav2_util::getTransform(
131  node_frame, route_frame_, tf2::durationFromSec(0.1), tf_, tf_transform);
132 
133  if (!got_transform) {
134  return false;
135  }
136 
137  cached_transforms.insert({node_frame, tf_transform});
138  }
139 
140  tf2::Vector3 graph_coord(
141  node.coords.x,
142  node.coords.y,
143  0.0);
144 
145  tf2::Vector3 new_coord = cached_transforms[node_frame] * graph_coord;
146 
147  node.coords.x = static_cast<float>(new_coord.x());
148  node.coords.y = static_cast<float>(new_coord.y());
149  node.coords.frame_id = route_frame_;
150  }
151 
152  return true;
153 }
154 
155 } // namespace nav2_route
bool transformGraph(Graph &graph)
Transform the coordinates in the graph to the route frame.
GraphLoader(nav2::LifecycleNode::SharedPtr node, nav2::TransformBuffer::SharedPtr tf, const std::string frame)
A constructor for nav2_route::GraphLoader.
bool loadGraphFromFile(Graph &graph, GraphToIDMap &idx_map, const std::string &filepath)
Loads a graph object with file information from a filepath.
bool loadGraphFromParameter(Graph &graph, GraphToIDMap &idx_map)
Loads a graph object with file information from ROS parameter, if provided.