ActionServer.hpp
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             //(stat.status == actionlib_msgs::GoalStatus::PREEMPTED) 
00048             //|| (stat.status == actionlib_msgs::GoalStatus::ABORTED)
00049             //|| (stat.status == actionlib_msgs::GoalStatus::LOST);
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(); //time the action already has been running
00060     
00061     ros::Time startWait=ros::Time::now();
00062     
00063     // Check if the action had already ended. This can
00064     // happen if he execution was so quick between starting it
00065     // and calling waitForExecution(), that it is ok to return the
00066     // last execution time. 
00067     if (!this->hasCurrentGoal()) return exeTime; 
00068 
00069     bool success=true;
00070     if (timeout < 0){
00071         // Unlocks the mutex and waits for a notification.
00072         this->executionFinishedCondition.wait(guard);
00073     }else{    
00074         // Unlocks the mutex and waits for a notification.
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; //ROSActionServerPtr();
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     // ROS_INFO("Checking whether goal can be accepted: ");
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 


convenience_ros_functions
Author(s): Jennifer Buehler
autogenerated on Sat Mar 2 2019 03:21:42