rapid
A ROS robotics library.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
action_client.h
Go to the documentation of this file.
1 #ifndef _RAPID_ROS_ACTION_CLIENT_H_
2 #define _RAPID_ROS_ACTION_CLIENT_H_
3 
4 #include <string>
5 
6 #include "actionlib/action_definition.h"
7 #include "actionlib/client/simple_action_client.h"
8 #include "actionlib/client/simple_client_goal_state.h"
9 #include "ros/ros.h"
10 
11 namespace rapid_ros {
12 // DECLARATIONS ----------------------------------------------------------------
13 // Interface wrapper for SimpleActionClient.
14 // Supports only a subset of SimpleActionClient functionality, more will be
15 // added as needed.
16 template <class ActionSpec>
18  private:
19  ACTION_DEFINITION(ActionSpec)
20 
21  public:
23  virtual ResultConstPtr getResult() = 0;
24  virtual actionlib::SimpleClientGoalState getState() = 0;
25  virtual bool isServerConnected() = 0;
26  virtual void sendGoal(const Goal& goal) = 0;
27  virtual bool waitForResult(
28  const ros::Duration& timeout = ros::Duration(0, 0)) = 0;
29  virtual bool waitForServer(
30  const ros::Duration& timeout = ros::Duration(0, 0)) = 0;
31 };
32 
33 // Implements a SimpleActionClient by forwarding calls.
34 template <class ActionSpec>
35 class ActionClient : public ActionClientInterface<ActionSpec> {
36  private:
37  ACTION_DEFINITION(ActionSpec)
38  actionlib::SimpleActionClient<ActionSpec> client_;
39 
40  public:
41  ActionClient(const std::string& name, bool spin_thread = true);
42  ResultConstPtr getResult();
43  actionlib::SimpleClientGoalState getState();
44  bool isServerConnected();
45  void sendGoal(const Goal& goal);
46  bool waitForResult(const ros::Duration& timeout = ros::Duration(0, 0));
47  bool waitForServer(const ros::Duration& timeout = ros::Duration(0, 0));
48 };
49 
50 // A mock action client.
51 //
52 // One limitation of this mock is that it will work in single-threaded
53 // applications. Real SimpleActionClients don't necessarily work in
54 // single-threaded applications. It may be moot if spin_thread=true in the
55 // constructor, though, it's not well understood.
56 template <class ActionSpec>
57 class MockActionClient : public ActionClientInterface<ActionSpec> {
58  private:
59  ACTION_DEFINITION(ActionSpec)
60  Goal last_goal_;
61  Result result_;
62  ros::Duration result_delay_;
63  ros::Duration server_delay_;
64  actionlib::SimpleClientGoalState state_;
65  bool is_server_connected_;
66 
67  public:
68  // Mocked methods
70  ResultConstPtr getResult();
71  actionlib::SimpleClientGoalState getState();
72  bool isServerConnected() { return is_server_connected_; }
73  void sendGoal(const Goal& goal);
74  bool waitForResult(const ros::Duration& timeout = ros::Duration(0, 0));
75  bool waitForServer(const ros::Duration& timeout = ros::Duration(0, 0));
76 
77  // Mock helpers
78  // Get the last goal that was sent.
79  Goal last_goal() const { return last_goal_; }
80  // Set the result to be returned by waitForResult.
81  void set_result(const Result& result) { result_ = result; }
82  // Set the amount of time to simulate a delay while waiting for the result.
83  void set_result_delay(const ros::Duration& delay) { result_delay_ = delay; }
84  bool set_server_connected(bool connected) {
85  is_server_connected_ = connected;
86  }
87  // Set the amount of time to simulate a delay while waiting for the server.
88  void set_server_delay(const ros::Duration& delay) { server_delay_ = delay; }
89  void set_state(const actionlib::SimpleClientGoalState& state) {
90  state_ = state;
91  }
92 };
93 
94 // DEFINITIONS -----------------------------------------------------------------
95 // ActionClient definitions
96 template <class ActionSpec>
98  bool spin_thread)
99  : client_(name, spin_thread) {}
100 
101 template <class ActionSpec>
104  return client_.getResult();
105 }
106 
107 template <class ActionSpec>
108 actionlib::SimpleClientGoalState ActionClient<ActionSpec>::getState() {
109  return client_.getState();
110 }
111 
112 template <class ActionSpec>
114  return client_.isServerConnected();
115 }
116 
117 template <class ActionSpec>
118 void ActionClient<ActionSpec>::sendGoal(const Goal& goal) {
119  client_.sendGoal(goal);
120 }
121 
122 template <class ActionSpec>
123 bool ActionClient<ActionSpec>::waitForResult(const ros::Duration& timeout) {
124  return client_.waitForResult(timeout);
125 }
126 
127 template <class ActionSpec>
128 bool ActionClient<ActionSpec>::waitForServer(const ros::Duration& timeout) {
129  return client_.waitForServer(timeout);
130 }
131 
132 // MockActionClient definitions
133 template <class ActionSpec>
135  : last_goal_(),
136  result_(),
137  state_(actionlib::SimpleClientGoalState::SUCCEEDED),
138  result_delay_(0),
139  server_delay_(0),
140  is_server_connected_(true) {}
141 
142 template <class ActionSpec>
145  return ResultConstPtr(new Result(result_));
146 }
147 
148 template <class ActionSpec>
149 actionlib::SimpleClientGoalState MockActionClient<ActionSpec>::getState() {
150  return state_;
151 }
152 
153 template <class ActionSpec>
155  if (!is_server_connected_) {
156  ROS_ERROR("Sent goal even though server isn't connected!");
157  return;
158  }
159  last_goal_ = goal;
160 }
161 
162 template <class ActionSpec>
163 bool MockActionClient<ActionSpec>::waitForResult(const ros::Duration& timeout) {
164  if (!is_server_connected_) {
165  ROS_ERROR("Waiting for result even though server isn't connected!");
166  return false;
167  }
168  if (timeout > result_delay_) {
169  return true;
170  } else {
171  if (timeout.isZero()) {
172  ROS_WARN(
173  "waitForResult given infinite timeout, are you sure that's what you "
174  "want? Failing.");
175  }
176  return false;
177  }
178 }
179 
180 template <class ActionSpec>
181 bool MockActionClient<ActionSpec>::waitForServer(const ros::Duration& timeout) {
182  if (!is_server_connected_) {
183  ROS_ERROR("Waiting for server even though server isn't connected!");
184  return false;
185  }
186  if (timeout > server_delay_) {
187  return true;
188  } else {
189  if (timeout.isZero()) {
190  ROS_WARN(
191  "waitForServer given infinite timeout, are you sure that's what you "
192  "want? Failing.");
193  }
194  return false;
195  }
196 }
197 } // namespace rapid_ros
198 #endif // _RAPID_ROS_ACTION_CLIENT_H_
bool set_server_connected(bool connected)
Definition: action_client.h:84
void sendGoal(const Goal &goal)
bool waitForServer(const ros::Duration &timeout=ros::Duration(0, 0))
void sendGoal(const Goal &goal)
bool waitForResult(const ros::Duration &timeout=ros::Duration(0, 0))
actionlib::SimpleClientGoalState getState()
void set_server_delay(const ros::Duration &delay)
Definition: action_client.h:88
virtual bool isServerConnected()=0
void set_state(const actionlib::SimpleClientGoalState &state)
Definition: action_client.h:89
bool waitForServer(const ros::Duration &timeout=ros::Duration(0, 0))
ResultConstPtr getResult()
void set_result_delay(const ros::Duration &delay)
Definition: action_client.h:83
virtual ResultConstPtr getResult()=0
virtual actionlib::SimpleClientGoalState getState()=0
virtual void sendGoal(const Goal &goal)=0
actionlib::SimpleClientGoalState getState()
bool waitForResult(const ros::Duration &timeout=ros::Duration(0, 0))
ActionClient(const std::string &name, bool spin_thread=true)
Definition: action_client.h:97
ResultConstPtr getResult()
virtual bool waitForServer(const ros::Duration &timeout=ros::Duration(0, 0))=0
virtual bool waitForResult(const ros::Duration &timeout=ros::Duration(0, 0))=0
void set_result(const Result &result)
Definition: action_client.h:81