action_client.h
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2008, Willow Garage, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34 
35 #ifndef ACTIONLIB__CLIENT__ACTION_CLIENT_H_
36 #define ACTIONLIB__CLIENT__ACTION_CLIENT_H_
37 
41 
42 #include <boost/thread/condition.hpp>
43 #include <string>
44 
45 #include "ros/ros.h"
47 
48 namespace actionlib
49 {
50 
58 template<class ActionSpec>
60 {
61 public:
63 
64 private:
65  ACTION_DEFINITION(ActionSpec)
66  typedef ActionClient<ActionSpec> ActionClientT;
67  typedef boost::function<void (GoalHandle)> TransitionCallback;
68  typedef boost::function<void (GoalHandle, const FeedbackConstPtr &)> FeedbackCallback;
69  typedef boost::function<void (const ActionGoalConstPtr)> SendGoalFunc;
70 
71 public:
80  ActionClient(const std::string & name, ros::CallbackQueueInterface * queue = NULL)
81  : n_(name), guard_(new DestructionGuard()),
83  {
84  initClient(queue);
85  }
86 
97  ActionClient(const ros::NodeHandle & n, const std::string & name,
98  ros::CallbackQueueInterface * queue = NULL)
99  : n_(n, name), guard_(new DestructionGuard()),
101  {
102  initClient(queue);
103  }
104 
106  {
107  ROS_DEBUG_NAMED("actionlib", "ActionClient: Waiting for destruction guard to clean up");
108  guard_->destruct();
109  ROS_DEBUG_NAMED("actionlib", "ActionClient: destruction guard destruct() done");
110  }
111 
112 
118  GoalHandle sendGoal(const Goal & goal,
119  TransitionCallback transition_cb = TransitionCallback(),
120  FeedbackCallback feedback_cb = FeedbackCallback())
121  {
122  ROS_DEBUG_NAMED("actionlib", "about to start initGoal()");
123  GoalHandle gh = manager_.initGoal(goal, transition_cb, feedback_cb);
124  ROS_DEBUG_NAMED("actionlib", "Done with initGoal()");
125 
126  return gh;
127  }
128 
136  {
137  actionlib_msgs::GoalID cancel_msg;
138  // CancelAll policy encoded by stamp=0, id=0
139  cancel_msg.stamp = ros::Time(0, 0);
140  cancel_msg.id = "";
141  cancel_pub_.publish(cancel_msg);
142  }
143 
149  {
150  actionlib_msgs::GoalID cancel_msg;
151  cancel_msg.stamp = time;
152  cancel_msg.id = "";
153  cancel_pub_.publish(cancel_msg);
154  }
155 
170  {
171  // if ros::Time::isSimTime(), then wait for it to become valid
172  if (!ros::Time::waitForValid(ros::WallDuration(timeout.sec, timeout.nsec))) {
173  return false;
174  }
175 
176  if (connection_monitor_) {
177  return connection_monitor_->waitForActionServerToStart(timeout, n_);
178  } else {
179  return false;
180  }
181  }
182 
188  {
189  return connection_monitor_->isServerConnected();
190  }
191 
192 private:
194 
197 
200 
201  boost::shared_ptr<ConnectionMonitor> connection_monitor_; // Have to destroy subscribers and publishers before the connection_monitor_, since we call callbacks in the connection_monitor_
202 
206 
207  void sendGoalFunc(const ActionGoalConstPtr & action_goal)
208  {
209  goal_pub_.publish(action_goal);
210  }
211 
212  void sendCancelFunc(const actionlib_msgs::GoalID & cancel_msg)
213  {
214  cancel_pub_.publish(cancel_msg);
215  }
216 
218  {
220  // read parameters indicating publish/subscribe queue sizes
221  int pub_queue_size;
222  int sub_queue_size;
223  n_.param("actionlib_client_pub_queue_size", pub_queue_size, 10);
224  n_.param("actionlib_client_sub_queue_size", sub_queue_size, 1);
225  if (pub_queue_size < 0) {pub_queue_size = 10;}
226  if (sub_queue_size < 0) {sub_queue_size = 1;}
227 
228  status_sub_ = queue_subscribe("status", static_cast<uint32_t>(sub_queue_size),
229  &ActionClientT::statusCb, this, queue);
230  feedback_sub_ = queue_subscribe("feedback", static_cast<uint32_t>(sub_queue_size),
231  &ActionClientT::feedbackCb, this, queue);
232  result_sub_ = queue_subscribe("result", static_cast<uint32_t>(sub_queue_size),
233  &ActionClientT::resultCb, this, queue);
234 
235  connection_monitor_.reset(new ConnectionMonitor(feedback_sub_, result_sub_));
236 
237  // Start publishers and subscribers
238  goal_pub_ = queue_advertise<ActionGoal>("goal", static_cast<uint32_t>(pub_queue_size),
239  boost::bind(&ConnectionMonitor::goalConnectCallback, connection_monitor_, _1),
240  boost::bind(&ConnectionMonitor::goalDisconnectCallback, connection_monitor_, _1),
241  queue);
242  cancel_pub_ =
243  queue_advertise<actionlib_msgs::GoalID>("cancel", static_cast<uint32_t>(pub_queue_size),
244  boost::bind(&ConnectionMonitor::cancelConnectCallback, connection_monitor_, _1),
245  boost::bind(&ConnectionMonitor::cancelDisconnectCallback, connection_monitor_, _1),
246  queue);
247 
248  manager_.registerSendGoalFunc(boost::bind(&ActionClientT::sendGoalFunc, this, _1));
249  manager_.registerCancelFunc(boost::bind(&ActionClientT::sendCancelFunc, this, _1));
250  }
251 
252  template<class M>
253  ros::Publisher queue_advertise(const std::string & topic, uint32_t queue_size,
254  const ros::SubscriberStatusCallback & connect_cb,
255  const ros::SubscriberStatusCallback & disconnect_cb,
257  {
259  ops.init<M>(topic, queue_size, connect_cb, disconnect_cb);
261  ops.latch = false;
262  ops.callback_queue = queue;
263  return n_.advertise(ops);
264  }
265 
266  template<class M, class T>
267  ros::Subscriber queue_subscribe(const std::string & topic, uint32_t queue_size, void (T::* fp)(
268  const ros::MessageEvent<M const> &), T * obj, ros::CallbackQueueInterface * queue)
269  {
271  ops.callback_queue = queue;
272  ops.topic = topic;
273  ops.queue_size = queue_size;
274  ops.md5sum = ros::message_traits::md5sum<M>();
275  ops.datatype = ros::message_traits::datatype<M>();
278  boost::bind(fp, obj, _1)
279  )
280  );
281  return n_.subscribe(ops);
282  }
283 
285  {
286  ROS_DEBUG_NAMED("actionlib", "Getting status over the wire.");
287  if (connection_monitor_) {
288  connection_monitor_->processStatus(
289  status_array_event.getConstMessage(), status_array_event.getPublisherName());
290  }
291  manager_.updateStatuses(status_array_event.getConstMessage());
292  }
293 
295  {
296  manager_.updateFeedbacks(action_feedback.getConstMessage());
297  }
298 
300  {
301  manager_.updateResults(action_result.getConstMessage());
302  }
303 };
304 
305 
306 } // namespace actionlib
307 
308 #endif // ACTIONLIB__CLIENT__ACTION_CLIENT_H_
void sendGoalFunc(const ActionGoalConstPtr &action_goal)
boost::function< void(const SingleSubscriberPublisher &)> SubscriberStatusCallback
void statusCb(const ros::MessageEvent< actionlib_msgs::GoalStatusArray const > &status_array_event)
ros::Publisher cancel_pub_
void cancelGoalsAtAndBeforeTime(const ros::Time &time)
Cancel all goals that were stamped at and before the specified time.
void publish(const boost::shared_ptr< M > &message) const
void goalConnectCallback(const ros::SingleSubscriberPublisher &pub)
bool isServerConnected()
Checks if the action client is successfully connected to the action server.
void init(const std::string &_topic, uint32_t _queue_size, const SubscriberStatusCallback &_connect_cb=SubscriberStatusCallback(), const SubscriberStatusCallback &_disconnect_cb=SubscriberStatusCallback())
GoalManager< ActionSpec > manager_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ros::Subscriber result_sub_
void goalDisconnectCallback(const ros::SingleSubscriberPublisher &pub)
void updateFeedbacks(const ActionFeedbackConstPtr &action_feedback)
ros::Subscriber status_sub_
ClientGoalHandle< ActionSpec > GoalHandle
Definition: action_client.h:62
ros::Subscriber queue_subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(const ros::MessageEvent< M const > &), T *obj, ros::CallbackQueueInterface *queue)
void cancelConnectCallback(const ros::SingleSubscriberPublisher &pub)
bool waitForActionServerToStart(const ros::Duration &timeout=ros::Duration(0, 0))
Waits for the ActionServer to connect to this client Often, it can take a second for the action serve...
void updateResults(const ActionResultConstPtr &action_result)
Full interface to an ActionServer.
Definition: action_client.h:59
boost::shared_ptr< SubscriptionCallbackHelper > SubscriptionCallbackHelperPtr
ros::Publisher goal_pub_
void sendCancelFunc(const actionlib_msgs::GoalID &cancel_msg)
void feedbackCb(const ros::MessageEvent< ActionFeedback const > &action_feedback)
const std::string & getPublisherName() const
GoalHandle sendGoal(const Goal &goal, TransitionCallback transition_cb=TransitionCallback(), FeedbackCallback feedback_cb=FeedbackCallback())
Sends a goal to the ActionServer, and also registers callbacks.
#define ROS_DEBUG_NAMED(name,...)
const boost::shared_ptr< ConstMessage > & getConstMessage() const
SubscriptionCallbackHelperPtr helper
VoidConstPtr tracked_object
ros::Publisher queue_advertise(const std::string &topic, uint32_t queue_size, const ros::SubscriberStatusCallback &connect_cb, const ros::SubscriberStatusCallback &disconnect_cb, ros::CallbackQueueInterface *queue)
void cancelAllGoals()
Cancel all goals currently running on the action server.
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void cancelDisconnectCallback(const ros::SingleSubscriberPublisher &pub)
boost::shared_ptr< DestructionGuard > guard_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
This class protects an object from being destructed until all users of that object relinquish control...
#define ACTION_DEFINITION(ActionSpec)
void registerSendGoalFunc(SendGoalFunc send_goal_func)
boost::function< void(const ActionGoalConstPtr)> SendGoalFunc
Definition: action_client.h:69
boost::function< void(GoalHandle)> TransitionCallback
Definition: action_client.h:67
void updateStatuses(const actionlib_msgs::GoalStatusArrayConstPtr &status_array)
Client side handle to monitor goal progress.
ros::Subscriber feedback_sub_
CallbackQueueInterface * callback_queue
void initClient(ros::CallbackQueueInterface *queue)
void registerCancelFunc(CancelFunc cancel_func)
static bool waitForValid()
boost::function< void(GoalHandle, const FeedbackConstPtr &)> FeedbackCallback
Definition: action_client.h:68
boost::shared_ptr< void > VoidPtr
void resultCb(const ros::MessageEvent< ActionResult const > &action_result)
CallbackQueueInterface * callback_queue
boost::shared_ptr< ConnectionMonitor > connection_monitor_
ActionClient(const ros::NodeHandle &n, const std::string &name, ros::CallbackQueueInterface *queue=NULL)
Constructor with namespacing options.
Definition: action_client.h:97


actionlib
Author(s): Eitan Marder-Eppstein, Vijay Pradeep, Mikael Arguedas
autogenerated on Mon Aug 24 2020 03:40:47