Nav2 Navigation Stack - lyrical  lyrical
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  main_srv_name_ = node->declare_or_get_parameter(
111  getName() + ".service_name", std::string(""));
112 
113  configureEvent(node, name);
114 
115  // There exists a single central service to use, create client.
116  // If this is set to empty string after configuration, then the individual nodes will
117  // indicate the endpoint for the particular service call.
118  if (!main_srv_name_.empty()) {
119  main_client_ =
120  node->create_client<SrvT>(main_srv_name_, true);
121  }
122  }
123 
136  NodePtr node_achieved,
137  EdgePtr /*edge_entered*/,
138  EdgePtr /*edge_exited*/,
139  const Route & /*route*/,
140  const geometry_msgs::msg::PoseStamped & /*curr_pose*/,
141  const Metadata * mdata) final
142  {
143  auto req = std::make_shared<typename SrvT::Request>();
144  std::shared_ptr<typename SrvT::Response> response;
145  populateRequest(req, mdata);
146 
147  std::string srv_name;
148  srv_name = mdata->getValue<std::string>("service_name", srv_name);
149  if (srv_name.empty() && !main_client_) {
151  "Route operation service (" + getName() + ") needs 'server_name' "
152  "set in the param file or in the operation's metadata!");
153  }
154 
155  try {
156  if (srv_name.empty()) {
157  srv_name = main_srv_name_;
158  response = main_client_->invoke(req, std::chrono::nanoseconds(500ms));
159  } else {
160  auto node = node_.lock();
161  if (!node) {
163  "Route operation service (" + getName() + ") failed to lock node.");
164  }
165  auto client =
166  node->template create_client<SrvT>(srv_name, true);
167  response = client->invoke(req, std::chrono::nanoseconds(500ms));
168  }
169  } catch (const std::exception & e) {
171  "Route operation service (" + getName() + ") failed to call service: " +
172  srv_name + " at Node " + std::to_string(node_achieved->nodeid));
173  }
174 
175  RCLCPP_INFO(
176  logger_,
177  "%s: Processed operation at Node %i with service %s.",
178  name_.c_str(), node_achieved->nodeid, srv_name.c_str());
179  return processResponse(response);
180  }
181 
186  std::string getName() override {return name_;}
187 
193  RouteOperationType processType() final {return RouteOperationType::ON_GRAPH;}
194 
195  std::string name_, main_srv_name_;
196  std::atomic_bool reroute_;
197  rclcpp::Logger logger_{rclcpp::get_logger("RouteOperationClient")};
198  typename nav2::ServiceClient<SrvT>::SharedPtr main_client_;
199  nav2::LifecycleNode::WeakPtr node_;
200 };
201 
202 } // namespace nav2_route
203 
204 #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