Go to the documentation of this file.00001 template<typename ActionMessage>
00002 ActionServer<ActionMessage>::ActionServer(
00003 ros::NodeHandle& _node,
00004 const std::string& action_topic):
00005 node(_node),
00006 initialized(false),
00007 hasGoal(false),
00008 actionTopic(action_topic),
00009 lastExeSuccess(false),
00010 actionServer(NULL),
00011 startTime(0), endTime (0)
00012 {}
00013
00014 template<typename ActionMessage>
00015 ActionServer<ActionMessage>::~ActionServer()
00016 {
00017 this->deleteServer();
00018 }
00019
00020
00021 template<typename ActionMessage>
00022 bool ActionServer<ActionMessage>::init()
00023 {
00024 startServer();
00025 bool success=initImpl();
00026 if (success) initialized = true;
00027 return success;
00028 }
00029
00030 template<typename ActionMessage>
00031 void ActionServer<ActionMessage>::shutdown()
00032 {
00033 this->shutdownImpl();
00034 deleteServer();
00035 initialized = false;
00036 }
00037
00038
00039 template<typename ActionMessage>
00040 bool ActionServer<ActionMessage>::executingGoal(){
00041 goalLock.lock();
00042 bool hasOneGoal=hasGoal;
00043 bool cancelled=false;
00044 if (hasOneGoal) {
00045 actionlib_msgs::GoalStatus stat=currentGoal.getGoalStatus();
00046 cancelled= (stat.status != actionlib_msgs::GoalStatus::ACTIVE);
00047
00048
00049
00050 }
00051 goalLock.unlock();
00052 return ros::ok() && !cancelled && hasOneGoal;
00053 }
00054
00055 template<typename ActionMessage>
00056 float ActionServer<ActionMessage>::waitForExecution(float timeout){
00057 unique_lock guard(executionFinishedMutex);
00058
00059 double exeTime=timeRunning();
00060
00061 ros::Time startWait=ros::Time::now();
00062
00063
00064
00065
00066
00067 if (!this->hasCurrentGoal()) return exeTime;
00068
00069 bool success=true;
00070 if (timeout < 0){
00071
00072 this->executionFinishedCondition.wait(guard);
00073 }else{
00074
00075 success = COND_WAIT(this->executionFinishedCondition, guard, timeout);
00076 }
00077 if (!success) return -1;
00078
00079 ros::Time endWait=ros::Time::now();
00080 float totalTime= exeTime+(endWait-startWait).toSec();
00081 return totalTime;
00082 }
00083
00084 template<typename ActionMessage>
00085 double ActionServer<ActionMessage>::timeRunning(){
00086 double ret=-1;
00087 if (this->hasCurrentGoal()){
00088 unique_lock lock(goalLock);
00089 ros::Time nowTime=ros::Time::now();
00090 ret=ros::Duration(nowTime-startTime).toSec();
00091 }else{
00092 unique_lock lock(goalLock);
00093 ret=ros::Duration(endTime-startTime).toSec();
00094 }
00095 return ret;
00096 }
00097
00098 template<typename ActionMessage>
00099 void ActionServer<ActionMessage>::currentActionDone(ResultT& result, const actionlib::SimpleClientGoalState& state){
00100 ROS_INFO_STREAM(this->actionTopic<<": Action finished. Result = "<<result);
00101 unique_lock guard( executionFinishedMutex );
00102 goalLock.lock();
00103 endTime=ros::Time::now();
00104 hasGoal = false;
00105 ROSFunctions::effectOnGoalHandle(state,currentGoal,result);
00106 lastExeSuccess=(state==actionlib::SimpleClientGoalState::SUCCEEDED);
00107 goalLock.unlock();
00108 executionFinishedCondition.notify_all();
00109 }
00110
00111 template<typename ActionMessage>
00112 void ActionServer<ActionMessage>::currentActionDone(const actionlib::SimpleClientGoalState& state)
00113 {
00114 ROS_INFO_STREAM(this->actionTopic<<": Action finished.");
00115 unique_lock guard( executionFinishedMutex );
00116 goalLock.lock();
00117 endTime=ros::Time::now();
00118 hasGoal = false;
00119 ROSFunctions::effectOnGoalHandle(state,currentGoal);
00120 lastExeSuccess=(state==actionlib::SimpleClientGoalState::SUCCEEDED);
00121 goalLock.unlock();
00122 executionFinishedCondition.notify_all();
00123 }
00124
00125 template<typename ActionMessage>
00126 void ActionServer<ActionMessage>::currentActionSuccess(const bool success){
00127 ROS_INFO_STREAM(this->actionTopic<<": Action finished. Success = "<<success);
00128 if (success) currentActionDone(actionlib::SimpleClientGoalState::SUCCEEDED);
00129 else currentActionDone(actionlib::SimpleClientGoalState::ABORTED);
00130 }
00131
00132 template<typename ActionMessage>
00133 bool ActionServer<ActionMessage>::initImpl(){
00134 return true;
00135 }
00136
00137 template<typename ActionMessage>
00138 void ActionServer<ActionMessage>::startServer()
00139 {
00140 if (actionServer)
00141 {
00142 delete actionServer;
00143 }
00144 actionServer = new ROSActionServerT(this->node,
00145 this->actionTopic,
00146 boost::bind(&Self::actionCallback, this, _1),
00147 boost::bind(&Self::actionCancelCallback, this, _1),
00148 false);
00149 actionServer->start();
00150 }
00151
00152 template<typename ActionMessage>
00153 void ActionServer<ActionMessage>::deleteServer(){
00154 if (this->actionServer) {
00155 delete actionServer;
00156 this->actionServer=NULL;
00157 }
00158 }
00159
00160 template<typename ActionMessage>
00161 #if ROS_VERSION_MINIMUM(1, 12, 0)
00162 void ActionServer<ActionMessage>::actionCallback(ActionGoalHandleT goal)
00163 #else
00164 void ActionServer<ActionMessage>::actionCallback(ActionGoalHandleT& goal)
00165 #endif
00166 {
00167 ROS_INFO_STREAM(this->actionTopic<<": received new goal.");
00168 if (!this->initialized) {
00169 ROS_ERROR("Action server not initialised, can't accept goal");
00170 goal.setRejected();
00171 return;
00172 }
00173
00174 if (this->hasCurrentGoal()){
00175 ROS_ERROR_STREAM(this->actionTopic<<": Goal currently running, can't accept this new goal");
00176 goal.setRejected();
00177 return;
00178 }
00179
00180
00181 if (!this->canAccept(goal))
00182 {
00183 ROS_ERROR_STREAM(this->actionTopic<<": Goal cannot be accepted");
00184 goal.setRejected();
00185 return;
00186 }
00187
00188 ROS_INFO_STREAM(this->actionTopic<<": Goal accepted.");
00189
00190 goalLock.lock();
00191 startTime=ros::Time::now();
00192 lastExeSuccess = false;
00193 hasGoal = true;
00194 currentGoal=goal;
00195 currentGoal.setAccepted();
00196 goalLock.unlock();
00197
00198 this->actionCallbackImpl(goal);
00199
00200 }
00201
00202 template<typename ActionMessage>
00203 #if ROS_VERSION_MINIMUM(1, 12, 0)
00204 void ActionServer<ActionMessage>::actionCancelCallback(ActionGoalHandleT goal)
00205 #else
00206 void ActionServer<ActionMessage>::actionCancelCallback(ActionGoalHandleT& goal)
00207 #endif
00208 {
00209 this->actionCancelCallbackImpl(goal);
00210 currentActionDone(actionlib::SimpleClientGoalState::ABORTED);
00211 }
00212
00213 template<typename ActionMessage>
00214 bool ActionServer<ActionMessage>::hasCurrentGoal(){
00215 unique_lock lock(goalLock);
00216 return hasGoal;
00217 }
00218