1 #ifndef __EXECUTE_ACTION__
2 #define __EXECUTE_ACTION__
5 #include <behavior_tree_leaves/ActionTemplate.h>
6 #include <actionlib/client/simple_action_client.h>
16 template <
class ActionClass,
class ActionGoal>
26 ExecuteAction(std::string node_name, std::string actionlib_name,
40 virtual bool fillGoal(ActionGoal &goal) = 0;
57 bool fillParameter(std::string param_name, std::string ¶m_val);
68 std::string ¶m_val);
69 void fillParameter(std::string param_name,
double def,
double ¶m_val);
70 void fillParameter(std::string param_name,
int def,
int ¶m_val);
89 template <
class ActionClass,
class ActionGoal>
91 std::string node_name, std::string actionlib_name, std::string bt_name)
92 : ActionTemplate::ActionTemplate(bt_name) {
93 nh_ = ros::NodeHandle(
"~");
98 template <
class ActionClass,
class ActionGoal>
100 delete action_client_;
103 template <
class ActionClass,
class ActionGoal>
106 if (nh_.hasParam(
"/sarafun/bt/running")) {
107 nh_.getParam(
"/sarafun/bt/running", running);
113 ROS_WARN(
"The parameter /sarafun/bt/running must be set"
114 "for a BT action to run!");
119 template <
class ActionClass,
class ActionGoal>
121 action_client_->cancelAllGoals();
122 delete action_client_;
124 ROS_WARN(
"The node %s was preempted", action_name_.c_str());
127 template <
class ActionClass,
class ActionGoal>
130 if (action_client_ == 0)
132 action_client_ =
new actionlib::SimpleActionClient<ActionClass>(action_name_,
true);
133 ROS_INFO(
"Action %s is waiting for the corresponding actionlib server!", action_name_.c_str());
134 bool active_server = action_client_->waitForServer(ros::Duration(2.0));
135 if (!active_server) {
136 ROS_ERROR(
"Actionlib server failed to start for action %s!",
137 action_name_.c_str());
138 delete action_client_;
142 start_time_ = ros::Time::now();
144 bool has_parameters = fillGoal(goal_);
146 if (!has_parameters) {
147 ROS_ERROR(
"Failed to get parameters for action %s!", action_name_.c_str());
151 ROS_INFO(
"Sending goal from action: %s. Timeout value: %.2f", action_name_.c_str(), getTimeoutValue());
152 action_client_->sendGoal(goal_);
155 if (!isSystemActive()) {
159 bool finished =
false, timeout =
false;
160 if ((ros::Time::now() - start_time_).toSec() < getTimeoutValue())
162 actionlib::SimpleClientGoalState goal_state = action_client_->getState();
163 if (goal_state != actionlib::SimpleClientGoalState::ACTIVE && goal_state != actionlib::SimpleClientGoalState::PENDING)
174 action_client_->cancelAllGoals();
175 actionlib::SimpleClientGoalState state = action_client_->getState();
176 ROS_INFO(
"Action finished: %s", state.toString().c_str());
178 delete action_client_;
180 if (state == actionlib::SimpleClientGoalState::SUCCEEDED) {
188 ROS_ERROR(
"Action %s timeout! Cancelling goals...", action_name_.c_str());
189 action_client_->cancelAllGoals();
190 delete action_client_;
197 template <
class ActionClass,
class ActionGoal>
199 std::string param_name, std::string ¶m_val) {
200 if (nh_.hasParam(param_name.c_str())) {
201 nh_.getParam(param_name.c_str(), param_val);
203 ROS_ERROR(
"%s not set!", param_name.c_str());
209 template <
class ActionClass,
class ActionGoal>
211 std::string param_name, std::string def, std::string ¶m_val) {
212 if (nh_.hasParam(param_name.c_str())) {
213 nh_.getParam(param_name.c_str(), param_val);
215 ROS_WARN(
"Param '%s' not set. Using default: %s", param_name.c_str(),
220 template <
class ActionClass,
class ActionGoal>
222 std::string param_name,
double def,
double ¶m_val) {
223 if (nh_.hasParam(param_name.c_str())) {
224 nh_.getParam(param_name.c_str(), param_val);
226 ROS_WARN(
"Param '%s' not set. Using default: %.2f", param_name.c_str(),
231 template <
class ActionClass,
class ActionGoal>
233 std::string param_name,
int def,
int ¶m_val) {
234 if (nh_.hasParam(param_name.c_str())) {
235 nh_.getParam(param_name.c_str(), param_val);
237 ROS_WARN(
"Param '%s' not set. Using default: %d", param_name.c_str(),
virtual bool fillGoal(ActionGoal &goal)=0
virtual double getTimeoutValue()=0
ExecuteAction(std::string node_name, std::string actionlib_name, std::string bt_name)
actionlib::SimpleActionClient< ActionClass > * action_client_
bool fillParameter(std::string param_name, std::string ¶m_val)