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
00035
00036
00037
00038 #include "srs_people_tracking_filter/people_tracking_node.h"
00039 #include "srs_people_tracking_filter/tracker_particle.h"
00040 #include "srs_people_tracking_filter/tracker_kalman.h"
00041 #include "srs_people_tracking_filter/state_pos_vel.h"
00042 #include "srs_people_tracking_filter/rgb.h"
00043 #include <srs_msgs/PositionMeasurement.h>
00044
00045
00046 using namespace std;
00047 using namespace tf;
00048 using namespace BFL;
00049 using namespace message_filters;
00050
00051 static const double sequencer_delay = 0.8;
00052 static const unsigned int sequencer_internal_buffer = 100;
00053 static const unsigned int sequencer_subscribe_buffer = 10;
00054 static const unsigned int num_particles_tracker = 1000;
00055 static const double tracker_init_dist = 4.0;
00056
00057 namespace estimation
00058 {
00059
00060 PeopleTrackingNode::PeopleTrackingNode(ros::NodeHandle nh)
00061 : nh_(nh),
00062 robot_state_(),
00063 tracker_counter_(0)
00064 {
00065
00066 meas_cloud_.points = vector<geometry_msgs::Point32>(1);
00067 meas_cloud_.points[0].x = 0;
00068 meas_cloud_.points[0].y = 0;
00069 meas_cloud_.points[0].z = 0;
00070
00071
00072 ros::NodeHandle local_nh("~");
00073 local_nh.param("fixed_frame", fixed_frame_, string("default"));
00074 local_nh.param("freq", freq_, 1.0);
00075 local_nh.param("start_distance_min", start_distance_min_, 0.0);
00076 local_nh.param("reliability_threshold", reliability_threshold_, 1.0);
00077 local_nh.param("sys_sigma_pos_x", sys_sigma_.pos_[0], 0.0);
00078 local_nh.param("sys_sigma_pos_y", sys_sigma_.pos_[1], 0.0);
00079 local_nh.param("sys_sigma_pos_z", sys_sigma_.pos_[2], 0.0);
00080 local_nh.param("sys_sigma_vel_x", sys_sigma_.vel_[0], 0.0);
00081 local_nh.param("sys_sigma_vel_y", sys_sigma_.vel_[1], 0.0);
00082 local_nh.param("sys_sigma_vel_z", sys_sigma_.vel_[2], 0.0);
00083 local_nh.param("follow_one_person", follow_one_person_, false);
00084
00085
00086 people_filter_pub_ = nh_.advertise<srs_msgs::PositionMeasurement>("people_tracker_filter",10);
00087
00088
00089 people_filter_vis_pub_ = nh_.advertise<sensor_msgs::PointCloud>("people_tracker_filter_visualization",10);
00090 people_tracker_vis_pub_ = nh_.advertise<sensor_msgs::PointCloud>("people_tracker_measurements_visualization",10);
00091
00092
00093 people_meas_sub_ = nh_.subscribe("people_tracker_measurements", 1, &PeopleTrackingNode::callbackRcv, this);
00094
00095 }
00096
00097
00098
00099 PeopleTrackingNode::~PeopleTrackingNode()
00100 {
00101
00102 delete message_sequencer_;
00103
00104
00105 for (list<Tracker*>::iterator it= trackers_.begin(); it!=trackers_.end(); it++)
00106 delete *it;
00107 };
00108
00109
00110
00111
00112
00113 void PeopleTrackingNode::callbackRcv(const srs_msgs::PositionMeasurement::ConstPtr& message)
00114 {
00115 ROS_DEBUG("Tracking node got a people position measurement (%f,%f,%f)",
00116 message->pos.x, message->pos.y, message->pos.z);
00117
00118 Stamped<tf::Vector3> meas_rel, meas;
00119 meas_rel.setData(
00120 tf::Vector3(message->pos.x, message->pos.y, message->pos.z));
00121 meas_rel.stamp_ = message->header.stamp;
00122 meas_rel.frame_id_ = message->header.frame_id;
00123 robot_state_.transformPoint(fixed_frame_, meas_rel, meas);
00124
00125
00126 SymmetricMatrix cov(3);
00127 for (unsigned int i = 0; i < 3; i++)
00128 for (unsigned int j = 0; j < 3; j++)
00129 cov(i + 1, j + 1) = message->covariance[3 * i + j];
00130
00131
00132 boost::mutex::scoped_lock lock(filter_mutex_);
00133
00134
00135 for (list<Tracker*>::iterator it = trackers_.begin(); it != trackers_.end(); it++)
00136 if ((*it)->getName() == message->object_id) {
00137 (*it)->updatePrediction(message->header.stamp.toSec());
00138 (*it)->updateCorrection(meas, cov);
00139 }
00140
00141 if (message->object_id == "" && message->reliability > reliability_threshold_) {
00142 double closest_tracker_dist = start_distance_min_;
00143 StatePosVel est;
00144 for (list<Tracker*>::iterator it = trackers_.begin(); it != trackers_.end(); it++) {
00145 (*it)->getEstimate(est);
00146 double dst = sqrt(pow(est.pos_[0] - meas[0], 2) + pow(est.pos_[1] - meas[1], 2));
00147 if (dst < closest_tracker_dist)
00148 closest_tracker_dist = dst;
00149 }
00150
00151 if (follow_one_person_)
00152 cout << "Following one person" << endl;
00153 if (message->initialization == 1 && ((!follow_one_person_ && (closest_tracker_dist >= start_distance_min_)) || (follow_one_person_ && trackers_.empty()))) {
00154
00155
00156 ROS_INFO("Passed crazy conditional.");
00157 tf::Point pt;
00158 tf::pointMsgToTF(message->pos, pt);
00159 tf::Stamped<tf::Point> loc(pt, message->header.stamp, message->header.frame_id);
00160 robot_state_.transformPoint("base_link", loc, loc);
00161 float cur_dist;
00162 if ((cur_dist = pow(loc[0], 2.0) + pow(loc[1], 2.0)) < tracker_init_dist) {
00163
00164 cout << "starting new tracker" << endl;
00165 stringstream tracker_name;
00166 StatePosVel prior_sigma(tf::Vector3(sqrt(cov(1, 1)), sqrt(cov(
00167 2, 2)), sqrt(cov(3, 3))), tf::Vector3(0.0000001, 0.0000001, 0.0000001));
00168 tracker_name << "person " << tracker_counter_++;
00169 Tracker* new_tracker = new TrackerKalman(tracker_name.str(),
00170 sys_sigma_);
00171
00172 new_tracker->initialize(meas, prior_sigma,
00173 message->header.stamp.toSec());
00174 trackers_.push_back(new_tracker);
00175 ROS_INFO("Initialized new tracker %s", tracker_name.str().c_str());
00176 }
00177 else
00178 ROS_INFO("Found a person, but he/she is not close enough to start following. Person is %f away, and must be less than %f away.", cur_dist , tracker_init_dist);
00179 }
00180 else
00181 ROS_INFO("Failed crazy conditional.");
00182 }
00183 lock.unlock();
00184
00185
00186
00187
00188 meas_cloud_.points[0].x = meas[0];
00189 meas_cloud_.points[0].y = meas[1];
00190 meas_cloud_.points[0].z = meas[2];
00191 meas_cloud_.header.frame_id = meas.frame_id_;
00192 people_tracker_vis_pub_.publish(meas_cloud_);
00193 }
00194
00195
00196
00197
00198 void PeopleTrackingNode::callbackDrop(const srs_msgs::PositionMeasurement::ConstPtr& message)
00199 {
00200 ROS_INFO("DROPPED PACKAGE for %s from %s with delay %f !!!!!!!!!!!",
00201 message->object_id.c_str(), message->name.c_str(), (ros::Time::now() - message->header.stamp).toSec());
00202
00203 }
00204
00205
00206
00207
00208
00209 void PeopleTrackingNode::spin()
00210 {
00211 ROS_INFO("People tracking manager started.");
00212
00213 while (ros::ok()){
00214
00215 boost::mutex::scoped_lock lock(filter_mutex_);
00216
00217
00218 vector<geometry_msgs::Point32> filter_visualize(trackers_.size());
00219 vector<float> weights(trackers_.size());
00220 sensor_msgs::ChannelFloat32 channel;
00221
00222
00223 unsigned int i=0;
00224 list<Tracker*>::iterator it= trackers_.begin();
00225 while (it!=trackers_.end()){
00226
00227 (*it)->updatePrediction(ros::Time::now().toSec() - sequencer_delay);
00228
00229
00230 srs_msgs::PositionMeasurement est_pos;
00231 (*it)->getEstimate(est_pos);
00232 est_pos.header.frame_id = fixed_frame_;
00233
00234 ROS_DEBUG("Publishing people tracker filter.");
00235 people_filter_pub_.publish(est_pos);
00236
00237
00238 filter_visualize[i].x = est_pos.pos.x;
00239 filter_visualize[i].y = est_pos.pos.y;
00240 filter_visualize[i].z = est_pos.pos.z;
00241 weights[i] = *(float*)&(rgb[min(998, 999-max(1, (int)trunc( (*it)->getQuality()*999.0 )))]);
00242
00243
00244 ROS_INFO("Quality of tracker %s = %f",(*it)->getName().c_str(), (*it)->getQuality());
00245 if ((*it)->getQuality() <= 0){
00246 ROS_INFO("Removing tracker %s",(*it)->getName().c_str());
00247 delete *it;
00248 trackers_.erase(it++);
00249 }
00250 else it++;
00251 i++;
00252 }
00253 lock.unlock();
00254
00255
00256
00257
00258 channel.name = "rgb";
00259 channel.values = weights;
00260 sensor_msgs::PointCloud people_cloud;
00261 people_cloud.channels.push_back(channel);
00262 people_cloud.header.frame_id = fixed_frame_;
00263 people_cloud.points = filter_visualize;
00264 people_filter_vis_pub_.publish(people_cloud);
00265
00266
00267 usleep(1e6/freq_);
00268
00269 ros::spinOnce();
00270 }
00271 };
00272
00273
00274 };
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 using namespace estimation;
00285 int main(int argc, char **argv)
00286 {
00287
00288 ros::init(argc, argv,"people_tracker");
00289 ros::NodeHandle(nh);
00290
00291
00292 PeopleTrackingNode my_tracking_node(nh);
00293
00294
00295 my_tracking_node.spin();
00296
00297
00298
00299 return 0;
00300 }