00001 #include "laser_people_label_alg_node.h"
00002
00003 LaserPeopleLabelAlgNode::LaserPeopleLabelAlgNode(void) :
00004 algorithm_base::IriBaseAlgorithm<LaserPeopleLabelAlgorithm>()
00005 {
00006
00007
00008
00009
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
00015 this->goal_subscriber_ = this->public_node_handle_.subscribe("goal", 100, &LaserPeopleLabelAlgNode::goal_callback, this);
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
00066
00067 this->alg_.lock();
00068 this->LaserScan_msg_ = currentScan;
00069 this->LaserScan_msg_.intensities = intensities;
00070 this->alg_.unlock();
00071
00072
00073
00074
00075
00076
00077
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
00086 void LaserPeopleLabelAlgNode::goal_callback(const geometry_msgs::PoseStamped::ConstPtr& msg)
00087 {
00088
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
00103
00104
00105
00106
00107
00108
00109
00110
00111 void LaserPeopleLabelAlgNode::initialize()
00112 {
00113 if(debug)
00114 cout << "LaserPeopleLabelAlgNode::initialize()" << endl;
00115
00116 currentIteration = 0;
00117 currentBagScan = 0;
00118 skipScan = false;
00119 modeArea = 0;
00120
00121
00122
00123
00124 alg_.myLaserPeopleLabel->setFilePath(filePath);
00125 bagFilePath = filePath + "bagFile.bag";
00126 labelsFilePath = filePath + "labels.txt";
00127
00128
00129
00130
00131
00132
00133 if(!doFileExist(bagFilePath))
00134 {
00135 cout << "--- Error: missing "<< bagFilePath << endl;
00136 exit(1);
00137 }
00138
00139
00140 loadBag();
00141
00142
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);
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
00179 nextScan();
00180 }
00181
00182
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
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
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
00257
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
00266
00267
00268
00269 }
00270 else
00271 {
00272 button_type = segment;
00273 }
00274 }
00275
00276 }
00277
00278
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
00340 break;
00341
00342 default:
00343
00344 break;
00345
00346 }
00347 }
00348
00349
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
00362 if(unsigned(currentBagScan+1)>bagScans.size())
00363 {
00364 mode=ending;
00365 return;
00366 }
00367
00368 this->alg_.lock();
00369
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
00377 if(!skipScan && currentIteration!=0)
00378 {
00379 alg_.myLaserPeopleLabel->savePointsFile(currentScan.ranges, append);
00380 }
00381
00382
00383 if(!skipScan)
00384 currentIteration++;
00385 currentBagScan++;
00386
00387
00388
00389 currentScan = bagScans[currentBagScan-1];
00390
00391
00392
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
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
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
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
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
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
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
00601 int main(int argc,char *argv[])
00602 {
00603 return algorithm_base::main<LaserPeopleLabelAlgNode>(argc, argv, "laser_people_label_alg_node");
00604 }