00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <ros/ros.h>
00035
00036 #include <leg_detector/LegDetectorConfig.h>
00037 #include <leg_detector/laser_processor.h>
00038 #include <leg_detector/calc_leg_features.h>
00039
00040 #include <opencv/cxcore.h>
00041 #include <opencv/cv.h>
00042 #include <opencv/ml.h>
00043
00044 #include <people_msgs/PositionMeasurement.h>
00045 #include <people_msgs/PositionMeasurementArray.h>
00046 #include <sensor_msgs/LaserScan.h>
00047
00048 #include <tf/transform_listener.h>
00049 #include <tf/message_filter.h>
00050 #include <message_filters/subscriber.h>
00051
00052 #include <people_tracking_filter/tracker_kalman.h>
00053 #include <people_tracking_filter/state_pos_vel.h>
00054 #include <people_tracking_filter/rgb.h>
00055 #include <visualization_msgs/Marker.h>
00056 #include <dynamic_reconfigure/server.h>
00057
00058 #include <algorithm>
00059
00060 using namespace std;
00061 using namespace laser_processor;
00062 using namespace ros;
00063 using namespace tf;
00064 using namespace estimation;
00065 using namespace BFL;
00066 using namespace MatrixWrapper;
00067
00068
00069 static double no_observation_timeout_s = 0.5;
00070 static double max_second_leg_age_s = 2.0;
00071 static double max_track_jump_m = 1.0;
00072 static double max_meas_jump_m = 0.75;
00073 static double leg_pair_separation_m = 1.0;
00074 static string fixed_frame = "odom_combined";
00075
00076 static double kal_p = 4, kal_q = .002, kal_r = 10;
00077 static bool use_filter = true;
00078
00079
00080 class SavedFeature
00081 {
00082 public:
00083 static int nextid;
00084 TransformListener& tfl_;
00085
00086 BFL::StatePosVel sys_sigma_;
00087 TrackerKalman filter_;
00088
00089 string id_;
00090 string object_id;
00091 ros::Time time_;
00092 ros::Time meas_time_;
00093
00094 double reliability, p;
00095
00096 Stamped<Point> position_;
00097 SavedFeature* other;
00098 float dist_to_person_;
00099
00100
00101 SavedFeature(Stamped<Point> loc, TransformListener& tfl)
00102 : tfl_(tfl),
00103 sys_sigma_(Vector3(0.05, 0.05, 0.05), Vector3(1.0, 1.0, 1.0)),
00104 filter_("tracker_name",sys_sigma_),
00105 reliability(-1.), p(4)
00106 {
00107 char id[100];
00108 snprintf(id,100,"legtrack%d", nextid++);
00109 id_ = std::string(id);
00110
00111 object_id = "";
00112 time_ = loc.stamp_;
00113 meas_time_ = loc.stamp_;
00114 other = NULL;
00115
00116 try {
00117 tfl_.transformPoint(fixed_frame, loc, loc);
00118 } catch(...) {
00119 ROS_WARN("TF exception spot 6.");
00120 }
00121 StampedTransform pose( Pose(Quaternion(0.0, 0.0, 0.0, 1.0), loc), loc.stamp_, id_, loc.frame_id_);
00122 tfl_.setTransform(pose);
00123
00124 StatePosVel prior_sigma(Vector3(0.1,0.1,0.1), Vector3(0.0000001, 0.0000001, 0.0000001));
00125 filter_.initialize(loc, prior_sigma, time_.toSec());
00126
00127 StatePosVel est;
00128 filter_.getEstimate(est);
00129
00130 updatePosition();
00131 }
00132
00133 void propagate(ros::Time time)
00134 {
00135 time_ = time;
00136
00137 filter_.updatePrediction(time.toSec());
00138
00139 updatePosition();
00140 }
00141
00142 void update(Stamped<Point> loc, double probability)
00143 {
00144 StampedTransform pose( Pose(Quaternion(0.0, 0.0, 0.0, 1.0), loc), loc.stamp_, id_, loc.frame_id_);
00145 tfl_.setTransform(pose);
00146
00147 meas_time_ = loc.stamp_;
00148 time_ = meas_time_;
00149
00150 SymmetricMatrix cov(3);
00151 cov = 0.0;
00152 cov(1,1) = 0.0025;
00153 cov(2,2) = 0.0025;
00154 cov(3,3) = 0.0025;
00155
00156 filter_.updateCorrection(loc, cov);
00157
00158 updatePosition();
00159
00160 if(reliability<0 || !use_filter){
00161 reliability = probability;
00162 p = kal_p;
00163 }
00164 else{
00165 p += kal_q;
00166 double k = p / (p+kal_r);
00167 reliability += k * (probability - reliability);
00168 p *= (1 - k);
00169 }
00170 }
00171
00172 double getLifetime()
00173 {
00174 return filter_.getLifetime();
00175 }
00176
00177 double getReliability()
00178 {
00179 return reliability;
00180 }
00181
00182 private:
00183 void updatePosition()
00184 {
00185 StatePosVel est;
00186 filter_.getEstimate(est);
00187
00188 position_[0] = est.pos_[0];
00189 position_[1] = est.pos_[1];
00190 position_[2] = est.pos_[2];
00191 position_.stamp_ = time_;
00192 position_.frame_id_ = fixed_frame;
00193 double nreliability = fmin(1.0, fmax(0.1, est.vel_.length() / 0.5));
00194
00195 }
00196 };
00197
00198 int SavedFeature::nextid = 0;
00199
00200
00201
00202
00203 class MatchedFeature
00204 {
00205 public:
00206 SampleSet* candidate_;
00207 SavedFeature* closest_;
00208 float distance_;
00209 double probability_;
00210
00211 MatchedFeature(SampleSet* candidate, SavedFeature* closest, float distance, double probability)
00212 : candidate_(candidate)
00213 , closest_(closest)
00214 , distance_(distance)
00215 , probability_(probability)
00216 {}
00217
00218 inline bool operator< (const MatchedFeature& b) const
00219 {
00220 return (distance_ < b.distance_);
00221 }
00222 };
00223
00224 int g_argc;
00225 char** g_argv;
00226
00227
00228
00229
00230
00231 class LegDetector
00232 {
00233 public:
00234 NodeHandle nh_;
00235
00236 TransformListener tfl_;
00237
00238 ScanMask mask_;
00239
00240 int mask_count_;
00241
00242 CvRTrees forest;
00243
00244 float connected_thresh_;
00245
00246 int feat_count_;
00247
00248 char save_[100];
00249
00250 list<SavedFeature*> saved_features_;
00251 boost::mutex saved_mutex_;
00252
00253 int feature_id_;
00254
00255 bool use_seeds_;
00256 bool publish_legs_, publish_people_, publish_leg_markers_, publish_people_markers_;
00257 int next_p_id_;
00258 double leg_reliability_limit_;
00259 int min_points_per_group;
00260
00261 ros::Publisher people_measurements_pub_;
00262 ros::Publisher leg_measurements_pub_;
00263 ros::Publisher markers_pub_;
00264
00265 dynamic_reconfigure::Server<leg_detector::LegDetectorConfig> server_;
00266
00267 message_filters::Subscriber<people_msgs::PositionMeasurement> people_sub_;
00268 message_filters::Subscriber<sensor_msgs::LaserScan> laser_sub_;
00269 tf::MessageFilter<people_msgs::PositionMeasurement> people_notifier_;
00270 tf::MessageFilter<sensor_msgs::LaserScan> laser_notifier_;
00271
00272 LegDetector(ros::NodeHandle nh) :
00273 nh_(nh),
00274 mask_count_(0),
00275 feat_count_(0),
00276 next_p_id_(0),
00277 people_sub_(nh_,"people_tracker_filter",10),
00278 laser_sub_(nh_,"scan",10),
00279 people_notifier_(people_sub_,tfl_,fixed_frame,10),
00280 laser_notifier_(laser_sub_,tfl_,fixed_frame,10)
00281 {
00282 if (g_argc > 1) {
00283 forest.load(g_argv[1]);
00284 feat_count_ = forest.get_active_var_mask()->cols;
00285 printf("Loaded forest with %d features: %s\n", feat_count_, g_argv[1]);
00286 } else {
00287 printf("Please provide a trained random forests classifier as an input.\n");
00288 shutdown();
00289 }
00290
00291 nh_.param<bool>("use_seeds", use_seeds_, !true);
00292
00293
00294 leg_measurements_pub_ = nh_.advertise<people_msgs::PositionMeasurementArray>("leg_tracker_measurements",0);
00295 people_measurements_pub_ = nh_.advertise<people_msgs::PositionMeasurementArray>("people_tracker_measurements", 0);
00296 markers_pub_ = nh_.advertise<visualization_msgs::Marker>("visualization_marker", 20);
00297
00298 if(use_seeds_){
00299 people_notifier_.registerCallback(boost::bind(&LegDetector::peopleCallback, this, _1));
00300 people_notifier_.setTolerance(ros::Duration(0.01));
00301 }
00302 laser_notifier_.registerCallback(boost::bind(&LegDetector::laserCallback, this, _1));
00303 laser_notifier_.setTolerance(ros::Duration(0.01));
00304
00305 dynamic_reconfigure::Server<leg_detector::LegDetectorConfig>::CallbackType f;
00306 f = boost::bind(&LegDetector::configure, this, _1, _2);
00307 server_.setCallback(f);
00308
00309 feature_id_ = 0;
00310 }
00311
00312
00313 ~LegDetector()
00314 {
00315 }
00316
00317 void configure(leg_detector::LegDetectorConfig &config, uint32_t level) {
00318 connected_thresh_ = config.connection_threshold;
00319 min_points_per_group = config.min_points_per_group;
00320 leg_reliability_limit_ = config.leg_reliability_limit;
00321 publish_legs_ = config.publish_legs;
00322 publish_people_ = config.publish_people;
00323 publish_leg_markers_ = config.publish_leg_markers;
00324 publish_people_markers_ = config.publish_people_markers;
00325
00326 no_observation_timeout_s = config.no_observation_timeout;
00327 max_second_leg_age_s = config.max_second_leg_age;
00328 max_track_jump_m = config.max_track_jump;
00329 max_meas_jump_m = config.max_meas_jump;
00330 leg_pair_separation_m = config.leg_pair_separation;
00331 if(fixed_frame.compare(config.fixed_frame) != 0)
00332 {
00333 fixed_frame = config.fixed_frame;
00334 laser_notifier_.setTargetFrame(fixed_frame);
00335 people_notifier_.setTargetFrame(fixed_frame);
00336 }
00337
00338 kal_p = config.kalman_p;
00339 kal_q = config.kalman_q;
00340 kal_r = config.kalman_r;
00341 use_filter = config.kalman_on == 1;
00342 }
00343
00344 double distance( list<SavedFeature*>::iterator it1, list<SavedFeature*>::iterator it2){
00345 Stamped<Point> one = (*it1)->position_, two = (*it2)->position_;
00346 double dx = one[0]-two[0], dy = one[1]-two[1], dz = one[2]-two[2];
00347 return sqrt(dx*dx+dy*dy+dz*dz);
00348 }
00349
00350
00351
00352 void peopleCallback(const people_msgs::PositionMeasurement::ConstPtr& people_meas)
00353 {
00354
00355 if (saved_features_.empty())
00356 return;
00357
00358 Point pt;
00359 pointMsgToTF(people_meas->pos, pt);
00360 Stamped<Point> person_loc(pt, people_meas->header.stamp, people_meas->header.frame_id);
00361 person_loc[2] = 0.0;
00362 Stamped<Point> dest_loc(pt, people_meas->header.stamp, people_meas->header.frame_id);
00363
00364 boost::mutex::scoped_lock lock(saved_mutex_);
00365
00366 list<SavedFeature*>::iterator closest = saved_features_.end();
00367 list<SavedFeature*>::iterator closest1 = saved_features_.end();
00368 list<SavedFeature*>::iterator closest2 = saved_features_.end();
00369 float closest_dist = max_meas_jump_m;
00370 float closest_pair_dist = 2*max_meas_jump_m;
00371
00372 list<SavedFeature*>::iterator begin = saved_features_.begin();
00373 list<SavedFeature*>::iterator end = saved_features_.end();
00374 list<SavedFeature*>::iterator it1, it2;
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 for (it1 = begin; it1 != end; ++it1)
00387 {
00388 try {
00389 tfl_.transformPoint((*it1)->id_, people_meas->header.stamp,
00390 person_loc, fixed_frame, dest_loc);
00391
00392 } catch(...) {
00393 ROS_WARN("TF exception spot 7.");
00394 }
00395 (*it1)->dist_to_person_ = dest_loc.length();
00396 }
00397
00398
00399 cout << "Looking for two legs" << endl;
00400 it2 = end;
00401 for (it1 = begin; it1 != end; ++it1)
00402 {
00403
00404 if ((*it1)->object_id == people_meas->object_id)
00405 {
00406
00407 if ((*it1)->dist_to_person_ < max_meas_jump_m)
00408 {
00409
00410 if (it2 == end)
00411 it2 = it1;
00412 else
00413 break;
00414 }
00415
00416 else{
00417
00418 (*it1)->object_id = "";
00419 }
00420 }
00421 }
00422
00423 if (it1 != end && it2 != end)
00424 {
00425 cout << "Found matching pair. The second distance was " << (*it1)->dist_to_person_ << endl;
00426 return;
00427 }
00428
00429
00430
00431
00432
00433
00434
00435 cout << "Looking for one leg plus one new leg" << endl;
00436 float dist_between_legs, closest_dist_between_legs;
00437 if (it2 != end)
00438 {
00439 closest_dist = max_meas_jump_m;
00440 closest = saved_features_.end();
00441
00442 for (it1 = begin; it1 != end; ++it1)
00443 {
00444
00445
00446
00447
00448
00449 if ((it1 == it2) || ((*it1)->object_id != "") || ((*it1)->getLifetime() > max_second_leg_age_s) || ((*it1)->dist_to_person_ >= closest_dist) )
00450 continue;
00451
00452
00453 try {
00454 tfl_.transformPoint((*it1)->id_, (*it2)->position_.stamp_, (*it2)->position_, fixed_frame, dest_loc);
00455 } catch(...) {
00456 ROS_WARN("TF exception getting distance between legs.");
00457 }
00458 dist_between_legs = dest_loc.length();
00459
00460
00461 if ( dist_between_legs < leg_pair_separation_m )
00462 {
00463 closest = it1;
00464 closest_dist = (*it1)->dist_to_person_;
00465 closest_dist_between_legs = dist_between_legs;
00466 }
00467 }
00468
00469 if (closest != end)
00470 {
00471 cout << "Replaced one leg with a distance of " << closest_dist << " and a distance between the legs of " << closest_dist_between_legs << endl;
00472 (*closest)->object_id = people_meas->object_id;
00473 }
00474 else
00475 {
00476 cout << "Returned one matched leg only" << endl;
00477 }
00478
00479
00480 return;
00481 }
00482
00483 cout << "Looking for a pair of new legs" << endl;
00484
00485 it1 = saved_features_.begin();
00486 it2 = saved_features_.begin();
00487 closest = saved_features_.end();
00488 closest1 = saved_features_.end();
00489 closest2 = saved_features_.end();
00490 closest_dist = max_meas_jump_m;
00491 closest_pair_dist = 2*max_meas_jump_m;
00492 for (; it1 != end; ++it1)
00493 {
00494
00495 if ((*it1)->object_id != "" || (*it1)->dist_to_person_ >= max_meas_jump_m )
00496 continue;
00497
00498
00499 if ( (*it1)->dist_to_person_ < closest_dist )
00500 {
00501 closest_dist = (*it1)->dist_to_person_;
00502 closest = it1;
00503 }
00504
00505
00506 it2 = it1;
00507 it2++;
00508 for (; it2 != end; ++it2)
00509 {
00510
00511 if ((*it2)->object_id != "" || (*it2)->dist_to_person_ >= max_meas_jump_m )
00512 continue;
00513
00514
00515 try {
00516 tfl_.transformPoint((*it1)->id_, (*it2)->position_.stamp_, (*it2)->position_, fixed_frame, dest_loc);
00517 } catch(...) {
00518 ROS_WARN("TF exception getting distance between legs in spot 2.");
00519 }
00520 dist_between_legs = dest_loc.length();
00521
00522
00523 if ( (*it1)->dist_to_person_+(*it2)->dist_to_person_ < closest_pair_dist && dist_between_legs < leg_pair_separation_m )
00524 {
00525 closest_pair_dist = (*it1)->dist_to_person_+(*it2)->dist_to_person_;
00526 closest1 = it1;
00527 closest2 = it2;
00528 closest_dist_between_legs = dist_between_legs;
00529 }
00530 }
00531 }
00532
00533 if (closest1 != end && closest2 != end)
00534 {
00535 (*closest1)->object_id = people_meas->object_id;
00536 (*closest2)->object_id = people_meas->object_id;
00537 cout << "Found a completely new pair with total distance " << closest_pair_dist << " and a distance between the legs of " << closest_dist_between_legs << endl;
00538 return;
00539 }
00540
00541 cout << "Looking for just one leg" << endl;
00542
00543 if (closest != end)
00544 {
00545 (*closest)->object_id = people_meas->object_id;
00546 cout << "Returned one new leg only" << endl;
00547 return;
00548 }
00549
00550 cout << "Nothing matched" << endl;
00551 }
00552
00553 void pairLegs()
00554 {
00555
00556 list<SavedFeature*>::iterator begin = saved_features_.begin();
00557 list<SavedFeature*>::iterator end = saved_features_.end();
00558 list<SavedFeature*>::iterator leg1, leg2, best, it;
00559
00560 for (leg1 = begin; leg1 != end; ++leg1)
00561 {
00562
00563 if ((*leg1)->object_id == "")
00564 continue;
00565
00566 leg2 = end;
00567 best = end;
00568 double closest_dist = leg_pair_separation_m;
00569 for ( it = begin; it != end; ++it)
00570 {
00571 if(it==leg1) continue;
00572
00573 if ( (*it)->object_id == (*leg1)->object_id ) {
00574 leg2 = it;
00575 break;
00576 }
00577
00578 if ((*it)->object_id != "")
00579 continue;
00580
00581 double d = distance(it, leg1);
00582 if (((*it)->getLifetime() <= max_second_leg_age_s)
00583 && (d < closest_dist)){
00584 closest_dist = d;
00585 best = it;
00586 }
00587
00588 }
00589
00590 if(leg2 != end){
00591 double dist_between_legs = distance(leg1, leg2);
00592 if (dist_between_legs > leg_pair_separation_m){
00593 (*leg1)->object_id = "";
00594 (*leg1)->other = NULL;
00595 (*leg2)->object_id = "";
00596 (*leg2)->other = NULL;
00597 }else{
00598 (*leg1)->other = *leg2;
00599 (*leg2)->other = *leg1;
00600 }
00601 }else if(best != end){
00602 (*best)->object_id = (*leg1)->object_id;
00603 (*leg1)->other = *best;
00604 (*best)->other = *leg1;
00605 }
00606 }
00607
00608
00609 for(;;){
00610 list<SavedFeature*>::iterator best1 = end, best2 = end;
00611 double closest_dist = leg_pair_separation_m;
00612
00613 for (leg1 = begin; leg1 != end; ++leg1)
00614 {
00615
00616 if ((*leg1)->object_id != ""
00617 || (*leg1)->getReliability() < leg_reliability_limit_)
00618 continue;
00619
00620 for ( leg2 = begin; leg2 != end; ++leg2)
00621 {
00622 if( ((*leg2)->object_id != "")
00623 || ((*leg2)->getReliability() < leg_reliability_limit_)
00624 || (leg1==leg2) ) continue;
00625 double d = distance(leg1, leg2);
00626 if(d<closest_dist){
00627 best1 = leg1;
00628 best2 = leg2;
00629 }
00630 }
00631 }
00632
00633 if(best1 != end){
00634 char id[100];
00635 snprintf(id,100,"Person%d", next_p_id_++);
00636 (*best1)->object_id = std::string(id);
00637 (*best2)->object_id = std::string(id);
00638 (*best1)->other = *best2;
00639 (*best2)->other = *best1;
00640 }else{
00641 break;
00642 }
00643 }
00644 }
00645
00646 void laserCallback(const sensor_msgs::LaserScan::ConstPtr& scan)
00647 {
00648 ScanProcessor processor(*scan, mask_);
00649
00650 processor.splitConnected(connected_thresh_);
00651 processor.removeLessThan(5);
00652
00653 CvMat* tmp_mat = cvCreateMat(1,feat_count_,CV_32FC1);
00654
00655
00656 ros::Time purge = scan->header.stamp + ros::Duration().fromSec(-no_observation_timeout_s);
00657 list<SavedFeature*>::iterator sf_iter = saved_features_.begin();
00658 while (sf_iter != saved_features_.end())
00659 {
00660 if ((*sf_iter)->meas_time_ < purge)
00661 {
00662 if( (*sf_iter)->other )
00663 (*sf_iter)->other->other = NULL;
00664 delete (*sf_iter);
00665 saved_features_.erase(sf_iter++);
00666 }
00667 else
00668 ++sf_iter;
00669 }
00670
00671
00672
00673 list<SavedFeature*> propagated;
00674 for (list<SavedFeature*>::iterator sf_iter = saved_features_.begin();
00675 sf_iter != saved_features_.end();
00676 sf_iter++)
00677 {
00678 (*sf_iter)->propagate(scan->header.stamp);
00679 propagated.push_back(*sf_iter);
00680 }
00681
00682
00683
00684
00685
00686 multiset<MatchedFeature> matches;
00687 for (list<SampleSet*>::iterator i = processor.getClusters().begin();
00688 i != processor.getClusters().end();
00689 i++)
00690 {
00691 vector<float> f = calcLegFeatures(*i, *scan);
00692
00693 for (int k = 0; k < feat_count_; k++)
00694 tmp_mat->data.fl[k] = (float)(f[k]);
00695
00696 float probability = forest.predict_prob( tmp_mat );
00697 Stamped<Point> loc((*i)->center(), scan->header.stamp, scan->header.frame_id);
00698 try {
00699 tfl_.transformPoint(fixed_frame, loc, loc);
00700 } catch(...) {
00701 ROS_WARN("TF exception spot 3.");
00702 }
00703
00704 list<SavedFeature*>::iterator closest = propagated.end();
00705 float closest_dist = max_track_jump_m;
00706
00707 for (list<SavedFeature*>::iterator pf_iter = propagated.begin();
00708 pf_iter != propagated.end();
00709 pf_iter++)
00710 {
00711
00712 float dist = loc.distance((*pf_iter)->position_);
00713 if ( dist < closest_dist )
00714 {
00715 closest = pf_iter;
00716 closest_dist = dist;
00717 }
00718 }
00719
00720 if (closest == propagated.end())
00721 {
00722 list<SavedFeature*>::iterator new_saved = saved_features_.insert(saved_features_.end(), new SavedFeature(loc, tfl_));
00723 }
00724
00725 else
00726 matches.insert(MatchedFeature(*i,*closest,closest_dist,probability));
00727 }
00728
00729
00730
00731 while (matches.size() > 0)
00732 {
00733 multiset<MatchedFeature>::iterator matched_iter = matches.begin();
00734 bool found = false;
00735 list<SavedFeature*>::iterator pf_iter = propagated.begin();
00736 while (pf_iter != propagated.end())
00737 {
00738
00739 if (matched_iter->closest_ == *pf_iter)
00740 {
00741
00742 Stamped<Point> loc(matched_iter->candidate_->center(), scan->header.stamp, scan->header.frame_id);
00743 try {
00744 tfl_.transformPoint(fixed_frame, loc, loc);
00745 } catch(...) {
00746 ROS_WARN("TF exception spot 4.");
00747 }
00748
00749
00750 matched_iter->closest_->update(loc, matched_iter->probability_);
00751
00752
00753 matches.erase(matched_iter);
00754 propagated.erase(pf_iter++);
00755 found = true;
00756 break;
00757 }
00758
00759 else
00760 {
00761 pf_iter++;
00762 }
00763 }
00764
00765
00766
00767 if (!found)
00768 {
00769 Stamped<Point> loc(matched_iter->candidate_->center(), scan->header.stamp, scan->header.frame_id);
00770 try {
00771 tfl_.transformPoint(fixed_frame, loc, loc);
00772 } catch(...) {
00773 ROS_WARN("TF exception spot 5.");
00774 }
00775
00776 list<SavedFeature*>::iterator closest = propagated.end();
00777 float closest_dist = max_track_jump_m;
00778
00779 for (list<SavedFeature*>::iterator remain_iter = propagated.begin();
00780 remain_iter != propagated.end();
00781 remain_iter++)
00782 {
00783 float dist = loc.distance((*remain_iter)->position_);
00784 if ( dist < closest_dist )
00785 {
00786 closest = remain_iter;
00787 closest_dist = dist;
00788 }
00789 }
00790
00791
00792
00793 if (closest == propagated.end())
00794 list<SavedFeature*>::iterator new_saved = saved_features_.insert(saved_features_.end(), new SavedFeature(loc, tfl_));
00795 else
00796 matches.insert(MatchedFeature(matched_iter->candidate_,*closest,closest_dist, matched_iter->probability_));
00797 matches.erase(matched_iter);
00798 }
00799 }
00800
00801 cvReleaseMat(&tmp_mat); tmp_mat = 0;
00802 if(!use_seeds_)
00803 pairLegs();
00804
00805
00806 int i = 0;
00807 vector<people_msgs::PositionMeasurement> people;
00808 vector<people_msgs::PositionMeasurement> legs;
00809
00810 for (list<SavedFeature*>::iterator sf_iter = saved_features_.begin();
00811 sf_iter != saved_features_.end();
00812 sf_iter++,i++)
00813 {
00814
00815 double reliability = (*sf_iter)->getReliability();
00816
00817 if ((*sf_iter)->getReliability() > leg_reliability_limit_
00818 && publish_legs_){
00819 people_msgs::PositionMeasurement pos;
00820 pos.header.stamp = scan->header.stamp;
00821 pos.header.frame_id = fixed_frame;
00822 pos.name = "leg_detector";
00823 pos.object_id = (*sf_iter)->id_;
00824 pos.pos.x = (*sf_iter)->position_[0];
00825 pos.pos.y = (*sf_iter)->position_[1];
00826 pos.pos.z = (*sf_iter)->position_[2];
00827 pos.reliability = reliability;
00828 pos.covariance[0] = pow(0.3 / reliability,2.0);
00829 pos.covariance[1] = 0.0;
00830 pos.covariance[2] = 0.0;
00831 pos.covariance[3] = 0.0;
00832 pos.covariance[4] = pow(0.3 / reliability,2.0);
00833 pos.covariance[5] = 0.0;
00834 pos.covariance[6] = 0.0;
00835 pos.covariance[7] = 0.0;
00836 pos.covariance[8] = 10000.0;
00837 pos.initialization = 0;
00838 legs.push_back(pos);
00839
00840 }
00841
00842 if (publish_leg_markers_){
00843 visualization_msgs::Marker m;
00844 m.header.stamp = (*sf_iter)->time_;
00845 m.header.frame_id = fixed_frame;
00846 m.ns = "LEGS";
00847 m.id = i;
00848 m.type = m.SPHERE;
00849 m.pose.position.x = (*sf_iter)->position_[0];
00850 m.pose.position.y = (*sf_iter)->position_[1];
00851 m.pose.position.z = (*sf_iter)->position_[2];
00852
00853 m.scale.x = .1;
00854 m.scale.y = .1;
00855 m.scale.z = .1;
00856 m.color.a = 1;
00857 m.lifetime = ros::Duration(0.5);
00858 if((*sf_iter)->object_id != ""){
00859 m.color.r = 1;
00860 }else{
00861 m.color.b = (*sf_iter)->getReliability();
00862 }
00863
00864 markers_pub_.publish(m);
00865 }
00866
00867 if (publish_people_ || publish_people_markers_){
00868 SavedFeature* other = (*sf_iter)->other;
00869 if(other!=NULL && other<(*sf_iter)){
00870 double dx = ((*sf_iter)->position_[0] + other->position_[0])/2,
00871 dy = ((*sf_iter)->position_[1] + other->position_[1])/2,
00872 dz = ((*sf_iter)->position_[2] + other->position_[2])/2;
00873
00874 if (publish_people_){
00875 reliability = reliability * other->reliability;
00876 people_msgs::PositionMeasurement pos;
00877 pos.header.stamp = (*sf_iter)->time_;
00878 pos.header.frame_id = fixed_frame;
00879 pos.name = (*sf_iter)->object_id;;
00880 pos.object_id = (*sf_iter)->id_ + "|" + other->id_;
00881 pos.pos.x = dx;
00882 pos.pos.y = dy;
00883 pos.pos.z = dz;
00884 pos.reliability = reliability;
00885 pos.covariance[0] = pow(0.3 / reliability,2.0);
00886 pos.covariance[1] = 0.0;
00887 pos.covariance[2] = 0.0;
00888 pos.covariance[3] = 0.0;
00889 pos.covariance[4] = pow(0.3 / reliability,2.0);
00890 pos.covariance[5] = 0.0;
00891 pos.covariance[6] = 0.0;
00892 pos.covariance[7] = 0.0;
00893 pos.covariance[8] = 10000.0;
00894 pos.initialization = 0;
00895 people.push_back(pos);
00896 }
00897
00898 if (publish_people_markers_){
00899 visualization_msgs::Marker m;
00900 m.header.stamp = (*sf_iter)->time_;
00901 m.header.frame_id = fixed_frame;
00902 m.ns = "PEOPLE";
00903 m.id = i;
00904 m.type = m.SPHERE;
00905 m.pose.position.x = dx;
00906 m.pose.position.y = dy;
00907 m.pose.position.z = dz;
00908 m.scale.x = .2;
00909 m.scale.y = .2;
00910 m.scale.z = .2;
00911 m.color.a = 1;
00912 m.color.g = 1;
00913 m.lifetime = ros::Duration(0.5);
00914
00915 markers_pub_.publish(m);
00916 }
00917 }
00918 }
00919 }
00920
00921 people_msgs::PositionMeasurementArray array;
00922 array.header.stamp = ros::Time::now();
00923 if(publish_legs_){
00924 array.people = legs;
00925 leg_measurements_pub_.publish(array);
00926 }
00927 if(publish_people_){
00928 array.people = people;
00929 people_measurements_pub_.publish(array);
00930 }
00931 }
00932 };
00933
00934 int main(int argc, char **argv)
00935 {
00936 ros::init(argc, argv,"leg_detector");
00937 g_argc = argc;
00938 g_argv = argv;
00939 ros::NodeHandle nh;
00940 LegDetector ld(nh);
00941 ros::spin();
00942
00943 return 0;
00944 }
00945