Nav2 Navigation Stack - humble  humble
ROS 2 Navigation Stack
lifecycle_service_client.cpp
1 // Copyright (c) 2019 Intel Corporation
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 "nav2_util/lifecycle_service_client.hpp"
16 
17 #include <string>
18 #include <chrono>
19 #include <memory>
20 
21 #include "lifecycle_msgs/srv/change_state.hpp"
22 #include "lifecycle_msgs/srv/get_state.hpp"
23 
24 using nav2_util::generate_internal_node;
25 using std::chrono::seconds;
26 using std::make_shared;
27 using std::string;
28 using namespace std::chrono_literals;
29 
30 namespace nav2_util
31 {
32 
33 LifecycleServiceClient::LifecycleServiceClient(const string & lifecycle_node_name)
34 : node_(generate_internal_node(lifecycle_node_name + "_lifecycle_client")),
35  change_state_(lifecycle_node_name + "/change_state", node_),
36  get_state_(lifecycle_node_name + "/get_state", node_)
37 {
38  // Block until server is up
39  rclcpp::Rate r(20);
40  while (!get_state_.wait_for_service(2s)) {
41  RCLCPP_INFO(
42  node_->get_logger(), "Waiting for service %s...", get_state_.getServiceName().c_str());
43  r.sleep();
44  }
45 }
46 
47 LifecycleServiceClient::LifecycleServiceClient(
48  const string & lifecycle_node_name,
49  rclcpp::Node::SharedPtr parent_node)
50 : node_(parent_node),
51  change_state_(lifecycle_node_name + "/change_state", node_),
52  get_state_(lifecycle_node_name + "/get_state", node_)
53 {
54  // Block until server is up
55  rclcpp::Rate r(20);
56  while (!get_state_.wait_for_service(2s)) {
57  RCLCPP_INFO(
58  node_->get_logger(), "Waiting for service %s...", get_state_.getServiceName().c_str());
59  r.sleep();
60  }
61 }
62 
63 bool LifecycleServiceClient::change_state(
64  const uint8_t transition,
65  const seconds timeout)
66 {
67  if (!change_state_.wait_for_service(timeout)) {
68  throw std::runtime_error("change_state service is not available!");
69  }
70 
71  auto request = std::make_shared<lifecycle_msgs::srv::ChangeState::Request>();
72  request->transition.id = transition;
73  auto response = change_state_.invoke(request, timeout);
74  return response.get();
75 }
76 
77 bool LifecycleServiceClient::change_state(
78  std::uint8_t transition)
79 {
80  if (!change_state_.wait_for_service(5s)) {
81  throw std::runtime_error("change_state service is not available!");
82  }
83 
84  auto request = std::make_shared<lifecycle_msgs::srv::ChangeState::Request>();
85  auto response = std::make_shared<lifecycle_msgs::srv::ChangeState::Response>();
86  request->transition.id = transition;
87  return change_state_.invoke(request, response);
88 }
89 
90 uint8_t LifecycleServiceClient::get_state(
91  const seconds timeout)
92 {
93  if (!get_state_.wait_for_service(timeout)) {
94  throw std::runtime_error("get_state service is not available!");
95  }
96 
97  auto request = std::make_shared<lifecycle_msgs::srv::GetState::Request>();
98  auto result = get_state_.invoke(request, timeout);
99  return result->current_state.id;
100 }
101 
102 } // namespace nav2_util