00001 #include "object_detection_alg_node.h"
00002
00003 #include <vector>
00004
00005 ObjectDetectionAlgNode::ObjectDetectionAlgNode(void) :
00006 algorithm_base::IriBaseAlgorithm<ObjectDetectionAlgorithm>(), it_(this->public_node_handle_),
00007 loquendo_client_("loquendo", true),
00008 hri_client_("hri", true),
00009 follow_target_client_("follow_target", true),
00010 cv_ptr_init(false), hri_busy(false), head_busy(false),
00011 current_state_(HOME_STATE)
00012 {
00013
00014
00015 this->loop_rate_ = 5;
00016
00017
00018 this->target_pos_publisher_ = this->public_node_handle_.advertise<geometry_msgs::PoseStamped>("target_pos", 100);
00019 image_pub_ = it_.advertise("image_out", 1);
00020
00021
00022 image_sub_ = it_.subscribe("image_in", 1, &ObjectDetectionAlgNode::image_callback, this);
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 parameters.fun_print_parameters();
00034 parameters.fun_load_detectors();
00035 ipl_scaledImage = cvCreateImage(cvSize(parameters.fun_get_image_width(), parameters.fun_get_image_height()), IPL_DEPTH_8U, 3);
00036
00037 std::vector<std::string> xml(NUM_CLIENTS, std::string(""));
00038 xml[TTS_] = "Let me introduce my self. I am Teebee; a robotic mobile platform, capable to recognize certain objects. Let's get started.";
00039 xml[LEDS_] = "";
00040 xml[HEAD_] = "";
00041 xml[RIGHT_ARM_] = "";
00042 xml[LEFT_ARM_] = "";
00043
00044 loquendoMakeActionRequest(xml[TTS_]);
00045 }
00046
00047 ObjectDetectionAlgNode::~ObjectDetectionAlgNode(void)
00048 {
00049
00050 if (ipl_scaledImage != NULL) cvReleaseImage( &ipl_scaledImage );
00051 }
00052
00053 void ObjectDetectionAlgNode::mainNodeThread(void)
00054 {
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 std::vector<std::string> xml(NUM_CLIENTS, std::string(""));
00067 std::string object_tag;
00068
00069 switch(this->current_state_)
00070 {
00071 case HOME_STATE:
00072 if(!hri_busy)
00073 {
00074 this->current_state_=LOOK_STATE;
00075 sleep(3);
00076
00077
00078 xml[TTS_] = "let's look for an object on the table.";
00079 xml[LEDS_] = "";
00080 xml[HEAD_] = "";
00081 xml[RIGHT_ARM_] = "";
00082 xml[LEFT_ARM_] = "";
00083
00084 loquendoMakeActionRequest(xml[TTS_]);
00085 }
00086 break;
00087 case LOOK_STATE:
00088 if(!hri_busy)
00089 {
00090 this->current_state_=DETECTION_STATE;
00091 }
00092 break;
00093 case DETECTION_STATE:
00094
00095
00096 if( detectOject(object_tag) )
00097 {
00098 this->current_state_=HRI_STATE;
00099
00100
00101 xml[TTS_] = "I think, on the table there is " + object_tag;
00102 xml[LEDS_] = "";
00103 xml[HEAD_] = "";
00104 xml[RIGHT_ARM_] = "";
00105 xml[LEFT_ARM_] = "";
00106
00107 ROS_WARN("I think, on the table there is %s", object_tag.c_str());
00108 loquendoMakeActionRequest(xml[TTS_]);
00109 }
00110
00111 break;
00112 case HRI_STATE:
00113 if(!hri_busy)
00114 {
00115 this->current_state_=HOME_STATE;
00116
00117 xml[TTS_] = "";
00118 xml[LEDS_] = "";
00119 xml[HEAD_] = "";
00120 xml[RIGHT_ARM_] = "";
00121 xml[LEFT_ARM_] = "";
00122
00123
00124 }
00125 break;
00126
00127 }
00128 }
00129
00130 bool ObjectDetectionAlgNode::detectOject(std::string & obj_tag)
00131 {
00132 int numDetections,x1=0,x2=0,y1=0,y2=0,color;
00133 float score;
00134 char const* tag;
00135 cv_bridge::CvImage roscv_outImage;
00136 static int count=0;
00137 std::string tmp_tag;
00138 static std::string object_tag;
00139 bool matched=false,stable=false;
00140
00141 this->image_mutex_.enter();
00142 bool image_ok = (cv_ptr_init);
00143 this->image_mutex_.exit();
00144
00145 if ( image_ok )
00146 {
00147
00148 this->image_mutex_.enter();
00149 IplImage ipl_inImage = cv_ptr->image;
00150
00151 roscv_outImage.header = cv_ptr->header;
00152 roscv_outImage.encoding = cv_ptr->encoding;
00153
00154
00155
00156
00157
00158 cvResize(&ipl_inImage , ipl_scaledImage, CV_INTER_LINEAR );
00159 this->image_mutex_.exit();
00160
00161
00162 clsDetectionSet detections = fun_detection(ipl_scaledImage,¶meters);
00163
00164
00165 numDetections = detections.fun_get_numDetections();
00166 ROS_INFO("ObjectDetectionAlgNode::detectOject: numDetections=%d", numDetections);
00167
00168 if (numDetections>0)
00169 {
00170 for (int ii=1; ii<=numDetections; ii++)
00171 {
00172
00173 detections.detection[ii].fun_get_values(x1,y1,x2,y2,score,tag,color);
00174 std::cout << "data: loaction -> [" << x1 << " " << y1 << " " << x2 << " " << y2 << "] : score -> " << score << " : tag->" << tag << std::endl;
00175 }
00176
00177 if(count==0)
00178 {
00179 detections.detection[1].fun_get_values(x1,y1,x2,y2,score,tag,color);
00180 if( std::string(tag).find("cactus") != std::string::npos )
00181 object_tag = "a cactus. Be aware not to get hurt";
00182 else if( std::string(tag).find("bottle") != std::string::npos )
00183 object_tag = "an empty, beer bottle. Who has drunk it?";
00184 else if( std::string(tag).find("box") != std::string::npos )
00185 object_tag = "an old fashioned floppy disk box";
00186 else if( std::string(tag).find("car") != std::string::npos )
00187 object_tag = "a small, toy car";
00188 else if( std::string(tag).find("elvis") != std::string::npos )
00189 object_tag = "a beautiful elvis mug. Is it from Graceland?";
00190 else if( std::string(tag).find("stapler") != std::string::npos )
00191 object_tag = "a blue stapler";
00192 else if( std::string(tag).find("vase") != std::string::npos )
00193 object_tag = "a plastic purple vase";
00194 else if( std::string(tag).find("mug_color") != std::string::npos )
00195 object_tag = "a colorful coffee mug";
00196 else
00197 object_tag = "none";
00198 ROS_INFO("ObjectDetectionAlgNode::detectOject: chosen object=%s",object_tag.c_str());
00199 count++;
00200 }
00201 else
00202 {
00203 ROS_INFO("ObjectDetectionAlgNode::detectOject: count=%d tag=%s numDetections=%d",count,tag, numDetections);
00204 for(int ii=1;ii<=numDetections;ii++)
00205 {
00206 detections.detection[ii].fun_get_values(x1,y1,x2,y2,score,tag,color);
00207 if( std::string(tag).find("cactus") != std::string::npos )
00208 tmp_tag = "a cactus. Be aware not to get hurt";
00209 else if( std::string(tag).find("bottle") != std::string::npos )
00210 tmp_tag = "an empty, beer bottle. Who has drunk it?";
00211 else if( std::string(tag).find("box") != std::string::npos )
00212 tmp_tag = "an old fashioned floppy disk box";
00213 else if( std::string(tag).find("car") != std::string::npos )
00214 tmp_tag = "a small, toy car";
00215 else if( std::string(tag).find("elvis") != std::string::npos )
00216 tmp_tag = "a beautiful elvis mug. Is it from Graceland?";
00217 else if( std::string(tag).find("stapler") != std::string::npos )
00218 tmp_tag = "a blue stapler";
00219 else if( std::string(tag).find("vase") != std::string::npos )
00220 tmp_tag = "a plastic purple vase";
00221 else if( std::string(tag).find("mug_color") != std::string::npos )
00222 tmp_tag = "a colorful coffee mug";
00223 else
00224 tmp_tag = "none";
00225 ROS_INFO("ObjectDetectionAlgNode::detectOject: matched tmp_tag=%s count=%d",tmp_tag.c_str(),count);
00226 if(tmp_tag.compare(object_tag) == 0)
00227 {
00228 matched=true;
00229 break;
00230 }
00231 }
00232 if(!matched)
00233 {
00234 ROS_INFO("ObjectDetectionAlgNode::detectOject: NOT matched! count=%d",count);
00235 count=0;
00236 }
00237 else
00238 {
00239 ROS_INFO("ObjectDetectionAlgNode::detectOject: tag=%s matched!! count=%d",tag,count);
00240 count++;
00241 if(count >= 5)
00242 {
00243 count = 0;
00244 stable=true;
00245 }
00246 }
00247 }
00248 ROS_INFO("ObjectDetectionAlgNode::detectOject: tag=%s count=%d",tag,count);
00249 }
00250
00251
00252 roscv_outImage.image = cv::cvarrToMat(ipl_scaledImage);
00253 image_pub_.publish(roscv_outImage.toImageMsg());
00254
00255 }
00256
00257 ROS_INFO("ObjectDetectionAlgNode::detectOject: leaving stable=%d",stable);
00258 std::cout << std::endl;
00259
00260 if(stable)
00261 obj_tag = object_tag;
00262
00263 return stable;
00264 }
00265
00266
00267 void ObjectDetectionAlgNode::image_callback(const sensor_msgs::ImageConstPtr& msg)
00268 {
00269
00270 try
00271 {
00272 this->image_mutex_.enter();
00273 cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
00274 cv_ptr_init = true;
00275 this->image_mutex_.exit();
00276 }
00277 catch (cv_bridge::Exception& e)
00278 {
00279 this->image_mutex_.enter();
00280 cv_ptr_init = false;
00281 this->image_mutex_.exit();
00282 ROS_ERROR("cv_bridge exception: %s", e.what());
00283 return;
00284 }
00285 }
00286
00287
00288
00289
00290 void ObjectDetectionAlgNode::loquendoDone(const actionlib::SimpleClientGoalState& state, const iri_common_drivers_msgs::ttsResultConstPtr& result)
00291 {
00292 hri_busy=false;
00293 if( state.toString().compare("SUCCEEDED") == 0 )
00294 ROS_INFO("ObjectDetectionAlgNode::loquendoDone: Goal Achieved!");
00295 else
00296 ROS_INFO("ObjectDetectionAlgNode::loquendoDone: %s", state.toString().c_str());
00297
00298
00299 }
00300
00301 void ObjectDetectionAlgNode::loquendoActive()
00302 {
00303
00304 }
00305
00306 void ObjectDetectionAlgNode::loquendoFeedback(const iri_common_drivers_msgs::ttsFeedbackConstPtr& feedback)
00307 {
00308
00309
00310 bool feedback_is_ok = true;
00311
00312
00313
00314
00315
00316 if( !feedback_is_ok )
00317 {
00318 loquendo_client_.cancelGoal();
00319
00320 }
00321 }
00322 void ObjectDetectionAlgNode::hriDone(const actionlib::SimpleClientGoalState& state, const tibi_dabo_msgs::sequenceResultConstPtr& result)
00323 {
00324 hri_busy=false;
00325
00326 if( state.toString().compare("SUCCEEDED") == 0 )
00327 ROS_INFO("ObjectDetectionAlgNode::hriDone: Goal Achieved!");
00328 else
00329 ROS_INFO("ObjectDetectionAlgNode::hriDone: %s", state.toString().c_str());
00330
00331
00332 }
00333
00334 void ObjectDetectionAlgNode::hriActive()
00335 {
00336
00337 }
00338
00339 void ObjectDetectionAlgNode::hriFeedback(const tibi_dabo_msgs::sequenceFeedbackConstPtr& feedback)
00340 {
00341
00342
00343 bool feedback_is_ok = true;
00344
00345
00346
00347
00348
00349 if( !feedback_is_ok )
00350 {
00351 hri_client_.cancelGoal();
00352
00353 }
00354 }
00355 void ObjectDetectionAlgNode::follow_targetDone(const actionlib::SimpleClientGoalState& state, const iri_nav_msgs::followTargetResultConstPtr& result)
00356 {
00357 head_busy = false;
00358
00359 if( state.toString().compare("SUCCEEDED") == 0 )
00360 ROS_INFO("ObjectDetectionAlgNode::follow_targetDone: Goal Achieved!");
00361 else
00362 ROS_INFO("ObjectDetectionAlgNode::follow_targetDone: %s", state.toString().c_str());
00363
00364
00365 }
00366
00367 void ObjectDetectionAlgNode::follow_targetActive()
00368 {
00369
00370 }
00371
00372 void ObjectDetectionAlgNode::follow_targetFeedback(const iri_nav_msgs::followTargetFeedbackConstPtr& feedback)
00373 {
00374
00375
00376 bool feedback_is_ok = true;
00377
00378
00379
00380 if (feedback->current_dist < 2.0)
00381 {
00382 feedback_is_ok = false;
00383 ROS_INFO("Head Action complete!");
00384 }
00385
00386
00387 if( !feedback_is_ok )
00388 {
00389 follow_target_client_.cancelGoal();
00390
00391 }
00392 }
00393
00394
00395 void ObjectDetectionAlgNode::loquendoMakeActionRequest(const std::string & msg)
00396 {
00397 ROS_INFO("ObjectDetectionAlgNode::loquendoMakeActionRequest: Starting New Request!");
00398
00399
00400
00401 loquendo_client_.waitForServer();
00402 ROS_INFO("ObjectDetectionAlgNode::loquendoMakeActionRequest: Server is Available!");
00403
00404
00405 loquendo_goal_.msg = msg;
00406 loquendo_client_.sendGoal(loquendo_goal_,
00407 boost::bind(&ObjectDetectionAlgNode::loquendoDone, this, _1, _2),
00408 boost::bind(&ObjectDetectionAlgNode::loquendoActive, this),
00409 boost::bind(&ObjectDetectionAlgNode::loquendoFeedback, this, _1));
00410 ROS_INFO("ObjectDetectionAlgNode::loquendoMakeActionRequest: Goal Sent. Wait for Result!");
00411 hri_busy=true;
00412 }
00413 void ObjectDetectionAlgNode::hriMakeActionRequest(const std::vector<std::string> & xml_files)
00414 {
00415 ROS_INFO("ObjectDetectionAlgNode::hriMakeActionRequest: Starting New Request!");
00416
00417
00418
00419 hri_client_.waitForServer();
00420 ROS_INFO("ObjectDetectionAlgNode::hriMakeActionRequest: Server is Available!");
00421
00422 tibi_dabo_msgs::sequenceGoal hri_goal;
00423 hri_goal.sequence_file = std::vector<std::string>(NUM_CLIENTS, std::string(""));
00424 for(unsigned int ii=0; ii<NUM_CLIENTS; ii++)
00425 hri_goal.sequence_file[ii] = xml_files[ii];
00426
00427
00428
00429 hri_client_.sendGoal(hri_goal,
00430 boost::bind(&ObjectDetectionAlgNode::hriDone, this, _1, _2),
00431 boost::bind(&ObjectDetectionAlgNode::hriActive, this),
00432 boost::bind(&ObjectDetectionAlgNode::hriFeedback, this, _1));
00433 ROS_INFO("ObjectDetectionAlgNode::hriMakeActionRequest: Goal Sent. Wait for Result!");
00434
00435 hri_busy=true;
00436 }
00437 void ObjectDetectionAlgNode::follow_targetMakeActionRequest()
00438 {
00439 ROS_INFO("ObjectDetectionAlgNode::follow_targetMakeActionRequest: Starting New Request!");
00440
00441
00442
00443 follow_target_client_.waitForServer();
00444 ROS_INFO("ObjectDetectionAlgNode::follow_targetMakeActionRequest: Server is Available!");
00445
00446
00447
00448 follow_target_client_.sendGoal(follow_target_goal_,
00449 boost::bind(&ObjectDetectionAlgNode::follow_targetDone, this, _1, _2),
00450 boost::bind(&ObjectDetectionAlgNode::follow_targetActive, this),
00451 boost::bind(&ObjectDetectionAlgNode::follow_targetFeedback, this, _1));
00452 ROS_INFO("ObjectDetectionAlgNode::follow_targetMakeActionRequest: Goal Sent. Wait for Result!");
00453 }
00454
00455 void ObjectDetectionAlgNode::node_config_update(Config &config, uint32_t level)
00456 {
00457 this->alg_.lock();
00458
00459 this->alg_.unlock();
00460 }
00461
00462 void ObjectDetectionAlgNode::addNodeDiagnostics(void)
00463 {
00464 }
00465
00466
00467 int main(int argc,char *argv[])
00468 {
00469 return algorithm_base::main<ObjectDetectionAlgNode>(argc, argv, "object_detection_alg_node");
00470 }