rtt_simple_action_server.h
Go to the documentation of this file.
1 #ifndef RTT_SIMPLE_ACTION_SERVER_HPP
2 #define RTT_SIMPLE_ACTION_SERVER_HPP
3 
4 #include <stdexcept>
5 #include <boost/bind.hpp>
6 #include <boost/function.hpp>
7 
11 
12 namespace rtt_actionlib {
13 
14 template <class ActionSpec> class RTTSimpleActionServer
15 {
16  protected:
17  // GoalHandle
19  // Goal, Feedback, Result typedefs
20  ACTION_DEFINITION(ActionSpec);
21 
22  protected:
24  GoalHandle goal_active;
25  GoalHandle goal_pending;
26 
27  // callbacks
28  boost::function<void(const Goal&)> newGoalHook;
29  boost::function<void()> cancelGoalHook;
30 
31  protected:
32 
33  void goalCallback(GoalHandle gh);
34  void cancelCallback(GoalHandle gh);
35 
36  public:
37 
45  {
46  if (!owner_service) throw std::invalid_argument("RTTSimpleActionServer: owner pointer must be valid.");
47  action_server.addPorts(owner_service);
48  action_server.registerGoalCallback(boost::bind(&RTTSimpleActionServer<ActionSpec>::goalCallback, this, _1));
50  }
51 
55  bool ready() {
56  return action_server.ready();
57  }
58 
59 
64  bool start(bool publish_feedback = false);
65 
69  void shutdown() {
70  action_server.shutdown();
71  }
72 
76  bool isActive() const {
77  return goal_active.isValid() && goal_active.getGoalStatus().status == actionlib_msgs::GoalStatus::ACTIVE;
78  }
79 
83  bool isPreempting() const {
84  return goal_active.isValid() && goal_active.getGoalStatus().status == actionlib_msgs::GoalStatus::PREEMPTING;
85  }
86 
90  bool isPending() const {
91  return goal_pending.isValid() && goal_pending.getGoalStatus().status == actionlib_msgs::GoalStatus::PENDING;
92  }
93 
98  if (isActive()) return goal_active.getGoal();
99  else return boost::shared_ptr<const Goal>(); // return NULL
100  // else nullptr;
101  }
102 
107  if (isPending()) return goal_pending.getGoal();
108  else return boost::shared_ptr<const Goal>(); // return NULL
109  // else nullptr;
110  }
111 
118  bool acceptPending(const Result& result, const std::string& msg = "");
119 
126  bool rejectPending(const Result& result, const std::string& msg = "");
127 
134  bool publishFeedback(const Feedback& feedpack);
135 
142  bool abortActive(const Result& result, const std::string& msg = "");
143 
150  bool cancelActive(const Result& result, const std::string& msg = "");
151 
158  bool succeedActive(const Result& result, const std::string& msg = "");
159 
164  void setGoalHook(boost::function< void(const Goal&)> _newGoalHook) {
165  newGoalHook = _newGoalHook;
166  }
167 
172  void setCancelHook(boost::function< void()> _cancelGoalHook) {
173  cancelGoalHook = _cancelGoalHook;
174  }
175 };
176 
177 template <class ActionSpec> bool RTTSimpleActionServer<ActionSpec>::start(bool publish_feedback)
178 {
179  if (ready()) {
180  action_server.start();
181  if (publish_feedback) action_server.initialize();
182  return true;
183  }
184  else return false;
185 }
186 
187 template <class ActionSpec> bool RTTSimpleActionServer<ActionSpec>::acceptPending(const Result& result, const std::string& msg)
188 {
189  if (isPending()) {
190  if (goal_active.isValid()) {
191  switch (goal_active.getGoalStatus().status) {
192  case actionlib_msgs::GoalStatus::ACTIVE:
193  case actionlib_msgs::GoalStatus::PREEMPTING:
194  goal_active.setAborted(result, msg);
195  break;
196  }
197  }
198  goal_pending.setAccepted();
199  goal_active = goal_pending;
200  return isActive();
201  }
202  else {
203  // if pending is in RECALLING cancelHook perform necessary actions
204  return false;
205  }
206 }
207 
208 template <class ActionSpec> bool RTTSimpleActionServer<ActionSpec>::rejectPending(const Result& result, const std::string& msg)
209 {
210  if (!goal_pending.isValid()) return false;
211  switch (goal_pending.getGoalStatus().status) {
212  case actionlib_msgs::GoalStatus::PENDING:
213  case actionlib_msgs::GoalStatus::RECALLING:
214  goal_pending.setRejected(result, msg);
215  return true;
216  }
217  return false;
218 }
219 
220 template <class ActionSpec> bool RTTSimpleActionServer<ActionSpec>::publishFeedback(const Feedback& feedpack)
221 {
222  if (!isActive()) return false;
223  goal_active.publishFeedback(feedpack);
224  return true;
225 }
226 
227 template <class ActionSpec> bool RTTSimpleActionServer<ActionSpec>::abortActive(const Result& result, const std::string& msg)
228 {
229  if (!goal_active.isValid()) return false;
230  switch (goal_active.getGoalStatus().status) {
231  case actionlib_msgs::GoalStatus::ACTIVE:
232  case actionlib_msgs::GoalStatus::PREEMPTING:
233  goal_active.setAborted(result, msg);
234  return true;
235  }
236  return false;
237 }
238 
239 template <class ActionSpec> bool RTTSimpleActionServer<ActionSpec>::cancelActive(const Result& result, const std::string& msg)
240 {
241  if (!goal_active.isValid()) return false;
242  switch (goal_active.getGoalStatus().status) {
243  case actionlib_msgs::GoalStatus::ACTIVE:
244  case actionlib_msgs::GoalStatus::PREEMPTING:
245  goal_active.setCanceled(result, msg);
246  return true;
247  }
248  return true;
249 }
250 
251 template <class ActionSpec> bool RTTSimpleActionServer<ActionSpec>::succeedActive(const Result& result, const std::string& msg)
252 {
253  if (!goal_active.isValid()) return false;
254  switch (goal_active.getGoalStatus().status) {
255  case actionlib_msgs::GoalStatus::ACTIVE:
256  case actionlib_msgs::GoalStatus::PREEMPTING:
257  goal_active.setSucceeded(result, msg);
258  return true;
259  }
260  return false;
261 }
262 
263 template <class ActionSpec> void RTTSimpleActionServer<ActionSpec>::goalCallback(GoalHandle gh)
264 {
265  if (goal_pending.isValid()) {
266  switch (goal_pending.getGoalStatus().status) {
267  case actionlib_msgs::GoalStatus::PENDING:
268  case actionlib_msgs::GoalStatus::RECALLING:
269  goal_pending.setRejected(Result(), "Pending goal is replaced by new received goal.");
270  break;
271  }
272  }
273  goal_pending = gh;
274  if (isPending() && newGoalHook) {
275  newGoalHook(*goal_pending.getGoal());
276  }
277 }
278 
279 template <class ActionSpec> void RTTSimpleActionServer<ActionSpec>::cancelCallback(GoalHandle gh) {
280  if (!gh.isValid()) return;
281  switch (gh.getGoalStatus().status) {
282  case actionlib_msgs::GoalStatus::ACTIVE:
283  case actionlib_msgs::GoalStatus::PREEMPTING:
284  case actionlib_msgs::GoalStatus::PENDING:
285  case actionlib_msgs::GoalStatus::RECALLING:
286  if (goal_active == gh) {
287  if (cancelGoalHook) cancelGoalHook();
288  // cancelActive(Result(), "Active goal is canceled by client request.");
289  }
290  else if (goal_pending == gh) {
291  gh.setCanceled(Result(), "Pending goal is canceled by client request.");
292  }
293  else {
294  gh.setCanceled(Result(), "Unknown goal.");
295  }
296  break;
297  }
298 }
299 
300 } // namespace rtt_actionlib
301 
302 #endif /*RTT_SIMPLE_ACTION_SERVER_HPP*/
void publishFeedback(const Feedback &feedback)
Orocos RTT-Based Action Server.
bool addPorts(RTT::Service::shared_ptr service, const bool create_topics=false, const std::string &topic_namespace="")
Add actionlib ports to a given rtt service.
void setGoalHook(boost::function< void(const Goal &)> _newGoalHook)
Setup goal hook.
actionlib::ServerGoalHandle< ActionSpec > GoalHandle
bool succeedActive(const Result &result, const std::string &msg="")
Succeed active goal. Succeed active goal with given result, do nothing if there is no active goal...
void setRejected(const Result &result=Result(), const std::string &text=std::string(""))
boost::shared_ptr< const Goal > getGoal() const
bool publishFeedback(const Feedback &feedpack)
Publish feedback on active goal. Publish feedback on active goal, do nothing if there is no active go...
void setCancelHook(boost::function< void()> _cancelGoalHook)
Setup cancel hook.
boost::shared_ptr< const Goal > getActiveGoal() const
void setCanceled(const Result &result=Result(), const std::string &text=std::string(""))
void setAccepted(const std::string &text=std::string(""))
void registerGoalCallback(boost::function< void(GoalHandle)> cb)
RTTSimpleActionServer(boost::shared_ptr< RTT::Service > owner_service)
void setSucceeded(const Result &result=Result(), const std::string &text=std::string(""))
bool start(bool publish_feedback=false)
bool ready()
Check if the server is ready to be started.
void registerCancelCallback(boost::function< void(GoalHandle)> cb)
void setAborted(const Result &result=Result(), const std::string &text=std::string(""))
boost::function< void(const Goal &)> newGoalHook
virtual void initialize()
Set up status publishing timers.
RTTActionServer< ActionSpec > action_server
boost::shared_ptr< const Goal > getPendingGoal() const
bool rejectPending(const Result &result, const std::string &msg="")
Reject pending goal. Reject pending goal with result, do nothing if there is no pending goal...
bool cancelActive(const Result &result, const std::string &msg="")
Cancel active goal. Cancel active goal with given result, do nothing if there is no active goal...
bool acceptPending(const Result &result, const std::string &msg="")
Accept pending goal. Accept pending goal, preempt the active goal with result if present. Do nothing if there is no pending goal.
actionlib_msgs::GoalStatus getGoalStatus() const
bool abortActive(const Result &result, const std::string &msg="")
Abort active goal. Abort active goal with given result, do nothing if there is no active goal...


rtt_actionlib
Author(s): Jonathan Bohren
autogenerated on Sat Jun 8 2019 18:06:05