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
00010 this->loop_rate_ = 1;
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
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
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 public_node_handle_.getParam("windist", windist);
00046 public_node_handle_.getParam("cellsize", cellsize);
00047
00048
00049
00050
00051
00052
00053
00054
00055
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
00061
00062
00063
00064
00065
00066
00067
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
00078 }
00079
00080 void TibiDaboHideandseekAlgNode::mainNodeThread(void)
00081 {
00082
00083 this->alg_.lock();
00084
00085 if(this->seekerPoseReceived && !this->moveBaseActive && this->paused && !this->ready2Move)
00086 {
00087
00088
00089
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
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
00120
00121 break;
00122 case STATE_WIN_SEEKER:
00123
00124 ROS_INFO("GAME: ROBOT WINS !!!");
00125 this->gameStatus=STATE_FINISHED;
00126 break;
00127 case STATE_WIN_HIDER:
00128
00129 ROS_INFO("GAME: HUMAN WINS !!!");
00130 this->gameStatus=STATE_FINISHED;
00131 break;
00132 case STATE_TIE:
00133
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
00154
00155 }
00156
00157 else if(this->ready2Move && !this->paused)
00158 {
00159
00160 move_base_goal_.target_pose = this->seekerGoal;
00161 ROS_INFO("GAME: NEXT TURN. MOVING!!!");
00162 move_baseMakeActionRequest();
00163 this->gameIteration++;
00164
00165 this->ready2Move=false;
00166 }
00167 this->alg_.unlock();
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 }
00178
00179
00180 void TibiDaboHideandseekAlgNode::people_callback(const iri_perception_msgs::peopleTrackingArray::ConstPtr& msg)
00181 {
00182
00183
00184
00185 this->alg_.lock();
00186
00187
00188
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;
00204 hiderPoses.push_back(person);
00205 }
00206 this->hiderPoseReceived = true;
00207 }
00208
00209 this->alg_.unlock();
00210
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
00218 this->alg_.lock();
00219
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
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
00254 move_base_client_.cancelGoal();
00255 }
00256
00257
00258
00259
00260 this->prev_buttons=msg->buttons;
00261 this->alg_.unlock();
00262
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
00270 this->alg_.lock();
00271
00272 if(this->gameStatus!=STATE_FINISHED && !this->ready2Move)
00273 {
00274
00275 try
00276 {
00277 std::string target_frame = "/map";
00278 std::string source_frame = msg->header.frame_id;
00279 ros::Time target_time = msg->header.stamp;
00280
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
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
00301 this->alg_.unlock();
00302
00303 }
00304
00305
00306
00307
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
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
00323 }
00324
00325 void TibiDaboHideandseekAlgNode::move_baseFeedback(const move_base_msgs::MoveBaseFeedbackConstPtr& feedback)
00326 {
00327
00328
00329 bool feedback_is_ok = true;
00330
00331
00332
00333
00334
00335 if( !feedback_is_ok )
00336 {
00337 move_base_client_.cancelGoal();
00338
00339 }
00340 }
00341
00342
00343 void TibiDaboHideandseekAlgNode::move_baseMakeActionRequest()
00344 {
00345 ROS_INFO("TibiDaboHideandseekAlgNode::move_baseMakeActionRequest: Starting New Request!");
00346
00347
00348
00349 move_base_client_.waitForServer();
00350 ROS_INFO("TibiDaboHideandseekAlgNode::move_baseMakeActionRequest: Server is Available!");
00351
00352
00353
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
00367 this->alg_.unlock();
00368 }
00369
00370 void TibiDaboHideandseekAlgNode::addNodeDiagnostics(void)
00371 {
00372 }
00373
00374
00375 int main(int argc,char *argv[])
00376 {
00377 return algorithm_base::main<TibiDaboHideandseekAlgNode>(argc, argv, "tibi_dabo_hideandseek_alg_node");
00378 }