tibi_dabo_hideandseek_alg_node.cpp
Go to the documentation of this file.
00001 #include "tibi_dabo_hideandseek_alg_node.h"
00002 #include <wiimote/State.h>
00003 
00004 TibiDaboHideandseekAlgNode::TibiDaboHideandseekAlgNode(void) :
00005   algorithm_base::IriBaseAlgorithm<TibiDaboHideandseekAlgorithm>(),
00006   move_base_client_("move_base", true)
00007 {
00008   ROS_INFO("TibiDaboHideandseekAlgNode::constructor!");
00009   //init class attributes if necessary
00010   this->loop_rate_ = 1;//in [Hz] //TODO RATE? turns
00011 
00012   this->seekerPoseReceived = false;
00013   this->hiderPoseReceived = false;
00014   this->moveBaseActive     = false;
00015   this->gameStatus= STATE_IDLE;
00016   this->gameIteration=0;
00017   this->paused=false;
00018   this->ready2Move=false;
00019 
00020   this->previousId=-1;
00021   //this->previousXY;
00022   std::string path;
00023   std::string pathOut;
00024   std::string map;
00025   std::string experiment;
00026   int solver;
00027   int windist;
00028   double cellsize;
00029   public_node_handle_.getParam("path", path);
00030   public_node_handle_.getParam("pathOut", pathOut);
00031   public_node_handle_.getParam("map", map);
00032   public_node_handle_.getParam("experiment", experiment);
00033   public_node_handle_.getParam("solver", solver);
00034                 /* solver should be (see SeekerHSParam)
00035                     static const char SOLVER_NOT_SET = 0;
00036                     static const char SOLVER_OFFLINE = 1;
00037                     static const char SOLVER_LAYERED = 2;
00038                     static const char SOLVER_LAYERED_COMPARE = 3;
00039                     static const char SOLVER_MCVI_OFFLINE = 4;
00040                     static const char SOLVER_POMCP = 5;
00041 
00042                     static const char SOLVER_SMART_SEEKER = 9;
00043                 */
00044 
00045   public_node_handle_.getParam("windist", windist);
00046   public_node_handle_.getParam("cellsize", cellsize);
00047   
00048   
00049   //this->alg_.initialize(path, pathOut, map, experiment, solver);
00050   //this->alg_.setWinDistToHider(windist);
00051   //this->alg_.setCellSizeM(cellsize);
00052 
00053   // [init publishers]
00054   
00055   // [init subscribers]
00056   this->people_subscriber_ = this->public_node_handle_.subscribe("people", 100, &TibiDaboHideandseekAlgNode::people_callback, this);
00057   this->joy_subscriber_    = this->public_node_handle_.subscribe("joy",    100, &TibiDaboHideandseekAlgNode::joy_callback,    this);
00058   this->odom_subscriber_   = this->public_node_handle_.subscribe("odom",   100, &TibiDaboHideandseekAlgNode::odom_callback,   this);
00059   
00060   // [init services]
00061   
00062   // [init clients]
00063   
00064   // [init action servers]
00065   
00066   // [init action clients]
00067   //ros::Duration(1).sleep();
00068   this->alg_.initialize(path, pathOut, map, experiment, solver);
00069   this->alg_.setWinDistToHider(windist);
00070   this->alg_.setCellSizeM(cellsize);
00071 
00072   ROS_INFO("TibiDaboHideandseekAlgNode::constructor end");
00073 }
00074 
00075 TibiDaboHideandseekAlgNode::~TibiDaboHideandseekAlgNode(void)
00076 {
00077   // [free dynamic memory]
00078 }
00079 
00080 void TibiDaboHideandseekAlgNode::mainNodeThread(void)
00081 { 
00082   // ros::Duration(0.1).sleep();
00083   this->alg_.lock();
00084 
00085   if(this->seekerPoseReceived /*&& this->hiderPoseReceived*/ && !this->moveBaseActive && this->paused && !this->ready2Move)
00086   {
00087     //ROS_INFO("TibiDaboHideandseekAlgNode::mainNodeThread! new data");
00088 
00089     // if status is IDLE (first iteration), game must be initialized
00090     if(this->gameStatus==STATE_IDLE)
00091     {
00092       ROS_INFO("TibiDaboHideandseekAlgNode::mainNodeThread: initGame!");
00093       ROS_INFO("TibiDaboHideandseekAlgNode::mainNodeThread: seeker position x,y: %f, %f. In frame %s !!!", seekerPose.pose.position.x, seekerPose.pose.position.y, seekerPose.header.frame_id.c_str() );
00094       this->alg_.initGame(this->seekerPose, this->hiderPoses);
00095       ROS_INFO("TibiDaboHideandseekAlgNode::mainNodeThread: initGame Done!");
00096       this->gameStatus=STATE_PLAYING;
00097     }
00098     else if(this->gameStatus!=STATE_FINISHED)
00099     {
00100       //send seeker and hider pose, receive seeker goal and game status
00101       this->seekerGoal = this->seekerPose;
00102       ROS_INFO("TibiDaboHideandseekAlgNode::mainNodeThread: nextIteration!");
00103       bool ok = this->alg_.iteration(this->seekerPose, this->hiderPoses, this->seekerGoal, this->gameStatus);
00104       ROS_INFO("TibiDaboHideandseekAlgNode::mainNodeThread: nextIteration Done!");
00105       
00106       if(!ok)
00107       {
00108         ROS_ERROR("TibiDaboHideandseekAlgNode::mainNodeThread: unexpected iteration failed, check hider/seeker poses !!!");
00109         this->paused=false;
00110         this->hiderPoseReceived  = true;
00111       }
00112       else
00113       {
00114         switch(gameStatus)
00115         {
00116           case STATE_PLAYING:
00117             this->ready2Move=true;
00118             ROS_INFO("GAME: READY FOR NEXT TURN. PRESS WIIMOTE BUTTON 1!!!");
00119             //TEST uncomment
00120             //this->paused=false;
00121             break;
00122           case STATE_WIN_SEEKER:
00123             //say "I WIN"
00124             ROS_INFO("GAME: ROBOT WINS !!!");
00125             this->gameStatus=STATE_FINISHED;
00126             break;
00127           case STATE_WIN_HIDER:
00128             //say "YOU WIN"
00129             ROS_INFO("GAME: HUMAN WINS !!!");
00130             this->gameStatus=STATE_FINISHED;
00131             break;
00132           case STATE_TIE:
00133             //say "IT'S A TIE"
00134             ROS_INFO("GAME: IT'S A TIE !!!");
00135             this->gameStatus=STATE_FINISHED;
00136             break;
00137           case STATE_FINISHED:
00138             ROS_INFO("GAME: FINISHED!!!");
00139             break;
00140           case STATE_IDLE:
00141             ROS_INFO("GAME: IDLE!!!");
00142             break;
00143           default:
00144             break;
00145         }
00146       }
00147     }
00148     else
00149     {
00150       ROS_INFO("GAME: FINISHED !!!");
00151       ROS_INFO("CTRL-C TO EXIT");
00152     }
00153     //this->seekerPoseReceived = false;
00154     //this->hiderPoseReceived  = false;
00155   }
00156   // when ready2Move and not paused (joy button1 pressed), send robot goal (and the person should do a move too)
00157   else if(this->ready2Move && !this->paused)
00158   {
00159     //send new seeker goal
00160     move_base_goal_.target_pose = this->seekerGoal;
00161     ROS_INFO("GAME: NEXT TURN. MOVING!!!");
00162     move_baseMakeActionRequest();
00163     this->gameIteration++;
00164     //this->paused=true;
00165     this->ready2Move=false;
00166   }
00167   this->alg_.unlock();
00168 
00169   // [fill msg structures]
00170 
00171   // [fill srv structure and make request to the server]
00172 
00173   // [fill action structure and make request to the action server]
00174   //move_baseMakeActionRequest();
00175 
00176   // [publish messages]
00177 }
00178 
00179 /*  [subscriber callbacks] */
00180 void TibiDaboHideandseekAlgNode::people_callback(const iri_perception_msgs::peopleTrackingArray::ConstPtr& msg) 
00181 { 
00182   //ROS_INFO("TibiDaboHideandseekAlgNode::people_callback: New Message Received"); 
00183 
00184   //use appropiate mutex to shared variables if necessary 
00185   this->alg_.lock(); 
00186   //this->people_mutex_.enter(); 
00187 
00188   //std::cout << msg->data << std::endl; 
00189   if(this->seekerPoseReceived && !this->hiderPoseReceived && this->gameStatus!=STATE_FINISHED && !this->ready2Move && msg->header.frame_id.size()!=0 )
00190   {
00191     if(msg->header.frame_id != "/map")
00192     {
00193       ROS_ERROR("TibiDaboHideandseekAlgNode::people_callback: people detections need to be in /map frame_id, but are in %s instead", 
00194                 msg->header.frame_id.c_str());
00195     }
00196 
00197     hiderPoses.clear();
00198     for(unsigned int i=0; i<msg->peopleSet.size(); i++)
00199     {
00200       geometry_msgs::Point person;
00201       person.x = msg->peopleSet[i].x;
00202       person.y = msg->peopleSet[i].y;
00203       person.z = 1.0; //quality TODO
00204       hiderPoses.push_back(person);
00205     }
00206     this->hiderPoseReceived = true;
00207   }
00208   //unlock previously blocked shared variables 
00209   this->alg_.unlock(); 
00210   //this->people_mutex_.exit(); 
00211 }
00212 
00213 void TibiDaboHideandseekAlgNode::joy_callback(const sensor_msgs::Joy::ConstPtr& msg) 
00214 { 
00215   ROS_DEBUG("TibiDaboHideandseekAlgNode::joy_callback: New Message Received"); 
00216 
00217   //use appropiate mutex to shared variables if necessary 
00218   this->alg_.lock(); 
00219   //this->joy_mutex_.enter(); 
00220 
00221 
00222 
00223   static bool first=true;
00224 
00225   if(first)
00226   {
00227     prev_buttons.resize(msg->buttons.size());
00228     first=false;
00229   }
00230 
00231   //std::cout << msg->data << std::endl; 
00232   if(msg->buttons[wiimote::State::MSG_BTN_HOME]==1 && prev_buttons[wiimote::State::MSG_BTN_HOME]==0)
00233   {
00234     ROS_INFO("GAME: BASE HOME BUTTON PRESSED !!!");
00235     this->gameStatus=STATE_WIN_HIDER;
00236     this->alg_.stopGame(this->gameStatus);
00237   }
00238   if(msg->buttons[wiimote::State::MSG_BTN_1]==1 && prev_buttons[wiimote::State::MSG_BTN_1]==0)
00239   {
00240     this->paused=false;
00241     ROS_INFO("GAME: NEXT TURN BUTTON 1 PRESSED, paused=%d !!!", this->paused);
00242   }
00243   else if(msg->buttons[wiimote::State::MSG_BTN_2]==1 && prev_buttons[wiimote::State::MSG_BTN_2]==0)
00244   {
00245     this->paused=true;
00246     this->hiderPoseReceived  = false;
00247     this->seekerPoseReceived  = false;
00248     ROS_INFO("GAME: END OF TURN BUTTON 2 PRESSED, paused=%d !!!", this->paused);
00249   }
00250   else if(msg->buttons[wiimote::State::MSG_BTN_A]==1 && prev_buttons[wiimote::State::MSG_BTN_A]==0)
00251   {
00252     ROS_INFO("GAME: goal cancelled, use teleop to adjust it!!!");
00253     // cancel Goal
00254     move_base_client_.cancelGoal(); 
00255   }
00256 
00257 
00258 
00259   //unlock previously blocked shared variables 
00260   this->prev_buttons=msg->buttons;
00261   this->alg_.unlock(); 
00262   //this->joy_mutex_.exit(); 
00263 }
00264 
00265 void TibiDaboHideandseekAlgNode::odom_callback(const nav_msgs::Odometry::ConstPtr& msg) 
00266 { 
00267   ROS_DEBUG("TibiDaboHideandseekAlgNode::odom_callback: New Message Received"); 
00268 
00269   //use appropiate mutex to shared variables if necessary 
00270   this->alg_.lock(); 
00271   //this->odom_mutex_.enter();
00272   if(this->gameStatus!=STATE_FINISHED && !this->ready2Move)
00273   {
00274     //std::cout << msg->data << std::endl;
00275     try
00276     {
00277       std::string target_frame = "/map";
00278       std::string source_frame = msg->header.frame_id; // "/odom"
00279       ros::Time   target_time  = msg->header.stamp;
00280       //wait for transform between odom and map
00281       bool tf_exists = tf_listener_.waitForTransform(target_frame, source_frame, target_time, ros::Duration(5), ros::Duration(0.01));
00282 
00283       if(tf_exists)
00284       {
00285         geometry_msgs::PoseStamped stampedIn;
00286         stampedIn.header = msg->header;
00287         stampedIn.pose   = msg->pose.pose;
00288         geometry_msgs::PoseStamped stampedOut;
00289         //transform odom pose from odom to map
00290         tf_listener_.transformPose( target_frame, stampedIn, stampedOut);
00291         this->seekerPose = stampedOut;
00292         this->seekerPoseReceived = true;
00293       }
00294     }
00295     catch (tf::TransformException &ex)
00296     {
00297       ROS_INFO("TibiDaboHideandseekAlgNode:: %s",ex.what());
00298     }
00299   }
00300   //unlock previously blocked shared variables 
00301   this->alg_.unlock(); 
00302   //this->odom_mutex_.exit(); 
00303 }
00304 
00305 /*  [service callbacks] */
00306 
00307 /*  [action callbacks] */
00308 void TibiDaboHideandseekAlgNode::move_baseDone(const actionlib::SimpleClientGoalState& state,  const move_base_msgs::MoveBaseResultConstPtr& result) 
00309 { 
00310   if( state.toString().compare("SUCCEEDED") == 0 ) 
00311     ROS_INFO("TibiDaboHideandseekAlgNode::move_baseDone: Goal Achieved!"); 
00312   else 
00313     ROS_INFO("TibiDaboHideandseekAlgNode::move_baseDone: %s", state.toString().c_str()); 
00314 
00315   //copy & work with requested result 
00316   this->moveBaseActive=false;
00317   ROS_INFO("TibiDaboHideandseekAlgNode::move_baseDone: PRESS WII BUTTON 2 TO CONTINUE!"); 
00318 } 
00319 
00320 void TibiDaboHideandseekAlgNode::move_baseActive() 
00321 { 
00322   //ROS_INFO("TibiDaboHideandseekAlgNode::move_baseActive: Goal just went active!"); 
00323 } 
00324 
00325 void TibiDaboHideandseekAlgNode::move_baseFeedback(const move_base_msgs::MoveBaseFeedbackConstPtr& feedback) 
00326 { 
00327   //ROS_INFO("TibiDaboHideandseekAlgNode::move_baseFeedback: Got Feedback!"); 
00328 
00329   bool feedback_is_ok = true; 
00330 
00331   //analyze feedback 
00332   //my_var = feedback->var; 
00333 
00334   //if feedback is not what expected, cancel requested goal 
00335   if( !feedback_is_ok ) 
00336   { 
00337     move_base_client_.cancelGoal(); 
00338     //ROS_INFO("TibiDaboHideandseekAlgNode::move_baseFeedback: Cancelling Action!"); 
00339   } 
00340 }
00341 
00342 /*  [action requests] */
00343 void TibiDaboHideandseekAlgNode::move_baseMakeActionRequest() 
00344 { 
00345   ROS_INFO("TibiDaboHideandseekAlgNode::move_baseMakeActionRequest: Starting New Request!"); 
00346 
00347   //wait for the action server to start 
00348   //will wait for infinite time 
00349   move_base_client_.waitForServer();  // TEST comment
00350   ROS_INFO("TibiDaboHideandseekAlgNode::move_baseMakeActionRequest: Server is Available!"); 
00351 
00352   //send a goal to the action 
00353   //move_base_goal_.data = my_desired_goal; 
00354   move_base_client_.sendGoal(move_base_goal_, 
00355               boost::bind(&TibiDaboHideandseekAlgNode::move_baseDone,     this, _1, _2), 
00356               boost::bind(&TibiDaboHideandseekAlgNode::move_baseActive,   this), 
00357               boost::bind(&TibiDaboHideandseekAlgNode::move_baseFeedback, this, _1)); 
00358   ROS_INFO("TibiDaboHideandseekAlgNode::move_baseMakeActionRequest: Goal Sent. Wait for Result!");
00359   this->moveBaseActive=true;
00360 }
00361 
00362 void TibiDaboHideandseekAlgNode::node_config_update(Config &config, uint32_t level)
00363 {
00364   this->alg_.lock();
00365   ROS_DEBUG("TibiDaboHideandseekAlgNode::config_update!");
00366   //this->variable = config.parameter;
00367   this->alg_.unlock();
00368 }
00369 
00370 void TibiDaboHideandseekAlgNode::addNodeDiagnostics(void)
00371 {
00372 }
00373 
00374 /* main function */
00375 int main(int argc,char *argv[])
00376 {
00377   return algorithm_base::main<TibiDaboHideandseekAlgNode>(argc, argv, "tibi_dabo_hideandseek_alg_node");
00378 }


tibi_dabo_hideandseek
Author(s): fherrero
autogenerated on Fri Dec 6 2013 22:12:38