NASA Astrobee Robot Software  0.19.1
Flight software for the Astrobee robots operating inside the International Space Station.
ff_service.h
Go to the documentation of this file.
1 /* Copyright (c) 2017, United States Government, as represented by the
2  * Administrator of the National Aeronautics and Space Administration.
3  *
4  * All rights reserved.
5  *
6  * The Astrobee platform is licensed under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations
16  * under the License.
17  */
18 
19 #ifndef FF_UTIL_FF_SERVICE_H_
20 #define FF_UTIL_FF_SERVICE_H_
21 
22 // ROS includes
23 #include <ros/ros.h>
24 
25 // C++ includes
26 #include <string>
27 #include <functional>
28 #include <memory>
29 
30 namespace ff_util {
31 
33 
34 // This is a simple wrapper around a ROS service client, which forces the connection to be persistent, and
35 // handles reconnection if the connection is dropped. This improves the performance of the service call as
36 // the connection is not established on each query, at the expense of a little more complexity.
37 
38 template < class ServiceSpec >
40  protected:
41  enum State {
42  WAITING_FOR_CREATE = 0, // Connect() has not been called
43  WAITING_FOR_CONNECT = 1, // Waiting to connect to server
44  WAITING_FOR_CALL = 2 // Connection established, waiting on call
45  };
46  static constexpr double DEFAULT_TIMEOUT_CONNECTED = 10.0;
47  static constexpr double DEFAULT_POLL_DURATION = 0.1;
48 
49  public:
50  // Callback types
51  typedef std::function < void (void) > ConnectedCallbackType;
52  typedef std::function < void (void) > TimeoutCallbackType;
53 
54  // Setters for callbacks
55  void SetTimeoutCallback(TimeoutCallbackType cb_timeout) { cb_timeout_ = cb_timeout; }
56  void SetConnectedCallback(ConnectedCallbackType cb_connected) { cb_connected_ = cb_connected; }
57 
58  // Setters for timeouts
59  void SetConnectedTimeout(double to_connected) { to_connected_ = ros::Duration(to_connected); }
60 
61  // Constructor
65 
66  // Destructor
68 
69  // Try and connect to the service client, and return whether the connection is active. In the blocking
70  // case (NOT RECOMMENDED) if the server exists, then the return value should be true. The non-blocking
71  // case will always return false, and you will receive a callback when the connection is ready.
72  bool Create(ros::NodeHandle *nh, std::string const& topic) {
73  // Create a timer to poll to see if the server is connected [autostart]
74  timer_connected_ = nh->createTimer(to_connected_,
75  &FreeFlyerServiceClient::TimeoutCallback, this, true, false);
76  timer_poll_ = nh->createTimer(to_poll_,
77  &FreeFlyerServiceClient::ConnectPollCallback, this, false, false);
78  // Save the node handle and topic to support reconnects
79  nh_ = nh;
80  topic_ = topic;
81  // Create a persistent connection to the service
82  return IsConnected();
83  }
84 
85  // Check that we are connected to the server
86  bool IsConnected() {
87  if (service_.isValid())
88  return true;
89  ConnectPollCallback(ros::TimerEvent());
90  return false;
91  }
92 
93  // Call triggers a check for connection in order to prevent continual polling
94  bool Call(ServiceSpec & service) {
95  if (!IsConnected())
96  return false;
97  return service_.call(service);
98  }
99 
100  protected:
101  // Simple wrapper around an optional timer
102  void StartOptionalTimer(ros::Timer & timer, ros::Duration const& duration) {
103  if (duration.isZero()) return;
104  timer.stop();
105  timer.setPeriod(duration);
106  timer.start();
107  }
108 
109  // Called periodically until the server is connected
110  void ConnectPollCallback(ros::TimerEvent const& event) {
111  // Case: connected
112  if (service_.isValid()) {
113  if (state_ != WAITING_FOR_CALL) {
115  timer_connected_.stop();
116  timer_poll_.stop();
117  if (cb_connected_)
118  cb_connected_();
119  }
120  // Case: disconnected
121  } else {
122  service_ = nh_->serviceClient<ServiceSpec>(topic_, true);
126  }
127  }
128 
129  // Called when the service doesn't go active or a response isn't received
130  void TimeoutCallback(ros::TimerEvent const& event) {
131  timer_connected_.stop();
132  timer_poll_.stop();
133  if (cb_timeout_)
134  cb_timeout_();
135  }
136 
137  protected:
139  ros::Duration to_connected_;
140  ros::Duration to_poll_;
143  ros::ServiceClient service_;
144  ros::Timer timer_connected_;
145  ros::Timer timer_poll_;
146  std::string topic_;
147  ros::NodeHandle *nh_;
148 };
149 
150 } // namespace ff_util
151 
152 #endif // FF_UTIL_FF_SERVICE_H_
ff_util::FreeFlyerServiceClient::SetConnectedCallback
void SetConnectedCallback(ConnectedCallbackType cb_connected)
Definition: ff_service.h:56
ff_util::FreeFlyerServiceClient::DEFAULT_POLL_DURATION
static constexpr double DEFAULT_POLL_DURATION
Definition: ff_service.h:47
ff_util::FreeFlyerServiceClient::ConnectedCallbackType
std::function< void(void) > ConnectedCallbackType
Definition: ff_service.h:51
ff_util::FreeFlyerServiceClient::cb_connected_
ConnectedCallbackType cb_connected_
Definition: ff_service.h:142
ff_util::FreeFlyerServiceClient
Definition: ff_service.h:39
ff_util::FreeFlyerServiceClient::topic_
std::string topic_
Definition: ff_service.h:146
ff_util::FreeFlyerServiceClient::StartOptionalTimer
void StartOptionalTimer(ros::Timer &timer, ros::Duration const &duration)
Definition: ff_service.h:102
ff_util::FreeFlyerServiceClient::TimeoutCallbackType
std::function< void(void) > TimeoutCallbackType
Definition: ff_service.h:52
ff_util::FreeFlyerServiceClient::~FreeFlyerServiceClient
~FreeFlyerServiceClient()
Definition: ff_service.h:67
ff_util::FreeFlyerServiceClient::timer_connected_
ros::Timer timer_connected_
Definition: ff_service.h:144
ff_util::FreeFlyerServiceClient::IsConnected
bool IsConnected()
Definition: ff_service.h:86
ff_util::FreeFlyerServiceClient::to_poll_
ros::Duration to_poll_
Definition: ff_service.h:140
ff_util::FreeFlyerServiceClient::TimeoutCallback
void TimeoutCallback(ros::TimerEvent const &event)
Definition: ff_service.h:130
ff_util::FreeFlyerServiceClient::FreeFlyerServiceClient
FreeFlyerServiceClient()
Definition: ff_service.h:62
ff_util::FreeFlyerServiceClient::WAITING_FOR_CONNECT
@ WAITING_FOR_CONNECT
Definition: ff_service.h:43
ff_util::FreeFlyerServiceClient::to_connected_
ros::Duration to_connected_
Definition: ff_service.h:139
ff_util::FreeFlyerServiceClient< ff_msgs::GetPipelines >::State
State
Definition: ff_service.h:41
ff_util::FreeFlyerServiceClient::cb_timeout_
TimeoutCallbackType cb_timeout_
Definition: ff_service.h:141
ff_util::FreeFlyerServiceClient::SetConnectedTimeout
void SetConnectedTimeout(double to_connected)
Definition: ff_service.h:59
ff_util::FreeFlyerServiceClient::WAITING_FOR_CALL
@ WAITING_FOR_CALL
Definition: ff_service.h:44
ff_util::FreeFlyerServiceClient::WAITING_FOR_CREATE
@ WAITING_FOR_CREATE
Definition: ff_service.h:42
ff_util::FreeFlyerServiceClient::nh_
ros::NodeHandle * nh_
Definition: ff_service.h:147
ff_util::FreeFlyerServiceClient::state_
State state_
Definition: ff_service.h:138
ff_util::FreeFlyerServiceClient::service_
ros::ServiceClient service_
Definition: ff_service.h:143
ff_util::FreeFlyerServiceClient::DEFAULT_TIMEOUT_CONNECTED
static constexpr double DEFAULT_TIMEOUT_CONNECTED
Definition: ff_service.h:46
ff_util::FreeFlyerServiceClient::timer_poll_
ros::Timer timer_poll_
Definition: ff_service.h:145
ff_util::FreeFlyerServiceClient::ConnectPollCallback
void ConnectPollCallback(ros::TimerEvent const &event)
Definition: ff_service.h:110
ff_util
Definition: config_client.h:31
ff_util::FreeFlyerServiceClient::Call
bool Call(ServiceSpec &service)
Definition: ff_service.h:94
ff_util::FreeFlyerServiceClient::Create
bool Create(ros::NodeHandle *nh, std::string const &topic)
Definition: ff_service.h:72
ff_util::FreeFlyerServiceClient::SetTimeoutCallback
void SetTimeoutCallback(TimeoutCallbackType cb_timeout)
Definition: ff_service.h:55