people_tracking_node.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2008, Willow Garage, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34 
35 /* Author: Wim Meeussen */
36 
42 #include <people_msgs/PositionMeasurement.h>
43 
44 
45 using namespace std;
46 using namespace tf;
47 using namespace BFL;
48 using namespace message_filters;
49 
50 static const double sequencer_delay = 0.8; //TODO: this is probably too big, it was 0.8
51 static const unsigned int sequencer_internal_buffer = 100;
52 static const unsigned int sequencer_subscribe_buffer = 10;
53 static const unsigned int num_particles_tracker = 1000;
54 static const double tracker_init_dist = 4.0;
55 
56 namespace estimation
57 {
58 // constructor
59 PeopleTrackingNode::PeopleTrackingNode(ros::NodeHandle nh)
60  : nh_(nh),
61  robot_state_(),
62  tracker_counter_(0)
63 {
64  // initialize
65  meas_cloud_.points = vector<geometry_msgs::Point32>(1);
66  meas_cloud_.points[0].x = 0;
67  meas_cloud_.points[0].y = 0;
68  meas_cloud_.points[0].z = 0;
69 
70  // get parameters
71  ros::NodeHandle local_nh("~");
72  local_nh.param("fixed_frame", fixed_frame_, string("default"));
73  local_nh.param("freq", freq_, 1.0);
74  local_nh.param("start_distance_min", start_distance_min_, 0.0);
75  local_nh.param("reliability_threshold", reliability_threshold_, 1.0);
76  local_nh.param("sys_sigma_pos_x", sys_sigma_.pos_[0], 0.0);
77  local_nh.param("sys_sigma_pos_y", sys_sigma_.pos_[1], 0.0);
78  local_nh.param("sys_sigma_pos_z", sys_sigma_.pos_[2], 0.0);
79  local_nh.param("sys_sigma_vel_x", sys_sigma_.vel_[0], 0.0);
80  local_nh.param("sys_sigma_vel_y", sys_sigma_.vel_[1], 0.0);
81  local_nh.param("sys_sigma_vel_z", sys_sigma_.vel_[2], 0.0);
82  local_nh.param("follow_one_person", follow_one_person_, false);
83 
84  // advertise filter output
85  people_filter_pub_ = nh_.advertise<people_msgs::PositionMeasurement>("people_tracker_filter", 10);
86 
87  // advertise visualization
88  people_filter_vis_pub_ = nh_.advertise<sensor_msgs::PointCloud>("people_tracker_filter_visualization", 10);
89  people_tracker_vis_pub_ = nh_.advertise<sensor_msgs::PointCloud>("people_tracker_measurements_visualization", 10);
90 
91  // register message sequencer
92  people_meas_sub_ = nh_.subscribe("people_tracker_measurements", 1, &PeopleTrackingNode::callbackRcv, this);
93 
94 }
95 
96 
97 // destructor
99 {
100  // delete sequencer
101  delete message_sequencer_;
102 
103  // delete all trackers
104  for (list<Tracker*>::iterator it = trackers_.begin(); it != trackers_.end(); it++)
105  delete *it;
106 };
107 
108 
109 
110 
111 // callback for messages
112 void PeopleTrackingNode::callbackRcv(const people_msgs::PositionMeasurement::ConstPtr& message)
113 {
114  ROS_DEBUG("Tracking node got a people position measurement (%f,%f,%f)",
115  message->pos.x, message->pos.y, message->pos.z);
116  // get measurement in fixed frame
117  Stamped<tf::Vector3> meas_rel, meas;
118  meas_rel.setData(
119  tf::Vector3(message->pos.x, message->pos.y, message->pos.z));
120  meas_rel.stamp_ = message->header.stamp;
121  meas_rel.frame_id_ = message->header.frame_id;
122  robot_state_.transformPoint(fixed_frame_, meas_rel, meas);
123 
124  // get measurement covariance
125  SymmetricMatrix cov(3);
126  for (unsigned int i = 0; i < 3; i++)
127  for (unsigned int j = 0; j < 3; j++)
128  cov(i + 1, j + 1) = message->covariance[3 * i + j];
129 
130  // ----- LOCKED ------
131  boost::mutex::scoped_lock lock(filter_mutex_);
132 
133  // update tracker if matching tracker found
134  for (list<Tracker*>::iterator it = trackers_.begin(); it != trackers_.end(); it++)
135  if ((*it)->getName() == message->object_id)
136  {
137  (*it)->updatePrediction(message->header.stamp.toSec());
138  (*it)->updateCorrection(meas, cov);
139  }
140  // check if reliable message with no name should be a new tracker
141  if (message->object_id == "" && message->reliability > reliability_threshold_)
142  {
143  double closest_tracker_dist = start_distance_min_;
144  StatePosVel est;
145  for (list<Tracker*>::iterator it = trackers_.begin(); it != trackers_.end(); it++)
146  {
147  (*it)->getEstimate(est);
148  double dst = sqrt(pow(est.pos_[0] - meas[0], 2) + pow(est.pos_[1] - meas[1], 2));
149  if (dst < closest_tracker_dist)
150  closest_tracker_dist = dst;
151  }
152  // initialize a new tracker
153  if (follow_one_person_)
154  cout << "Following one person" << endl;
155  if (message->initialization == 1 && ((!follow_one_person_ && (closest_tracker_dist >= start_distance_min_)) || (follow_one_person_ && trackers_.empty())))
156  {
157  //if (closest_tracker_dist >= start_distance_min_ || message->initialization == 1){
158  //if (message->initialization == 1 && trackers_.empty()){
159  ROS_INFO("Passed crazy conditional.");
160  tf::Point pt;
161  tf::pointMsgToTF(message->pos, pt);
162  tf::Stamped<tf::Point> loc(pt, message->header.stamp, message->header.frame_id);
163  robot_state_.transformPoint("base_link", loc, loc);
164  float cur_dist;
165  if ((cur_dist = pow(loc[0], 2.0) + pow(loc[1], 2.0)) < tracker_init_dist)
166  {
167 
168  cout << "starting new tracker" << endl;
169  stringstream tracker_name;
170  StatePosVel prior_sigma(tf::Vector3(sqrt(cov(1, 1)), sqrt(cov(
171  2, 2)), sqrt(cov(3, 3))), tf::Vector3(0.0000001, 0.0000001, 0.0000001));
172  tracker_name << "person " << tracker_counter_++;
173  Tracker* new_tracker = new TrackerKalman(tracker_name.str(),
174  sys_sigma_);
175  //Tracker* new_tracker = new TrackerParticle(tracker_name.str(), num_particles_tracker, sys_sigma_);
176  new_tracker->initialize(meas, prior_sigma,
177  message->header.stamp.toSec());
178  trackers_.push_back(new_tracker);
179  ROS_INFO("Initialized new tracker %s", tracker_name.str().c_str());
180  }
181  else
182  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);
183  }
184  else
185  ROS_INFO("Failed crazy conditional.");
186  }
187  lock.unlock();
188  // ------ LOCKED ------
189 
190 
191  // visualize measurement
192  meas_cloud_.points[0].x = meas[0];
193  meas_cloud_.points[0].y = meas[1];
194  meas_cloud_.points[0].z = meas[2];
195  meas_cloud_.header.frame_id = meas.frame_id_;
197 }
198 
199 
200 
201 // callback for dropped messages
202 void PeopleTrackingNode::callbackDrop(const people_msgs::PositionMeasurement::ConstPtr& message)
203 {
204  ROS_INFO("DROPPED PACKAGE for %s from %s with delay %f !!!!!!!!!!!",
205  message->object_id.c_str(), message->name.c_str(), (ros::Time::now() - message->header.stamp).toSec());
206 
207 }
208 
209 
210 
211 
212 // filter loop
214 {
215  ROS_INFO("People tracking manager started.");
216 
217  while (ros::ok())
218  {
219  // ------ LOCKED ------
220  boost::mutex::scoped_lock lock(filter_mutex_);
221 
222  // visualization variables
223  vector<geometry_msgs::Point32> filter_visualize(trackers_.size());
224  vector<float> weights(trackers_.size());
225  sensor_msgs::ChannelFloat32 channel;
226 
227  // loop over trackers
228  unsigned int i = 0;
229  list<Tracker*>::iterator it = trackers_.begin();
230  while (it != trackers_.end())
231  {
232  // update prediction up to delayed time
233  (*it)->updatePrediction(ros::Time::now().toSec() - sequencer_delay);
234 
235  // publish filter result
236  people_msgs::PositionMeasurement est_pos;
237  (*it)->getEstimate(est_pos);
238  est_pos.header.frame_id = fixed_frame_;
239 
240  ROS_DEBUG("Publishing people tracker filter.");
241  people_filter_pub_.publish(est_pos);
242 
243  // visualize filter result
244  filter_visualize[i].x = est_pos.pos.x;
245  filter_visualize[i].y = est_pos.pos.y;
246  filter_visualize[i].z = est_pos.pos.z;
247  weights[i] = *(float*) & (rgb[min(998, 999 - max(1, (int)trunc((*it)->getQuality() * 999.0)))]);
248 
249  // remove trackers that have zero quality
250  ROS_INFO("Quality of tracker %s = %f", (*it)->getName().c_str(), (*it)->getQuality());
251  if ((*it)->getQuality() <= 0)
252  {
253  ROS_INFO("Removing tracker %s", (*it)->getName().c_str());
254  delete *it;
255  trackers_.erase(it++);
256  }
257  else it++;
258  i++;
259  }
260  lock.unlock();
261  // ------ LOCKED ------
262 
263 
264  // visualize all trackers
265  channel.name = "rgb";
266  channel.values = weights;
267  sensor_msgs::PointCloud people_cloud;
268  people_cloud.channels.push_back(channel);
269  people_cloud.header.frame_id = fixed_frame_;
270  people_cloud.points = filter_visualize;
271  people_filter_vis_pub_.publish(people_cloud);
272 
273  // sleep
274  usleep(1e6 / freq_);
275 
276  ros::spinOnce();
277  }
278 };
279 
280 
281 }; // namespace
282 
283 
284 
285 
286 
287 
288 // ----------
289 // -- MAIN --
290 // ----------
291 using namespace estimation;
292 int main(int argc, char **argv)
293 {
294  // Initialize ROS
295  ros::init(argc, argv, "people_tracker");
296  ros::NodeHandle(nh);
297 
298  // create tracker node
299  PeopleTrackingNode my_tracking_node(nh);
300 
301  // wait for filter to finish
302  my_tracking_node.spin();
303 
304  // Clean up
305 
306  return 0;
307 }
static const unsigned int num_particles_tracker
static void pointMsgToTF(const geometry_msgs::Point &msg_v, Point &bt_v)
void publish(const boost::shared_ptr< M > &message) const
void setData(const T &input)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void callbackDrop(const people_msgs::PositionMeasurement::ConstPtr &message)
callback for dropped messages
sensor_msgs::PointCloud meas_cloud_
Class representing state with pos and vel.
Definition: state_pos_vel.h:46
void transformPoint(const std::string &target_frame, const geometry_msgs::PointStamped &stamped_in, geometry_msgs::PointStamped &stamped_out) const
void callbackRcv(const people_msgs::PositionMeasurement::ConstPtr &message)
callback for messages
static const unsigned int sequencer_subscribe_buffer
std::list< Tracker * > trackers_
trackers
static const double sequencer_delay
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
virtual void initialize(const BFL::StatePosVel &mu, const BFL::StatePosVel &sigma, const double time)=0
initialize tracker
virtual ~PeopleTrackingNode()
destructor
ROSCPP_DECL bool ok()
static const unsigned int sequencer_internal_buffer
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
message_filters::TimeSequencer< people_msgs::PositionMeasurement > * message_sequencer_
message sequencer
ros::Time stamp_
std::string frame_id_
tf::Vector3 vel_
Definition: state_pos_vel.h:49
static const double tracker_init_dist
int min(int a, int b)
static const int rgb[]
Definition: rgb.h:4
static Time now()
tf::Vector3 pos_
Definition: state_pos_vel.h:49
ROSCPP_DECL void spinOnce()
int main(int argc, char **argv)
#define ROS_DEBUG(...)


people_tracking_filter
Author(s): Caroline Pantofaru
autogenerated on Fri Jun 7 2019 22:07:49