00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 namespace actionlib
00040 {
00041
00042 template<class ActionSpec>
00043 ClientGoalHandle<ActionSpec>::ClientGoalHandle()
00044 {
00045 gm_ = NULL;
00046 active_ = false;
00047 }
00048
00049 template<class ActionSpec>
00050 ClientGoalHandle<ActionSpec>::~ClientGoalHandle()
00051 {
00052 reset();
00053 }
00054
00055 template<class ActionSpec>
00056 ClientGoalHandle<ActionSpec>::ClientGoalHandle(GoalManagerT* gm, typename ManagedListT::Handle handle,
00057 const boost::shared_ptr<DestructionGuard>& guard)
00058 {
00059 gm_ = gm;
00060 active_ = true;
00061 list_handle_ = handle;
00062 guard_ = guard;
00063 }
00064
00065 template<class ActionSpec>
00066 void ClientGoalHandle<ActionSpec>::reset()
00067 {
00068 if (active_)
00069 {
00070 DestructionGuard::ScopedProtector protector(*guard_);
00071 if (!protector.isProtected())
00072 {
00073 ROS_ERROR("This action client associated with the goal handle has already been destructed. Ignoring this reset() call");
00074 return;
00075 }
00076
00077 boost::recursive_mutex::scoped_lock lock(gm_->list_mutex_);
00078 list_handle_.reset();
00079 active_ = false;
00080 gm_ = NULL;
00081 }
00082 }
00083
00084 template<class ActionSpec>
00085 bool ClientGoalHandle<ActionSpec>::isExpired() const
00086 {
00087 return !active_;
00088 }
00089
00090
00091 template<class ActionSpec>
00092 CommState ClientGoalHandle<ActionSpec>::getCommState()
00093 {
00094 if (!active_)
00095 {
00096 ROS_ERROR("Trying to getCommState on an inactive ClientGoalHandle. You are incorrectly using a ClientGoalHandle");
00097 return CommState(CommState::DONE);
00098 }
00099
00100 DestructionGuard::ScopedProtector protector(*guard_);
00101 if (!protector.isProtected())
00102 {
00103 ROS_ERROR("This action client associated with the goal handle has already been destructed. Ignoring this getCommState() call");
00104 return CommState(CommState::DONE);
00105 }
00106
00107 assert(gm_);
00108
00109 boost::recursive_mutex::scoped_lock lock(gm_->list_mutex_);
00110 return list_handle_.getElem()->getCommState();
00111 }
00112
00113 template<class ActionSpec>
00114 TerminalState ClientGoalHandle<ActionSpec>::getTerminalState()
00115 {
00116
00117 if (!active_)
00118 {
00119 ROS_ERROR("Trying to getTerminalState on an inactive ClientGoalHandle. You are incorrectly using a ClientGoalHandle");
00120 return TerminalState(TerminalState::LOST);
00121 }
00122
00123 DestructionGuard::ScopedProtector protector(*guard_);
00124 if (!protector.isProtected())
00125 {
00126 ROS_ERROR("This action client associated with the goal handle has already been destructed. Ignoring this getTerminalState() call");
00127 return TerminalState(TerminalState::LOST);
00128 }
00129
00130 assert(gm_);
00131
00132 boost::recursive_mutex::scoped_lock lock(gm_->list_mutex_);
00133 CommState comm_state_ = list_handle_.getElem()->getCommState();
00134 if (comm_state_ != CommState::DONE)
00135 ROS_WARN("Asking for the terminal state when we're in [%s]", comm_state_.toString().c_str());
00136
00137 actionlib_msgs::GoalStatus goal_status = list_handle_.getElem()->getGoalStatus();
00138
00139 switch (goal_status.status)
00140 {
00141 case actionlib_msgs::GoalStatus::PENDING:
00142 case actionlib_msgs::GoalStatus::ACTIVE:
00143 case actionlib_msgs::GoalStatus::PREEMPTING:
00144 case actionlib_msgs::GoalStatus::RECALLING:
00145 ROS_ERROR("Asking for terminal state, but latest goal status is %u", goal_status.status); return TerminalState(TerminalState::LOST, goal_status.text);
00146 case actionlib_msgs::GoalStatus::PREEMPTED: return TerminalState(TerminalState::PREEMPTED, goal_status.text);
00147 case actionlib_msgs::GoalStatus::SUCCEEDED: return TerminalState(TerminalState::SUCCEEDED, goal_status.text);
00148 case actionlib_msgs::GoalStatus::ABORTED: return TerminalState(TerminalState::ABORTED, goal_status.text);
00149 case actionlib_msgs::GoalStatus::REJECTED: return TerminalState(TerminalState::REJECTED, goal_status.text);
00150 case actionlib_msgs::GoalStatus::RECALLED: return TerminalState(TerminalState::RECALLED, goal_status.text);
00151 case actionlib_msgs::GoalStatus::LOST: return TerminalState(TerminalState::LOST, goal_status.text);
00152 default:
00153 ROS_ERROR("Unknown goal status: %u", goal_status.status); break;
00154 }
00155
00156 ROS_ERROR("Bug in determining terminal state");
00157 return TerminalState(TerminalState::LOST, goal_status.text);
00158 }
00159
00160 template<class ActionSpec>
00161 typename ClientGoalHandle<ActionSpec>::ResultConstPtr ClientGoalHandle<ActionSpec>::getResult()
00162 {
00163 if (!active_)
00164 ROS_ERROR("Trying to getResult on an inactive ClientGoalHandle. You are incorrectly using a ClientGoalHandle");
00165 assert(gm_);
00166
00167 DestructionGuard::ScopedProtector protector(*guard_);
00168 if (!protector.isProtected())
00169 {
00170 ROS_ERROR("This action client associated with the goal handle has already been destructed. Ignoring this getResult() call");
00171 return typename ClientGoalHandle<ActionSpec>::ResultConstPtr() ;
00172 }
00173
00174 boost::recursive_mutex::scoped_lock lock(gm_->list_mutex_);
00175 return list_handle_.getElem()->getResult();
00176 }
00177
00178 template<class ActionSpec>
00179 void ClientGoalHandle<ActionSpec>::resend()
00180 {
00181 if (!active_)
00182 ROS_ERROR("Trying to resend() on an inactive ClientGoalHandle. You are incorrectly using a ClientGoalHandle");
00183
00184 DestructionGuard::ScopedProtector protector(*guard_);
00185 if (!protector.isProtected())
00186 {
00187 ROS_ERROR("This action client associated with the goal handle has already been destructed. Ignoring this resend() call");
00188 return;
00189 }
00190
00191 assert(gm_);
00192
00193 boost::recursive_mutex::scoped_lock lock(gm_->list_mutex_);
00194
00195 ActionGoalConstPtr action_goal = list_handle_.getElem()->getActionGoal();
00196
00197 if (!action_goal)
00198 ROS_ERROR("BUG: Got a NULL action_goal");
00199
00200 if (gm_->send_goal_func_)
00201 gm_->send_goal_func_(action_goal);
00202 }
00203
00204 template<class ActionSpec>
00205 void ClientGoalHandle<ActionSpec>::cancel()
00206 {
00207 if (!active_)
00208 ROS_ERROR("Trying to cancel() on an inactive ClientGoalHandle. You are incorrectly using a ClientGoalHandle");
00209 assert(gm_);
00210
00211 DestructionGuard::ScopedProtector protector(*guard_);
00212 if (!protector.isProtected())
00213 {
00214 ROS_ERROR("This action client associated with the goal handle has already been destructed. Ignoring this call");
00215 return;
00216 }
00217
00218 boost::recursive_mutex::scoped_lock lock(gm_->list_mutex_);
00219
00220 ActionGoalConstPtr action_goal = list_handle_.getElem()->getActionGoal();
00221
00222 actionlib_msgs::GoalID cancel_msg;
00223 cancel_msg.stamp = ros::Time(0,0);
00224 cancel_msg.id = list_handle_.getElem()->getActionGoal()->goal_id.id;
00225
00226 if (gm_->cancel_func_)
00227 gm_->cancel_func_(cancel_msg);
00228
00229 list_handle_.getElem()->transitionToState(*this, CommState::WAITING_FOR_CANCEL_ACK);
00230 }
00231
00232 template<class ActionSpec>
00233 bool ClientGoalHandle<ActionSpec>::operator==(const ClientGoalHandle<ActionSpec>& rhs)
00234 {
00235
00236 if (!active_ && !rhs.active_)
00237 return true;
00238
00239
00240 if (!active_ || !rhs.active_)
00241 return false;
00242
00243 DestructionGuard::ScopedProtector protector(*guard_);
00244 if (!protector.isProtected())
00245 {
00246 ROS_ERROR("This action client associated with the goal handle has already been destructed. Ignoring this operator==() call");
00247 return false;
00248 }
00249
00250 return (list_handle_ == rhs.list_handle_) ;
00251 }
00252
00253 template<class ActionSpec>
00254 bool ClientGoalHandle<ActionSpec>::operator!=(const ClientGoalHandle<ActionSpec>& rhs)
00255 {
00256 return !(*this==rhs);
00257 }
00258
00259 }