people_follower_alg_node.cpp
Go to the documentation of this file.
00001 #include "people_follower_alg_node.h"
00002 
00003 #include "exceptions.h"
00004 #include <list>
00005 
00006 PeopleFollowerAlgNode::PeopleFollowerAlgNode(void) :
00007   algorithm_base::IriBaseAlgorithm<PeopleFollowerAlgorithm>(),
00008   followTarget_aserver_(public_node_handle_, "followTarget"),
00009   moveBase_client_("moveBase", true),
00010   new_req_event_id_("new_req_event"),
00011   moveBase_done_event_id_("moveBase_done_event"),
00012   moveBase_preempt_event_id_("moveBase_preempt_event"),
00013   target_pose_received_event_id_("target_pose_received_event"),
00014   follow_target_done_event_id_("follow_target_done_event"),
00015   current_state_(IDLE_STATE),
00016   request_id_(0),
00017   dist_to_goal_(0.f)
00018 {
00019   //init class attributes if necessary
00020   //this->loop_rate_ = 2;//in [Hz]
00021 
00022   // [init publishers]
00023 
00024   // [init subscribers]
00025   target_pose_subscriber_ = public_node_handle_.subscribe("target_pose", 100, &PeopleFollowerAlgNode::target_pose_callback, this);
00026 
00027   // [init services]
00028 
00029   // [init clients]
00030 
00031   // [init action servers]
00032   followTarget_aserver_.registerStartCallback(boost::bind(&PeopleFollowerAlgNode::followTargetStartCallback, this, _1)); 
00033   followTarget_aserver_.registerStopCallback(boost::bind(&PeopleFollowerAlgNode::followTargetStopCallback, this)); 
00034   followTarget_aserver_.registerIsFinishedCallback(boost::bind(&PeopleFollowerAlgNode::followTargetIsFinishedCallback, this)); 
00035   followTarget_aserver_.registerHasSucceedCallback(boost::bind(&PeopleFollowerAlgNode::followTargetHasSucceedCallback, this)); 
00036   followTarget_aserver_.registerGetResultCallback(boost::bind(&PeopleFollowerAlgNode::followTargetGetResultCallback, this, _1)); 
00037   followTarget_aserver_.registerGetFeedbackCallback(boost::bind(&PeopleFollowerAlgNode::followTargetGetFeedbackCallback, this, _1)); 
00038   followTarget_aserver_.start();
00039 
00040   // [init action clients]
00041 
00042   //init events
00043   event_server_ = CEventServer::instance();
00044 
00045   event_server_->create_event(new_req_event_id_);
00046   event_server_->create_event(moveBase_done_event_id_);
00047   event_server_->create_event(moveBase_preempt_event_id_);
00048   event_server_->create_event(target_pose_received_event_id_);
00049   event_server_->create_event(follow_target_done_event_id_);
00050 
00051   public_node_handle_.param<std::string>("tf_prefix", tf_prefix_, "");
00052   target_frame_ = tf_prefix_ + "/base_link";
00053   fixed_frame_  = tf_prefix_ + "/odom";
00054 }
00055 
00056 PeopleFollowerAlgNode::~PeopleFollowerAlgNode(void)
00057 {
00058   // [free dynamic memory]
00059 
00060   event_server_->delete_event(new_req_event_id_);
00061   event_server_->delete_event(moveBase_done_event_id_);
00062   event_server_->delete_event(moveBase_preempt_event_id_);
00063   event_server_->delete_event(target_pose_received_event_id_);
00064   event_server_->delete_event(follow_target_done_event_id_);
00065 }
00066 
00067 void PeopleFollowerAlgNode::mainNodeThread(void)
00068 {
00069   // [fill msg structures]
00070 
00071   // [fill srv structure and make request to the server]
00072 
00073   // [fill action structure and make request to the action server]
00074 
00075   // [publish messages]
00076 
00077   alg_.lock();
00078   switch(current_state_)
00079   {
00080     case IDLE_STATE:
00081       ROS_INFO("IDLE_STATE: request_id_=%d",request_id_);
00082 //      try
00083 //      {
00084         //wait for new follow request
00085         //event_server_->wait_first( std::list<std::string>(1, new_req_event_id_), 1000 );
00086         if( event_server_->event_is_set(new_req_event_id_) )
00087         {
00088           event_server_->reset_event(new_req_event_id_);
00089 
00090           //once we receive a follow target request
00091           //jumpt to request move base request state
00092           current_state_ = REQ_MB_STATE;
00093         }
00094         else
00095         {
00096           ROS_WARN("PeopleFollowerAlgNode::mainNodeThread: No follow request received");
00097         }
00098 
00099 //        //once we receive a follow target request
00100 //        //jumpt to request move base request state
00101 //        current_state_ = REQ_MB_STATE;
00102 //      }
00103 //      catch(CException &e)
00104 //      {
00105 //        ROS_WARN("PeopleFollowerAlgNode::mainNodeThread: No follow request received");
00106 //      }
00107       break;
00108 
00109     case REQ_MB_STATE:
00110       ROS_INFO("REQ_MB_STATE request_id_=%d",request_id_);
00111       //first time in this state, make move action request
00112 //      try
00113 //      {
00114 //          event_server_->wait_first( std::list<std::string>(1, target_pose_received_event_id_), 1000 );
00115         //wait until tracker finds requested target id, or timeout
00116         if( event_server_->event_is_set(target_pose_received_event_id_) )
00117         {
00118           event_server_->reset_event(target_pose_received_event_id_);
00119 
00120           //update target and make request
00121           target_pose_mutex_.enter();
00122             global_target_goal_ = current_global_target_pose_;
00123           target_pose_mutex_.exit();
00124 
00125           //send a goal to the action
00126           move_base_msgs::MoveBaseGoal local_goal;
00127           local_goal.target_pose = global_target_goal_;
00128 
00129           //transform goal to base_link frame
00130           if( alg_.transformGoal(local_goal.target_pose, target_frame_, fixed_frame_) )
00131           {
00132             moveBaseMakeActionRequest(local_goal);
00133             current_state_ = FOLLOWING_STATE;
00134           }
00135           else
00136           {
00137             ROS_ERROR("PeopleFollowerAlgNode::mainNodeThread: Could NOT Transform from %s to %s", global_target_goal_.header.frame_id.c_str(), target_frame_.c_str());
00138             followTarget_aserver_.setPreempted();
00139             current_state_ = IDLE_STATE;
00140           }
00141         }
00142 //      catch(CException &e)
00143 //      {
00144 //        ROS_ERROR("PeopleFollowerAlgNode::mainNodeThread: Follow Goal TIMEOUT: %s", e.what().c_str());
00145 //        followTarget_aserver_.setPreempted();
00146 //        current_state_ = IDLE_STATE;
00147 //      }
00148       break;
00149 
00150     case FOLLOWING_STATE:
00151       ROS_INFO("FOLLOWING_STATE request_id_=%d",request_id_);
00152       //check if move base action has finish successfully
00153       if( event_server_->event_is_set(moveBase_done_event_id_) )
00154       {
00155         current_state_ = SUCCESS_STATE;
00156       }
00157       //if it has not finished yet
00158       else
00159       {
00160         //check if move base server has preempted its action
00161         if( event_server_->event_is_set(moveBase_preempt_event_id_) )
00162         {
00163           ROS_WARN("PeopleFollowerAlgNode::mainNodeThread: moveBase_preempt_event=%d", event_server_->event_is_set(moveBase_preempt_event_id_));
00164           current_state_ = PREEMPT_STATE;
00165         }
00166         //move base action is still valid
00167         else
00168         {
00169 //          try
00170 //          {
00171             //wait until tracker finds requested target id, or timeout
00172 //            event_server_->wait_first( std::list<std::string>(1, target_pose_received_event_id_), 500 );
00173             if( event_server_->event_is_set(target_pose_received_event_id_) )
00174             {
00175               event_server_->reset_event(target_pose_received_event_id_);
00176 
00177               target_pose_mutex_.enter();
00178                 bool update = alg_.udpateGoal(global_target_goal_, current_global_target_pose_, dist_to_goal_);
00179               target_pose_mutex_.exit();
00180 
00181               //if target has moved and needs an update
00182               if( update )
00183                 current_state_ = UPDATE_STATE;
00184             }
00185             //no target pose message received
00186             else
00187             {
00188               no_target_pose_msg_received_++;
00189 
00190               if( no_target_pose_msg_received_ > MAX_ITERS_NO_MSG )
00191               {
00192                 current_state_ = PREEMPT_STATE;
00193               }
00194             }
00195 //          }
00196 //          catch(CException &e)
00197 //          {
00198 //            ROS_ERROR("PeopleFollowerAlgNode::mainNodeThread: Follow Goal TIMEOUT: %s", e.what().c_str());
00199 //            current_state_ = PREEMPT_STATE;
00200 //          }
00201         }
00202       }
00203       break;
00204 
00205     case SUCCESS_STATE:
00206       ROS_WARN("SUCCESS_STATE request_id_=%d",request_id_);
00207 //      event_server_->wait_first( std::list<std::string>(1, follow_target_done_event_id_) );
00208       if( event_server_->event_is_set(follow_target_done_event_id_) )
00209       {
00210         event_server_->reset_event(follow_target_done_event_id_);
00211         current_state_ = IDLE_STATE;
00212       }
00213       break;
00214 
00215     case UPDATE_STATE:
00216       ROS_WARN("UPDATE_STATE request_id_=%d",request_id_);
00217       moveBase_client_.cancelGoal();
00218       current_state_ = REQ_MB_STATE;
00219       break;
00220 
00221     case PREEMPT_STATE:
00222       ROS_WARN("PREEMPT_STATE request_id_=%d",request_id_);
00223       moveBase_client_.cancelGoal();
00224       followTarget_aserver_.setPreempted();
00225       current_state_ = IDLE_STATE;
00226       break;
00227   }
00228   alg_.unlock();
00229 }
00230 
00231 /*  [subscriber callbacks] */
00232 void PeopleFollowerAlgNode::target_pose_callback(const geometry_msgs::PoseStamped::ConstPtr& msg)
00233 {
00234   ROS_DEBUG("PeopleFollowerAlgNode::target_pose_callback: New Message Received");
00235 
00236   //reset counter
00237   no_target_pose_msg_received_ = 0;
00238 
00239   geometry_msgs::PoseStamped local_pose;
00240   local_pose = *msg;
00241 
00242   //transform goal from laser to fixed frame
00243   if( alg_.transformGoal(local_pose, fixed_frame_, fixed_frame_) )
00244   {
00245     //substract safety distance from original goal
00246     local_pose.pose.position = alg_.substractSafetyDistance(local_pose.pose.position, dist_to_goal_);
00247     target_pose_mutex_.enter();
00248       current_global_target_pose_ = local_pose;
00249     target_pose_mutex_.exit();
00250 
00251     ROS_INFO("PeopleFollowerAlgNode::people_tracker_callback: target_pose_received_event_id_");
00252     event_server_->set_event(target_pose_received_event_id_);
00253   }
00254   //if transform could not be made
00255   else
00256   {
00257     ROS_ERROR("PeopleFollowerAlgNode::people_tracker_callback: Could NOT Transform from %s to %s", 
00258               global_target_goal_.header.frame_id.c_str(), target_frame_.c_str());
00259   }
00260 }
00261 
00262 /*  [service callbacks] */
00263 
00264 /*  [action callbacks] */
00265 void PeopleFollowerAlgNode::followTargetStartCallback(const iri_nav_msgs::followTargetGoalConstPtr& goal)
00266 {
00267   ROS_INFO("PeopleFollowerAlgNode::followTargetStartCallback: NEW REQUEST!");// target_id=%d",goal->target_id);
00268 
00269   alg_.lock();
00270     request_id_++;
00271   alg_.unlock();
00272 
00273   event_server_->set_event(new_req_event_id_);
00274   ROS_WARN("PeopleFollowerAlgNode::followTargetStartCallback: NEW REQ EVENT!!");
00275 }
00276 
00277 void PeopleFollowerAlgNode::followTargetStopCallback(void)
00278 {
00279   alg_.lock();
00280     //stop action
00281   alg_.unlock();
00282 }
00283 
00284 bool PeopleFollowerAlgNode::followTargetIsFinishedCallback(void)
00285 {
00286   bool ret = false;
00287 
00288   //if action has finish for any reason
00289   if( event_server_->event_is_set(moveBase_done_event_id_) )
00290     ret = true;
00291 
00292   return ret;
00293 }
00294 
00295 bool PeopleFollowerAlgNode::followTargetHasSucceedCallback(void)
00296 {
00297   bool ret = false;
00298 
00299   //if goal was accomplished
00300   if( event_server_->event_is_set(moveBase_done_event_id_) )
00301   {
00302     ret = true;
00303     event_server_->set_event(follow_target_done_event_id_);
00304   }
00305 
00306   return ret;
00307 }
00308 
00309 void PeopleFollowerAlgNode::followTargetGetResultCallback(iri_nav_msgs::followTargetResultPtr& result)
00310 {
00311   alg_.lock();
00312     //update result data to be sent to client
00313     //result->data = data;
00314   alg_.unlock();
00315 }
00316 
00317 void PeopleFollowerAlgNode::followTargetGetFeedbackCallback(iri_nav_msgs::followTargetFeedbackPtr& feedback)
00318 {
00319   alg_.lock();
00320     //keep track of feedback
00321     //ROS_INFO("feedback: %s", feedback->data.c_str());
00322   alg_.unlock();
00323 }
00324 
00325 void PeopleFollowerAlgNode::moveBaseDone(const actionlib::SimpleClientGoalState& state,  const move_base_msgs::MoveBaseResultConstPtr& result) 
00326 {
00327   if( state.toString().compare("SUCCEEDED") == 0 )
00328   {
00329     ROS_INFO("PeopleFollowerAlgNode::moveBaseDone: Goal Achieved!");
00330     event_server_->set_event(moveBase_done_event_id_);
00331   }
00332   else
00333   {
00334     ROS_WARN("PeopleFollowerAlgNode::moveBaseDone: state=%s", state.toString().c_str());
00335     event_server_->set_event(moveBase_preempt_event_id_);
00336   }
00337 
00338   //ROS_INFO("PeopleFollowerAlgNode::moveBaseDone: %s", state.toString().c_str());
00339 
00340   //copy & work with requested result
00341 
00342 }
00343 
00344 void PeopleFollowerAlgNode::moveBaseActive()
00345 {
00346   //ROS_INFO("PeopleFollowerAlgNode::moveBaseActive: Goal just went active!");
00347 }
00348 
00349 void PeopleFollowerAlgNode::moveBaseFeedback(const move_base_msgs::MoveBaseFeedbackConstPtr& feedback)
00350 {
00351   //ROS_INFO("PeopleFollowerAlgNode::moveBaseFeedback: Got Feedback!");
00352 
00353   bool feedback_is_ok = true;
00354 
00355   //analyze feedback
00356   //my_var = feedback->var;
00357 
00358   //if feedback is not what expected, cancel requested goal
00359   if( !feedback_is_ok )
00360   {
00361     moveBase_client_.cancelGoal();
00362     //ROS_INFO("PeopleFollowerAlgNode::moveBaseFeedback: Cancelling Action!");
00363   }
00364 }
00365 
00366 /*  [action requests] */
00367 void PeopleFollowerAlgNode::moveBaseMakeActionRequest(const move_base_msgs::MoveBaseGoal & goal) 
00368 {
00369   event_server_->reset_event(moveBase_done_event_id_);
00370   event_server_->reset_event(moveBase_preempt_event_id_);
00371   
00372   ROS_INFO("PeopleFollowerAlgNode::moveBaseMakeActionRequest: Starting New Request!"); 
00373 
00374   //wait for the action server to start 
00375   //will wait for infinite time 
00376   moveBase_client_.waitForServer();  
00377   ROS_INFO("PeopleFollowerAlgNode::moveBaseMakeActionRequest: Server is Available!"); 
00378 
00379   //send a goal to the action 
00380   moveBase_client_.sendGoal(goal, 
00381               boost::bind(&PeopleFollowerAlgNode::moveBaseDone,     this, _1, _2), 
00382               boost::bind(&PeopleFollowerAlgNode::moveBaseActive,   this), 
00383               boost::bind(&PeopleFollowerAlgNode::moveBaseFeedback, this, _1)); 
00384   ROS_INFO("PeopleFollowerAlgNode::moveBaseMakeActionRequest: Goal(%f,%f) Sent. Wait for Result!",
00385             goal.target_pose.pose.position.x, goal.target_pose.pose.position.y);
00386 }
00387 
00388 void PeopleFollowerAlgNode::node_config_update(Config &config, uint32_t level)
00389 {
00390   alg_.lock();
00391     dist_to_goal_ = config.dist_to_goal;
00392     ROS_INFO("PeopleFollowerAlgNode::node_config_update: dist_to_goal_=%f",dist_to_goal_);
00393   alg_.unlock();
00394 }
00395 
00396 void PeopleFollowerAlgNode::addNodeDiagnostics(void)
00397 {
00398 }
00399 
00400 /* main function */
00401 int main(int argc,char *argv[])
00402 {
00403   return algorithm_base::main<PeopleFollowerAlgNode>(argc, argv, "people_follower_alg_node");
00404 }


iri_people_follower
Author(s):
autogenerated on Fri Dec 6 2013 23:15:31