laser_people_label_alg_node.cpp
Go to the documentation of this file.
00001 #include "laser_people_label_alg_node.h"
00002 
00003 LaserPeopleLabelAlgNode::LaserPeopleLabelAlgNode(void) :
00004   algorithm_base::IriBaseAlgorithm<LaserPeopleLabelAlgorithm>()
00005 {
00006   //init class attributes if necessary
00007   //this->loop_rate_ = 2;//in [Hz]
00008 
00009   // [init publishers]
00010   this->areas_array_publisher_ = this->public_node_handle_.advertise<visualization_msgs::MarkerArray>("areas_array", 100);
00011   this->buttons_array_publisher_ = this->public_node_handle_.advertise<visualization_msgs::MarkerArray>("buttons_array", 100);
00012   this->scanLabel_publisher_ = this->public_node_handle_.advertise<sensor_msgs::LaserScan>("scanLabel", 100);
00013 
00014   // [init subscribers]
00015   this->goal_subscriber_ = this->public_node_handle_.subscribe("goal", 100, &LaserPeopleLabelAlgNode::goal_callback, this);
00016 
00017   // [init services]
00018 
00019   // [init clients]
00020 
00021   // [init action servers]
00022 
00023   // [init action clients]
00024 
00025   //define a private node handle if it does not exist already
00026   ros::NodeHandle private_node_handle("~");
00027   private_node_handle.param<std::string>("scanTopic", scanTopic, "scan");
00028   private_node_handle.param<std::string>("filePath", filePath, "~/iri-lab/ros/iri-ros-pkg/iri_perception/iri_laser_people_label/data/");
00029 
00030   debug=false;
00031   initialize();
00032 
00033 }
00034 
00035 LaserPeopleLabelAlgNode::~LaserPeopleLabelAlgNode(void)
00036 {
00037   // [free dynamic memory]
00038 }
00039 
00040 void LaserPeopleLabelAlgNode::mainNodeThread(void)
00041 {
00042   switch(mode)
00043   {
00044     case ending:
00045       alg_.myLaserPeopleLabel->saveLabelsFile(append);
00046       cout << "----------------------------------------------" << endl;
00047       cout << "               CTRL+C to exit                 " << endl;
00048       cout << "----------------------------------------------" << endl;
00049       ros::shutdown();
00050       break;
00051 
00052     case playing:
00053       nextScan();
00054       break;
00055 
00056     case standby:
00057 
00058       break;
00059 
00060     default:
00061 
00062       break;
00063   }
00064 
00065   // [fill msg structures]
00066   //this->MarkerArrayAreas_msg_.data = my_var;
00067   this->alg_.lock();
00068   this->LaserScan_msg_ = currentScan;
00069   this->LaserScan_msg_.intensities = intensities;
00070   this->alg_.unlock();
00071 
00072   // [fill srv structure and make request to the server]
00073 
00074   // [fill action structure and make request to the action server]
00075 
00076   // [publish messages]
00077   //this->areas_array_publisher_.publish(this->MarkerArrayAreas_msg_);
00078 
00079   this->scanLabel_publisher_.publish(this->LaserScan_msg_);
00080 
00081   fillButtons(this->MarkerArrayButtons_msg_);
00082   this->buttons_array_publisher_.publish(this->MarkerArrayButtons_msg_);
00083 }
00084 
00085 /*  [subscriber callbacks] */
00086 void LaserPeopleLabelAlgNode::goal_callback(const geometry_msgs::PoseStamped::ConstPtr& msg)
00087 {
00088   //ROS_INFO("LaserPeopleLabelAlgNode::goal_callback: New Message Received");
00089 
00090   this->goal_mutex_.enter();
00091 
00092   this->currentGoal.clear();
00093   this->currentGoal.push_back(msg->pose.position.x);
00094   this->currentGoal.push_back(msg->pose.position.y);
00095 
00096   getButton(currentGoal);
00097   doButton();
00098   this->goal_mutex_.exit();
00099 
00100 }
00101 
00102 /*  [service callbacks] */
00103 
00104 /*  [action callbacks] */
00105 
00106 /*  [action requests] */
00107 
00108 /* [class functions] */
00109 
00110 // Inits startup variables, loads files and performs the first iteration
00111 void LaserPeopleLabelAlgNode::initialize()
00112 {
00113   if(debug)
00114     cout << "LaserPeopleLabelAlgNode::initialize()" << endl;
00115   //initialize variables
00116   currentIteration = 0;
00117   currentBagScan   = 0;
00118   skipScan         = false;
00119   modeArea         = 0;
00120 
00121   // defines paths to files and scan topic (to read in bagFile)
00122   //filePath = "/home/fherrero/iri-stuff/my-ros/iri_laser_people_label/data/";
00123   //filePath = "$(find iri_laser_people_label)/data/";
00124   alg_.myLaserPeopleLabel->setFilePath(filePath);
00125   bagFilePath = filePath + "bagFile.bag";
00126   labelsFilePath = filePath + "labels.txt";
00127   //scanTopic = "/tibi/front_laser/scan";
00128   //scanTopic = "scan";
00129 
00130 
00131 
00132   // checks if bagFile exists
00133   if(!doFileExist(bagFilePath))
00134   {
00135     cout << "--- Error: missing "<< bagFilePath << endl;
00136     exit(1);
00137   }
00138 
00139   // loads scans from bagFile
00140   loadBag();
00141 
00142   // checks if labels already exists, and asks to append data or not
00143   append = false;
00144   if(doFileExist(labelsFilePath))
00145   {
00146     while(1)
00147     {
00148       cout << "--- Do you want to APPEND information to existing data? [y/n]: ";
00149       string input;
00150       getline( cin, input );
00151       if(input=="y" || input=="Y" || input=="yes" || input=="YES" || input=="Yes")
00152       {
00153         append=1;
00154         string pointsFile = alg_.myLaserPeopleLabel->pointsFile;
00155         alg_.myLaserPeopleLabel->getNumberOfScans(pointsFile); //Get number of scans in data (needed for appending labels)
00156         cout << "--- Information will be added to existing data ("<<alg_.myLaserPeopleLabel->lastIter<<" iterations)" << endl;
00157         break;
00158       }
00159       else if(input=="n" || input=="N" || input=="no" || input=="NO" || input=="No"){
00160         append=0;
00161         if ( !remove(alg_.myLaserPeopleLabel->pointsFile.c_str()) )
00162         {
00163           cout<<"--- Deleted previous file: " << alg_.myLaserPeopleLabel->pointsFile << endl;
00164         }
00165         else
00166         {
00167           cout<<"--- Can't delete file: " << alg_.myLaserPeopleLabel->pointsFile << endl;
00168         }
00169         cout << "--- Existing files will be overwritten with new data" << endl;
00170         break;
00171       }
00172       else {
00173         cout << "--- Unrecognized answer. Try again" << endl;
00174       }
00175     }
00176   }
00177 
00178   // first iteration
00179   nextScan();
00180 }
00181 
00182 // Loads a bag into a vector of scans (std::vector<sensor_msgs::LaserScan> bagScans )
00183 void LaserPeopleLabelAlgNode::loadBag(void)
00184 {
00185   if(debug)
00186     cout << "LaserPeopleLabelAlgNode::loadBag()" << endl;
00187   cout << "--- Loading '" << scanTopic << "' topic from '"<< bagFilePath << "' file." << endl;
00188   bagScans.clear();
00189   rosbag::Bag bag(bagFilePath.c_str());
00190   rosbag::View view(bag, rosbag::TopicQuery(scanTopic));
00191   for(iter = view.begin(); iter != view.end(); ++iter)
00192   {
00193     rosbag::MessageInstance m = *iter;
00194     sensor_msgs::LaserScan::ConstPtr msgScan = m.instantiate<sensor_msgs::LaserScan>();
00195     this->alg_.lock();
00196     this->currentScan=*msgScan;
00197     this->currentScan.header.frame_id = "/laser";
00198     bagScans.push_back(currentScan);
00199     this->alg_.unlock();
00200   }
00201   bag.close();
00202   cout << "--- Loaded " << bagScans.size() << " scans." << endl;
00203   if(bagScans.size()==0)
00204   {
00205     cout << "--- Modify scanTopic param in launch according to bagFile in use" << endl;
00206     exit(1);
00207   }
00208 }
00209 
00210 // Returns if specified file exists
00211 bool LaserPeopleLabelAlgNode::doFileExist(string filePath)
00212 {
00213   ifstream ifile(filePath.c_str());
00214   if(ifile)
00215     cout << "--- Check: existing file " << filePath << endl;
00216   return ifile;
00217 }
00218 
00219 // Sets button_type value according to received goal
00220 void LaserPeopleLabelAlgNode::getButton(vector<float> goal)
00221 {
00222   float x = goal[0];
00223   float y = goal[1];
00224   float x1   = -2;
00225   float x2   = -3;
00226   float x3   = -4;
00227   float x4   = -5;
00228 
00229   if(modeArea!=0)
00230   {
00231     setArea();
00232     button_type = idle;
00233   }
00234   else
00235   {
00236     button_type = segment;
00237     if(x<x1 && x>x2)
00238     {
00239       if(y<2 && y>1)
00240         button_type = next;
00241       else if(y<1 && y>0)
00242         button_type = go;
00243       else if(y<0 && y>-1)
00244         button_type = skip;
00245       else if(y<-1 && y>-2)
00246         button_type = end;
00247     }
00248     else if(x<x2 && x>x3)
00249     {
00250       if(y<2 && y>1)
00251         button_type = Apos;
00252       else if(y<1 && y>0)
00253         button_type = Aneg;
00254       else if(y<0 && y>-1)
00255         button_type = Areset;
00256       //else if(y<-1 && y>-2)
00257         //button_type = empty;
00258     }
00259     else if(x<x3 && x>x4)
00260     {
00261       if(y<2 && y>1)
00262         button_type = play;
00263       else if(y<1 && y>0)
00264         button_type = stop;
00265       //else if(y<0 && y>-1)
00266         //button_type = empty;
00267       //else if(y<-1 && y>-2)
00268         //button_type = empty;
00269     }
00270     else
00271     {
00272       button_type = segment;
00273     }
00274   }
00275 
00276 }
00277 
00278 // Performs the actions associated to the pressed button
00279 void LaserPeopleLabelAlgNode::doButton()
00280 {
00281   skipScan = false;
00282   switch(button_type)
00283   {
00284     case next:
00285       nextScan();
00286       break;
00287 
00288     case go:
00289       skipScan=true;
00290       alg_.myLaserPeopleLabel->removeLabels(currentIteration);
00291       cout<<"--- Skipping scan "<< currentBagScan <<endl;
00292       goToScan();
00293       nextScan();
00294       break;
00295 
00296     case skip:
00297       skipScan=true;
00298       alg_.myLaserPeopleLabel->removeLabels(currentIteration);
00299       cout<<"--- Skipping scan "<< currentBagScan <<endl;
00300       nextScan();
00301       break;
00302 
00303     case end:
00304       mode = ending;
00305       break;
00306 
00307     case Apos:
00308       cout<<"--- Started adding area"<< endl;
00309       modeArea=1;
00310       areaVertex=0;
00311       break;
00312 
00313     case Aneg:
00314       cout<<"--- Started substracting area"<< endl;
00315       modeArea=-1;
00316       areaVertex=0;
00317       break;
00318 
00319     case Areset:
00320       cout<<"--- Reseting areas "<< endl;
00321       areaListPos.clear();
00322       areaListNeg.clear();
00323       fillAreas(this->MarkerArrayAreas_msg_);
00324       break;
00325     case play:
00326       mode = playing;
00327       break;
00328 
00329     case stop:
00330       mode = standby;
00331       break;
00332 
00333     case segment:
00334       alg_.myLaserPeopleLabel->labelSegment(currentGoal, currentIteration);
00335       intensities = alg_.myLaserPeopleLabel->getIntensities();
00336       break;
00337 
00338     case idle:
00339       //nothing
00340       break;
00341 
00342     default:
00343       //nothing
00344       break;
00345 
00346   }
00347 }
00348 
00349 // Loads the next scan of the bagFile (...)
00350 void LaserPeopleLabelAlgNode::nextScan()
00351 {
00352   if(debug)
00353     cout << "LaserPeopleLabelAlgNode::nextScan()" << endl;
00354 
00355   if(areaListPos.size()!=0 || areaListNeg.size()!=0)
00356   {
00357     cout<<"--- Labeling with areas" << endl;
00358     labelAreas();
00359   }
00360 
00361   // If reached end of bag, end labeling
00362   if(unsigned(currentBagScan+1)>bagScans.size())
00363   {
00364     mode=ending;
00365     return;
00366   }
00367 
00368   this->alg_.lock();
00369   //On start, save scan parameters on file
00370   if(currentIteration==0)
00371   {
00372     alg_.myLaserPeopleLabel->saveParamsFile(currentScan.angle_min, currentScan.angle_max, currentScan.angle_increment);
00373     cout << "--- Saved params.txt"<<endl;
00374   }
00375 
00376   //Save scan if no skipScan is set
00377   if(!skipScan && currentIteration!=0)
00378   {
00379     alg_.myLaserPeopleLabel->savePointsFile(currentScan.ranges, append);
00380   }
00381 
00382   // Next iteration
00383   if(!skipScan)
00384     currentIteration++;
00385   currentBagScan++;
00386 
00387   // Load next scan in currentScan
00388 
00389   currentScan = bagScans[currentBagScan-1];
00390 
00391 
00392   // labelIteration (ranges -> points -> segments)
00393   alg_.myLaserPeopleLabel->labelIteration(currentScan.ranges, currentScan.angle_min, currentScan.angle_max, currentScan.angle_increment);
00394   intensities = alg_.myLaserPeopleLabel->getIntensities();
00395 
00396   cout<<"--- Iter: "<< currentIteration+alg_.myLaserPeopleLabel->lastIter << "   Scan: " << currentBagScan <<"/"<< bagScans.size() << endl;
00397   this->alg_.unlock();
00398 
00399 }
00400 
00401 // GoToScan button, asks new scan input to jump to
00402 void LaserPeopleLabelAlgNode::goToScan()
00403 {
00404   unsigned int scan;
00405   while(1){
00406     cout << "--- Go to scan number: ";
00407     string input3;
00408     getline(cin,input3);
00409     istringstream iss( input3 );
00410     if( ( iss >> scan) && scan>0 && scan<=bagScans.size() ){
00411       iss>>scan;
00412       break;
00413     }
00414     else if( scan<=0 || scan>bagScans.size() ){
00415       cout<<"--- Scan must be between 1 and " << bagScans.size() << endl;
00416     }
00417     else if( !(iss>>scan) ) {
00418       cout<<"--- It must be an integer!"<<endl;
00419     }
00420   }
00421   currentBagScan=scan-1;
00422 }
00423 
00424 void LaserPeopleLabelAlgNode::setArea()
00425 {
00426   cout << "--- --- modeArea: click to add vertex" << endl;
00427   area.push_back(currentGoal[0]);
00428   area.push_back(currentGoal[1]);
00429   areaVertex++;
00430   cout<<"--- --- Added area vertex "<< areaVertex <<"/2"<< endl;
00431 
00432   if(areaVertex==2)
00433   {
00434     if(modeArea==1)
00435       areaListPos.push_back(area);
00436     if(modeArea==-1)
00437       areaListNeg.push_back(area);
00438     modeArea=0;
00439     area.clear();
00440     cout << "--- Area finished" << endl;
00441     fillAreas(this->MarkerArrayAreas_msg_);
00442   }
00443 
00444 }
00445 
00446 void LaserPeopleLabelAlgNode::labelAreas()
00447 {
00448   for(unsigned int i=0; i<areaListPos.size(); i++)
00449   {
00450     cout << "--- --- Using positive area " << i+1 << "/"<<areaListPos.size()<< endl;
00451     float xmax = max( areaListPos[i][0],areaListPos[i][2] );
00452     float xmin = min( areaListPos[i][0],areaListPos[i][2] );
00453     float ymax = max( areaListPos[i][1],areaListPos[i][3] );
00454     float ymin = min( areaListPos[i][1],areaListPos[i][3] );
00455     alg_.myLaserPeopleLabel->labelArea(xmax,xmin, ymax, ymin, 1.0, currentIteration);
00456   }
00457 
00458   for(unsigned int i=0; i<areaListNeg.size(); i++)
00459   {
00460     cout << "--- --- Using negative area " << i+1 << "/"<<areaListNeg.size()<< endl;
00461     float xmax = max( areaListNeg[i][0],areaListNeg[i][2] );
00462     float xmin = min( areaListNeg[i][0],areaListNeg[i][2] );
00463     float ymax = max( areaListNeg[i][1],areaListNeg[i][3] );
00464     float ymin = min( areaListNeg[i][1],areaListNeg[i][3] );
00465     alg_.myLaserPeopleLabel->labelArea(xmax, xmin, ymax, ymin, -1.0, currentIteration );
00466   }
00467 }
00468 
00469 // Defines the buttons (text and boxes) to show on rviz
00470 void LaserPeopleLabelAlgNode::fillButtons(visualization_msgs::MarkerArray & buttons)
00471 {
00472   string buttonText[] = {"Next",   "Go", "Skip",  "End",  "A+",  "A-",  "A0", "Play", "Stop"};
00473   float buttonR[]     = {    0 ,     0 ,     1 ,     1 ,    1 ,  0.4 ,    1 ,     0 ,     1 };
00474   float buttonG[]     = {    1 ,     1 ,     1 ,     0 ,    0 ,    1 ,  0.4 ,     1 ,     0 };
00475   float buttonB[]     = {    0 ,     1 ,     0 ,     0 ,    1 ,    0 ,    0 ,     0 ,     0 };
00476   float buttonX[]     = { -2.5 ,  -2.5 ,  -2.5 ,  -2.5 , -3.5 , -3.5 , -3.5 ,  -4.5 ,  -4.5 };
00477   float buttonY[]     = {  1.5 ,   0.5 ,  -0.5 ,  -1.5 ,  1.5 ,  0.5 , -0.5 ,   1.5 ,   0.5 };
00478 
00479   int buttonsNumber = sizeof(buttonR) / sizeof(float);
00480   buttons.markers.resize(2*buttonsNumber);
00481 
00482   for(int i=0; i<buttonsNumber; i++)
00483   {
00484     buttons.markers[i].header.frame_id = currentScan.header.frame_id;
00485     buttons.markers[i].id     = i;
00486     buttons.markers[i].type   = visualization_msgs::Marker::TEXT_VIEW_FACING;
00487     buttons.markers[i].action = visualization_msgs::Marker::ADD;
00488 
00489     buttons.markers[i].pose.position.x = buttonX[i];
00490     buttons.markers[i].pose.position.y = buttonY[i];
00491     buttons.markers[i].pose.position.z = 0;
00492 
00493     buttons.markers[i].scale.z = 0.5;
00494 
00495     buttons.markers[i].text= buttonText[i];
00496     buttons.markers[i].color.r = buttonR[i];
00497     buttons.markers[i].color.g = buttonG[i];
00498     buttons.markers[i].color.b = buttonB[i];
00499     buttons.markers[i].color.a = 1;
00500   }
00501 
00502   int j=0;
00503   for(int i=buttonsNumber; i<2*buttonsNumber; i++)
00504   {
00505     buttons.markers[i].header.frame_id = currentScan.header.frame_id;
00506     buttons.markers[i].id = i;
00507     buttons.markers[i].type = visualization_msgs::Marker::CUBE;
00508     buttons.markers[i].action = visualization_msgs::Marker::ADD;
00509 
00510     buttons.markers[i].pose.position.x = buttonX[j];
00511     buttons.markers[i].pose.position.y = buttonY[j];
00512     buttons.markers[i].pose.position.z = 0;
00513 
00514     buttons.markers[i].scale.x = 1;
00515     buttons.markers[i].scale.y = 1;
00516     buttons.markers[i].scale.z = 0.1;
00517 
00518     buttons.markers[i].color.r = buttonR[j];
00519     buttons.markers[i].color.g = buttonG[j];
00520     buttons.markers[i].color.b = buttonB[j];
00521     buttons.markers[i].color.a = 0.25;
00522     j++;
00523   }
00524 
00525 }
00526 
00527 void LaserPeopleLabelAlgNode::fillAreas(visualization_msgs::MarkerArray & areas)
00528 {
00529   for(unsigned int i=0; i<areas.markers.size(); i++)
00530   {
00531     areas.markers[i].action = visualization_msgs::Marker::DELETE;
00532   }
00533 
00534   this->areas_array_publisher_.publish(this->MarkerArrayAreas_msg_);
00535 
00536   areas.markers.resize(areaListPos.size() + areaListNeg.size());
00537   //cout << "--- --- Drawing areas (+): " << areaListPos.size() << endl;
00538 
00539   for(unsigned int i=0; i<areaListPos.size(); i++)
00540   {
00541     areas.markers[i].header.frame_id = currentScan.header.frame_id;
00542     areas.markers[i].id = i;
00543     areas.markers[i].type = visualization_msgs::Marker::CUBE;
00544     areas.markers[i].action = visualization_msgs::Marker::ADD;
00545 
00546     areas.markers[i].pose.position.x = (areaListPos[i][0]+areaListPos[i][2])/2.0;
00547     areas.markers[i].pose.position.y = (areaListPos[i][1]+areaListPos[i][3])/2.0;
00548     areas.markers[i].pose.position.z = 0;
00549 
00550     areas.markers[i].scale.x = abs(areaListPos[i][0]-areaListPos[i][2]);
00551     areas.markers[i].scale.y = abs(areaListPos[i][1]-areaListPos[i][3]);
00552     areas.markers[i].scale.z = 0.1;
00553 
00554     //areas.markers[i].text=" ";
00555     areas.markers[i].color.r = 1.0;
00556     areas.markers[i].color.g = 0.0;
00557     areas.markers[i].color.b = 0.0;
00558     areas.markers[i].color.a = 0.25;
00559   }
00560 
00561   //cout << "--- --- Drawing areas (-): " << areaListNeg.size() << endl;
00562 
00563   for(unsigned int i=areaListPos.size(); i<(areaListPos.size()+areaListNeg.size()); i++)
00564   {
00565     int t=i-areaListPos.size();
00566     areas.markers[i].header.frame_id = currentScan.header.frame_id;
00567     areas.markers[i].id = i;
00568     areas.markers[i].type = visualization_msgs::Marker::CUBE;
00569     areas.markers[i].action = visualization_msgs::Marker::ADD;
00570 
00571     areas.markers[i].pose.position.x = (areaListNeg[t][0]+areaListNeg[t][2])/2.0;
00572     areas.markers[i].pose.position.y = (areaListNeg[t][1]+areaListNeg[t][3])/2.0;
00573     areas.markers[i].pose.position.z = 0;
00574 
00575     areas.markers[i].scale.x = abs(areaListNeg[t][0]-areaListNeg[t][2]);
00576     areas.markers[i].scale.y = abs(areaListNeg[t][1]-areaListNeg[t][3]);
00577     areas.markers[i].scale.z = 0.1;
00578 
00579     //areas.markers[i].text=" ";
00580     areas.markers[i].color.r = 0.5;
00581     areas.markers[i].color.g = 0.5;
00582     areas.markers[i].color.b = 0.5;
00583     areas.markers[i].color.a = 0.25;
00584   }
00585 
00586   this->areas_array_publisher_.publish(this->MarkerArrayAreas_msg_);
00587 }
00588 
00589 void LaserPeopleLabelAlgNode::node_config_update(Config &config, uint32_t level)
00590 {
00591   this->alg_.lock();
00592 
00593   this->alg_.unlock();
00594 }
00595 
00596 void LaserPeopleLabelAlgNode::addNodeDiagnostics(void)
00597 {
00598 }
00599 
00600 /* main function */
00601 int main(int argc,char *argv[])
00602 {
00603   return algorithm_base::main<LaserPeopleLabelAlgNode>(argc, argv, "laser_people_label_alg_node");
00604 }


iri_laser_people_label
Author(s): fherrero
autogenerated on Fri Dec 6 2013 22:57:38