Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
route_operation_client.hpp
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 #ifndef NAV2_ROUTE__PLUGINS__ROUTE_OPERATION_CLIENT_HPP_
16 #define NAV2_ROUTE__PLUGINS__ROUTE_OPERATION_CLIENT_HPP_
17 
18 #include <memory>
19 #include <chrono>
20 #include <string>
21 
22 #include "rclcpp/rclcpp.hpp"
23 #include "rclcpp_lifecycle/lifecycle_node.hpp"
24 #include "nav2_route/interfaces/route_operation.hpp"
25 #include "nav2_core/route_exceptions.hpp"
26 #include "nav2_ros_common/node_utils.hpp"
27 #include "nav2_ros_common/service_client.hpp"
28 #include "std_srvs/srv/trigger.hpp"
29 
30 namespace nav2_route
31 {
32 
33 using namespace std::chrono_literals; // NOLINT
34 
61 template<typename SrvT>
63 {
64 public:
68  RouteOperationClient() = default;
69 
73  virtual ~RouteOperationClient() = default;
74 
80  virtual void configureEvent(
81  const nav2::LifecycleNode::SharedPtr /*node*/,
82  const std::string & /*name*/) {}
83 
87  virtual void populateRequest(
88  std::shared_ptr<typename SrvT::Request>/*request*/, const Metadata * /*mdata*/) {}
89 
94  std::shared_ptr<typename SrvT::Response>/*response*/) {return OperationResult();}
95 
96 protected:
100  void configure(
101  const nav2::LifecycleNode::SharedPtr node,
102  std::shared_ptr<nav2_costmap_2d::CostmapSubscriber>,
103  const std::string & name) final
104  {
105  RCLCPP_INFO(node->get_logger(), "Configuring route operation client: %s.", name.c_str());
106  name_ = name;
107  logger_ = node->get_logger();
108  node_ = node;
109 
110  nav2::declare_parameter_if_not_declared(
111  node, getName() + ".service_name", rclcpp::ParameterValue(""));
112  main_srv_name_ = node->get_parameter(getName() + ".service_name").as_string();
113 
114  configureEvent(node, name);
115 
116  // There exists a single central service to use, create client.
117  // If this is set to empty string after configuration, then the individual nodes will
118  // indicate the endpoint for the particular service call.
119  if (!main_srv_name_.empty()) {
120  main_client_ =
121  node->create_client<SrvT>(main_srv_name_, true);
122  }
123  }
124 
137  NodePtr node_achieved,
138  EdgePtr /*edge_entered*/,
139  EdgePtr /*edge_exited*/,
140  const Route & /*route*/,
141  const geometry_msgs::msg::PoseStamped & /*curr_pose*/,
142  const Metadata * mdata) final
143  {
144  auto req = std::make_shared<typename SrvT::Request>();
145  std::shared_ptr<typename SrvT::Response> response;
146  populateRequest(req, mdata);
147 
148  std::string srv_name;
149  srv_name = mdata->getValue<std::string>("service_name", srv_name);
150  if (srv_name.empty() && !main_client_) {
152  "Route operation service (" + getName() + ") needs 'server_name' "
153  "set in the param file or in the operation's metadata!");
154  }
155 
156  try {
157  if (srv_name.empty()) {
158  srv_name = main_srv_name_;
159  response = main_client_->invoke(req, std::chrono::nanoseconds(500ms));
160  } else {
161  auto node = node_.lock();
162  if (!node) {
164  "Route operation service (" + getName() + ") failed to lock node.");
165  }
166  auto client =
167  node->create_client<SrvT>(srv_name, true);
168  response = client->invoke(req, std::chrono::nanoseconds(500ms));
169  }
170  } catch (const std::exception & e) {
172  "Route operation service (" + getName() + ") failed to call service: " +
173  srv_name + " at Node " + std::to_string(node_achieved->nodeid));
174  }
175 
176  RCLCPP_INFO(
177  logger_,
178  "%s: Processed operation at Node %i with service %s.",
179  name_.c_str(), node_achieved->nodeid, srv_name.c_str());
180  return processResponse(response);
181  }
182 
187  std::string getName() override {return name_;}
188 
194  RouteOperationType processType() final {return RouteOperationType::ON_GRAPH;}
195 
196  std::string name_, main_srv_name_;
197  std::atomic_bool reroute_;
198  rclcpp::Logger logger_{rclcpp::get_logger("RouteOperationClient")};
199  typename nav2::ServiceClient<SrvT>::SharedPtr main_client_;
200  nav2::LifecycleNode::WeakPtr node_;
201 };
202 
203 } // namespace nav2_route
204 
205 #endif // NAV2_ROUTE__PLUGINS__ROUTE_OPERATION_CLIENT_HPP_
A route operation base class to trigger a service event at a node or edge. This is meant to be named ...
virtual OperationResult processResponse(std::shared_ptr< typename SrvT::Response >)
Process response from service to populate a result, if necessary.
void configure(const nav2::LifecycleNode::SharedPtr node, std::shared_ptr< nav2_costmap_2d::CostmapSubscriber >, const std::string &name) final
Configure.
virtual void populateRequest(std::shared_ptr< typename SrvT::Request >, const Metadata *)
Populate request with details for service, if necessary.
RouteOperationType processType() final
Indication that the adjust speed limit route operation is performed on all state changes.
virtual void configureEvent(const nav2::LifecycleNode::SharedPtr, const std::string &)
Configure client with any necessary parameters, etc. May change or reset main_srv_name_ variable to c...
virtual ~RouteOperationClient()=default
destructor
RouteOperationClient()=default
Constructor.
std::string getName() override
Get name of the plugin for parameter scope mapping.
OperationResult perform(NodePtr node_achieved, EdgePtr, EdgePtr, const Route &, const geometry_msgs::msg::PoseStamped &, const Metadata *mdata) final
The main operation to call a service of arbitrary type and arbitrary name.
A plugin interface to perform an operation while tracking the route such as triggered from the graph ...
An object representing edges between nodes.
Definition: types.hpp:134
An object to store arbitrary metadata regarding nodes from the graph file.
Definition: types.hpp:35
An object to store the nodes in the graph file.
Definition: types.hpp:183
a struct to hold return from an operation
An ordered set of nodes and edges corresponding to the planned route.
Definition: types.hpp:211