SMACC
Loading...
Searching...
No Matches
smacc_action_client_base.h
Go to the documentation of this file.
1/*****************************************************************************************************************
2 * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018
3 * Authors: Pablo Inigo Blasco, Brett Aldrich
4 *
5 ******************************************************************************************************************/
6
7#pragma once
8
10#include <smacc/smacc_signal.h>
11
12#include <boost/optional/optional_io.hpp>
13
14namespace smacc
15{
16namespace client_bases
17{
18using namespace smacc::default_events;
19
20template <typename ActionType>
22{
23public:
24 // Inside this macro you can find the typedefs for Goal and other types
25 ACTION_DEFINITION(ActionType);
26 typedef actionlib::SimpleActionClient<ActionType> ActionClient;
27 typedef actionlib::SimpleActionClient<ActionType> GoalHandle;
28
29 typedef typename ActionClient::SimpleDoneCallback SimpleDoneCallback;
30 typedef typename ActionClient::SimpleActiveCallback SimpleActiveCallback;
31 typedef typename ActionClient::SimpleFeedbackCallback SimpleFeedbackCallback;
32
33 SmaccActionClientBase(std::string actionServerName)
35 name_(actionServerName)
36 {
37 }
38
41 name_("")
42 {
43 }
44
45 static std::string getEventLabel()
46 {
47 auto type = TypeInfo::getTypeInfoFromType<ActionType>();
48 return type->getNonTemplatedTypeName();
49 }
50
52 {
53 }
54
56 std::string name_;
57
58 virtual void initialize() override
59 {
60 client_ = std::make_shared<ActionClient>(name_);
61 }
62
63 smacc::SmaccSignal<void(const ResultConstPtr &)> onSucceeded_;
64 smacc::SmaccSignal<void(const ResultConstPtr &)> onAborted_;
65 smacc::SmaccSignal<void(const ResultConstPtr &)> onPreempted_;
66 smacc::SmaccSignal<void(const ResultConstPtr &)> onRejected_;
67
68 // event creation/posting factory functions
69 std::function<void(ResultConstPtr)> postSuccessEvent;
70 std::function<void(ResultConstPtr)> postAbortedEvent;
71 std::function<void(ResultConstPtr)> postPreemptedEvent;
72 std::function<void(ResultConstPtr)> postRejectedEvent;
73
74 std::function<void(FeedbackConstPtr)> postFeedbackEvent;
75
79
80 template <typename EvType>
81 void postResultEvent(ResultConstPtr result)
82 {
83 auto *ev = new EvType();
84 //ev->client = this;
85 ev->resultMessage = *result;
86 ROS_INFO("Posting EVENT %s", demangleSymbol(typeid(ev).name()).c_str());
87 this->postEvent(ev);
88 }
89
90 template <typename TOrthogonal, typename TSourceObject>
92 {
93 // we create here all the event factory functions capturing the TOrthogonal
94 postSuccessEvent = [=](auto msg) { this->postResultEvent<EvActionSucceeded<TSourceObject, TOrthogonal>>(msg); };
95 postAbortedEvent = [=](auto msg) { this->postResultEvent<EvActionAborted<TSourceObject, TOrthogonal>>(msg); };
96 postPreemptedEvent = [=](auto msg) { this->postResultEvent<EvActionPreempted<TSourceObject, TOrthogonal>>(msg); };
97 postRejectedEvent = [=](auto msg) { this->postResultEvent<EvActionRejected<TSourceObject, TOrthogonal>>(msg); };
98 postFeedbackEvent = [=](auto msg) {
99 auto actionFeedbackEvent = new EvActionFeedback<Feedback, TOrthogonal>();
100 actionFeedbackEvent->client = this;
101 actionFeedbackEvent->feedbackMessage = *msg;
102 this->postEvent(actionFeedbackEvent);
103 ROS_DEBUG("[%s] FEEDBACK EVENT", demangleType(typeid(*this)).c_str());
104 };
105
106 done_cb = boost::bind(&SmaccActionClientBase<ActionType>::onResult, this, _1, _2);
107 //active_cb;
109 }
110
111 template <typename T>
112 boost::signals2::connection onSucceeded(void (T::*callback)(ResultConstPtr &), T *object)
113 {
114 return this->getStateMachine()->createSignalConnection(onSucceeded_, callback, object);
115 }
116
117 template <typename T>
118 boost::signals2::connection onSucceeded(std::function<void(ResultConstPtr &)> callback)
119 {
120 return this->getStateMachine()->createSignalConnection(onSucceeded_, callback);
121 }
122
123 template <typename T>
124 boost::signals2::connection onAborted(void (T::*callback)(ResultConstPtr &), T *object)
125 {
126 return this->getStateMachine()->createSignalConnection(onAborted_, callback, object);
127 }
128
129 template <typename T>
130 boost::signals2::connection onAborted(std::function<void(ResultConstPtr &)> callback)
131 {
132 return this->getStateMachine()->createSignalConnection(onAborted_, callback);
133 }
134
135 template <typename T>
136 boost::signals2::connection onPreempted(void (T::*callback)(ResultConstPtr &), T *object)
137 {
138 return this->getStateMachine()->createSignalConnection(onPreempted_, callback, object);
139 }
140
141 template <typename T>
142 boost::signals2::connection onPreempted(std::function<void(ResultConstPtr &)> callback)
143 {
144 return this->getStateMachine()->createSignalConnection(onPreempted_, callback);
145 }
146
147 template <typename T>
148 boost::signals2::connection onRejected(void (T::*callback)(ResultConstPtr &), T *object)
149 {
150 return this->getStateMachine()->createSignalConnection(onRejected_, callback, object);
151 }
152
153 template <typename T>
154 boost::signals2::connection onRejected(std::function<void(ResultConstPtr &)> callback)
155 {
156 return this->getStateMachine()->createSignalConnection(onRejected_, callback);
157 }
158
159 virtual void cancelGoal() override
160 {
161 if (client_->isServerConnected())
162 {
163 ROS_INFO("Cancelling goal of %s", this->getName().c_str());
164 client_->cancelGoal();
165 }
166 else
167 {
168 ROS_ERROR("%s [at %s]: not connected with actionserver, skipping cancel goal ...", getName().c_str(), getNamespace().c_str());
169 }
170 }
171
172 virtual SimpleClientGoalState getState() override
173 {
174 return client_->getState();
175 }
176
177 void sendGoal(Goal &goal)
178 {
179 ROS_INFO_STREAM("[ActionClient<"<< demangledTypeName<ActionType>() <<">] Sending goal to actionserver located in " << this->name_ << "\"");
180
181 if (client_->isServerConnected())
182 {
183 ROS_INFO_STREAM(getName() << ": Goal Value: " << std::endl
184 << goal);
185 client_->sendGoal(goal, done_cb, active_cb, feedback_cb);
186 }
187 else
188 {
189 ROS_ERROR("%s [at %s]: not connected with actionserver, skipping goal request ...", getName().c_str(), getNamespace().c_str());
190 //client_->waitForServer();
191 }
192 }
193
194protected:
195 std::shared_ptr<ActionClient> client_;
196
197 void onFeedback(const FeedbackConstPtr &feedback_msg)
198 {
199 postFeedbackEvent(feedback_msg);
200 }
201
202 void onResult(const SimpleClientGoalState &state, const ResultConstPtr &result_msg)
203 {
204 // auto *actionResultEvent = new EvActionResult<TDerived>();
205 // actionResultEvent->client = this;
206 // actionResultEvent->resultMessage = *result_msg;
207
208 const auto &resultType = this->getState();
209 ROS_INFO("[%s] request result: %s", this->getName().c_str(), resultType.toString().c_str());
210
211 if (resultType == actionlib::SimpleClientGoalState::SUCCEEDED)
212 {
213 ROS_INFO("[%s] request result: Success", this->getName().c_str());
214 onSucceeded_(result_msg);
215 postSuccessEvent(result_msg);
216 }
217 else if (resultType == actionlib::SimpleClientGoalState::ABORTED)
218 {
219 ROS_INFO("[%s] request result: Aborted", this->getName().c_str());
220 onAborted_(result_msg);
221 postAbortedEvent(result_msg);
222 }
223 else if (resultType == actionlib::SimpleClientGoalState::REJECTED)
224 {
225 ROS_INFO("[%s] request result: Rejected", this->getName().c_str());
226 onRejected_(result_msg);
227 postRejectedEvent(result_msg);
228 }
229 else if (resultType == actionlib::SimpleClientGoalState::PREEMPTED)
230 {
231 ROS_INFO("[%s] request result: Preempted", this->getName().c_str());
232 onPreempted_(result_msg);
233 postPreemptedEvent(result_msg);
234 }
235 else
236 {
237 ROS_INFO("[%s] request result: NOT HANDLED TYPE: %s", this->getName().c_str(), resultType.toString().c_str());
238 }
239 }
240};
241
242#define SMACC_ACTION_CLIENT_DEFINITION(ActionType) ACTION_DEFINITION(ActionType); typedef smacc::client_bases::SmaccActionClientBase<ActionType> Base;
243} // namespace client_bases
244
245} // namespace smacc
virtual std::string getName() const
Definition: client.cpp:34
ISmaccStateMachine * getStateMachine()
boost::signals2::connection createSignalConnection(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object)
std::function< void(ResultConstPtr)> postRejectedEvent
ActionClient::SimpleFeedbackCallback SimpleFeedbackCallback
smacc::SmaccSignal< void(const ResultConstPtr &)> onPreempted_
boost::signals2::connection onPreempted(std::function< void(ResultConstPtr &)> callback)
void onResult(const SimpleClientGoalState &state, const ResultConstPtr &result_msg)
actionlib::SimpleActionClient< ActionType > GoalHandle
boost::signals2::connection onRejected(void(T::*callback)(ResultConstPtr &), T *object)
smacc::SmaccSignal< void(const ResultConstPtr &)> onRejected_
ActionClient::SimpleDoneCallback SimpleDoneCallback
void onFeedback(const FeedbackConstPtr &feedback_msg)
boost::signals2::connection onAborted(std::function< void(ResultConstPtr &)> callback)
boost::signals2::connection onAborted(void(T::*callback)(ResultConstPtr &), T *object)
boost::signals2::connection onPreempted(void(T::*callback)(ResultConstPtr &), T *object)
boost::signals2::connection onSucceeded(std::function< void(ResultConstPtr &)> callback)
std::function< void(ResultConstPtr)> postPreemptedEvent
virtual SimpleClientGoalState getState() override
std::function< void(ResultConstPtr)> postAbortedEvent
actionlib::SimpleActionClient< ActionType > ActionClient
std::function< void(FeedbackConstPtr)> postFeedbackEvent
ActionClient::SimpleActiveCallback SimpleActiveCallback
smacc::SmaccSignal< void(const ResultConstPtr &)> onAborted_
SmaccActionClientBase(std::string actionServerName)
boost::signals2::connection onSucceeded(void(T::*callback)(ResultConstPtr &), T *object)
boost::signals2::connection onRejected(std::function< void(ResultConstPtr &)> callback)
smacc::SmaccSignal< void(const ResultConstPtr &)> onSucceeded_
std::function< void(ResultConstPtr)> postSuccessEvent
std::string demangleType(const std::type_info *tinfo)
Definition: introspection.h:86
std::string demangleSymbol()
Definition: introspection.h:75