pointcloud2_interpreter.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2018, Andreas Gustavsson.
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 * Author: Andreas Gustavsson
35 *********************************************************************/
36 
37 /* ROS */
38 #include <ros/ros.h>
39 #include <tf2_ros/buffer.h>
41 #include <tf2_ros/message_filter.h>
44 #include <sensor_msgs/PointCloud2.h>
45 
46 #ifdef NODELET
48 #endif
49 
50 /* C/C++ */
51 #include <iostream>
52 #include <cmath>
53 #include <pthread.h>
54 
55 // #ifdef PC2ARRAY
56 // #include <omp.h>
57 // #endif
58 
59 /* LOCAL INCLUDES */
62 
63 #ifdef NODELET
64 /* TELL ROS ABOUT THIS NODELET PLUGIN */
65 # ifdef PC2ARRAY
66 PLUGINLIB_EXPORT_CLASS(find_moving_objects::PointCloud2ArrayInterpreterNodelet, nodelet::Nodelet)
67 # else
68 PLUGINLIB_EXPORT_CLASS(find_moving_objects::PointCloud2InterpreterNodelet, nodelet::Nodelet)
69 # endif
70 #endif
71 
72 
73 namespace find_moving_objects
74 {
75 
76 /*
77  * Standard Units of Measure and Coordinate Conventions: http://www.ros.org/reps/rep-0103.html
78  * Coordinate Frames for Mobile Platforms: http://www.ros.org/reps/rep-0105.html
79  */
80 
81 
82 /* CONFIDENCE CALCULATION FOR BANK */
83 double a_factor = -10 / 3;
84 double root_1=0.35, root_2=0.65; // optimized for bank coverage of 0.5s, adapted in hz calculation
85 double width_factor = 0.0;
86 double Bank::calculateConfidence(const MovingObject & mo,
87  const BankArgument & ba,
88  const double dt,
89  const double mo_old_width)
90 {
91  return /*ba.ema_alpha **/ // Using weighting decay decreases the confidence while,
92  (ba.base_confidence // how much we trust the sensor itself,
93  + a_factor * (dt-root_1) * (dt-root_2) // a well-adapted bank size in relation to the sensor rate and environmental context
94  - width_factor * fabs(mo.seen_width - mo_old_width)); // and low difference in width between old and new object,
95  // make us more confident
96 }
97 
98 
99 
100 /* CONSTRUCTOR */
101 #ifdef NODELET
102 # ifdef PC2ARRAY
103 PointCloud2ArrayInterpreterNodelet::PointCloud2ArrayInterpreterNodelet()
104 # else
105 PointCloud2InterpreterNodelet::PointCloud2InterpreterNodelet()
106 # endif
107 #endif
108 #ifdef NODE
109 # ifdef PC2ARRAY
110 PointCloud2ArrayInterpreterNode::PointCloud2ArrayInterpreterNode()
111 # else
112 PointCloud2InterpreterNode::PointCloud2InterpreterNode()
113 # endif
114 #endif
115 : received_messages(0),
117 {
118 #ifdef NODELET
119  // Wait for time to become valid, then start bank
121 #endif
122 
123  tf_filter = NULL;
124  tf_listener = NULL;
125  tf_buffer = NULL;
126 
127 #ifdef NODE
128  onInit();
129 #endif
130 }
131 
132 
133 
134 /* DESTRUCTOR */
135 #ifdef PC2ARRAY
136 # ifdef NODELET
137 PointCloud2ArrayInterpreterNodelet::~PointCloud2ArrayInterpreterNodelet()
138 # endif
139 # ifdef NODE
140 PointCloud2ArrayInterpreterNode::~PointCloud2ArrayInterpreterNode()
141 # endif
142 #else
143 # ifdef NODELET
144 PointCloud2InterpreterNodelet::~PointCloud2InterpreterNodelet()
145 # endif
146 # ifdef NODE
147 PointCloud2InterpreterNode::~PointCloud2InterpreterNode()
148 # endif
149 #endif
150 {
151  int nr_banks = banks.size();
152  for (int i=0; i<nr_banks; ++i)
153  {
154  delete banks[i];
155  }
156  banks.clear();
157 
158  if (tf_filter != NULL) delete tf_filter;
159  if (tf_buffer != NULL) delete tf_buffer;
160 }
161 
162 
163 
164 /* CALLBACK */
165 #ifdef PC2ARRAY
166 # ifdef NODELET
167 void PointCloud2ArrayInterpreterNodelet::pointCloud2ArrayCallback(const find_moving_objects::PointCloud2Array::ConstPtr & msg)
168 # endif
169 # ifdef NODE
170 void PointCloud2ArrayInterpreterNode::pointCloud2ArrayCallback(const find_moving_objects::PointCloud2Array::ConstPtr & msg)
171 # endif
172 #else
173 # ifdef NODELET
174 void PointCloud2InterpreterNodelet::pointCloud2Callback(const sensor_msgs::PointCloud2::ConstPtr & msg)
175 # endif
176 # ifdef NODE
177 void PointCloud2InterpreterNode::pointCloud2Callback(const sensor_msgs::PointCloud2::ConstPtr & msg)
178 # endif
179 #endif
180 {
181  switch (state)
182  {
183  /*
184  * MAIN STATE - WHEN ALL IS INITIALIZED
185  */
186  case FIND_MOVING_OBJECTS:
187  {
188 #ifdef PC2ARRAY
189  // Consider the msgs of msg in parallel
190 // #pragma omp parallel for
191  for (int i=0; i<msg->msgs.size(); ++i)
192  {
193  // Can message be added to bank?
194  if (banks[i]->addMessage(&(msg->msgs[i]), false) != 0)
195  {
196  // Adding message failed, try the next one
197  continue;
198  }
199 
200  // If so, then find and report objects
201  banks[i]->findAndReportMovingObjects();
202  }
203 #else
204  // Can message be added to bank?
205  if (banks[0]->addMessage(&(*msg)) != 0) // De-reference ConstPtr object and take reference of result to get a
206  // pointer to a PointCloud2 object
207  {
208  // Adding message failed
209  break;
210  }
211 
212  // If so, then find and report objects
213  banks[0]->findAndReportMovingObjects();
214 #endif
215  break;
216  }
217 
218 
219  /*
220  * BEFORE MAIN STATE CAN BE SET, THIS CASE MUST HAVE BEEN EXECUTED
221  */
222  case INIT_BANKS:
223  {
224  // Debug frame to see e.g. if we are dealing with an optical frame
225 #ifdef NODELET
226  NODELET_DEBUG_STREAM("PointCloud2Array sensor is using frame: " << msg->header.frame_id);
227 #endif
228 #ifdef NODE
229  ROS_DEBUG_STREAM("PointCloud2Array sensor is using frame: " << msg->header.frame_id);
230 #endif
231 
232 #ifdef PC2ARRAY
233  // Create banks
234  const int nr_msgs = msg->msgs.size();
235  if (banks.size() == 0)
236  {
237  // If reaching this point, then this block has not been executed before
238  // If it has, then it will not be executed again, and the modifications to banks and bank_arguments are hence
239  // maintained valid, assuming that the new message contains the same number of messages in the array
240  bank_arguments.resize(nr_msgs);
241  banks.resize(nr_msgs);
242  for (int i=0; i<nr_msgs; ++i)
243  {
244  // Create bank and start listening to tf data
246 
247  // Copy first bank argument
249  }
250 
251  // Modify bank arguments
252  for (int i=0; i<nr_msgs; ++i)
253  {
254  const std::string append_str = "_" + std::to_string(i);
255  bank_arguments[i].topic_ema.append(append_str);
256  bank_arguments[i].topic_objects_closest_point_markers.append(append_str);
257  bank_arguments[i].topic_objects_velocity_arrows.append(append_str);
258  bank_arguments[i].topic_objects_delta_position_lines.append(append_str);
259  bank_arguments[i].topic_objects_width_lines.append(append_str);
260 
261  bank_arguments[i].velocity_arrow_ns.append(append_str);
262  bank_arguments[i].delta_position_line_ns.append(append_str);
263  bank_arguments[i].width_line_ns.append(append_str);
264 
265  bank_arguments[i].node_name_suffix.append(append_str);
266  }
267  }
268 
269  // Init banks
270  for (int i=0; i<nr_msgs; ++i)
271  {
272  banks[i]->init(bank_arguments[i], &(msg->msgs[i]), false); // addFirstMessage might not succeed, disregard that
273  }
274 #else
275  // Create banks
276  if (banks.size() == 0)
277  {
278  banks.resize(1);
280  }
281 
282  // Init bank
283  if (banks[0]->init(bank_arguments[0], &(*msg)) != 0)
284  {
285  // If init fails we do not change state, but use this one again
286  break;
287  }
288 #endif
289 
290  // Change state
292  break;
293  }
294 
295 
296  /*
297  * CALCULATE HZ OF TOPIC AND UPDATE SIZE OF BANK
298  */
299  case CALCULATE_HZ:
300  {
301  // spin until target is reached
303  const double elapsed_time = ros::Time::now().toSec() - start_time;
304 
305  // Are we done?
306  if (max_time <= elapsed_time ||
308  {
309  // Calculate HZ
310  const double hz = received_messages / elapsed_time;
311 
312  // Set nr of messages in bank
313  const double nr_scans = optimize_nr_scans_in_bank * hz;
314  bank_arguments[0].nr_scans_in_bank = nr_scans - ((long) nr_scans) == 0.0 ? nr_scans + 1 : ceil(nr_scans);
315 
316  // Sanity check
317  if (bank_arguments[0].nr_scans_in_bank < 2)
318  {
319  bank_arguments[0].nr_scans_in_bank = 2;
320  }
321 
322  // Update confidence roots and amplitude factor
323  root_1 = optimize_nr_scans_in_bank * 0.6;
325  a_factor = 4 * max_confidence_for_dt_match / (2*root_1*root_2 - root_1*root_1 - root_2*root_2);
326 
327 #ifdef NODELET
328  NODELET_INFO_STREAM("Topic " << subscribe_topic << " has rate " << hz << "Hz" <<
329  " (based on " << received_messages << " msgs during " << elapsed_time << " seconds)");
330  NODELET_INFO_STREAM("Optimized bank size is " << bank_arguments[0].nr_scans_in_bank);
331 #endif
332 #ifdef NODE
333  ROS_INFO_STREAM("Topic " << subscribe_topic << " has rate " << hz << "Hz" <<
334  " (based on " << received_messages << " msgs during " << elapsed_time << " seconds)");
335  ROS_INFO_STREAM("Optimized bank size is " << bank_arguments[0].nr_scans_in_bank);
336 #endif
337 
338  // Change state since we are done
339  state = INIT_BANKS;
340  }
341  break;
342  }
343 
344 
345  /*
346  * WHEN CALCULATING HZ OF TOPIC, WAIT FOR A MESSAGE TO ARRIVE AND SAVE THE TIME
347  */
349  {
350  // Set start time
352 
353  // Change state
355  break;
356  }
357 
358 
359  /*
360  * THERE ARE NO MORE STATES - TERMINATE, THIS IS AN ERROR
361  */
362  default:
363  {
364  ROS_ERROR("Message callback is in an unknown state");
365  ROS_BREAK();
366  }
367  }
368 }
369 
370 
371 
372 /* ENTRY POINT FOR NODELET AND INIT FOR NODE */
373 #ifdef NODELET
374 # ifdef PC2ARRAY
375 void PointCloud2ArrayInterpreterNodelet::onInit()
376 # else
377 void PointCloud2InterpreterNodelet::onInit()
378 # endif
379 {
380  // Node handles
381  nh = getNodeHandle();
382  nh_priv = getPrivateNodeHandle();
383 #endif
384 #ifdef NODE
385 # ifdef PC2ARRAY
386 void PointCloud2ArrayInterpreterNode::onInit()
387 # else
388 void PointCloud2InterpreterNode::onInit()
389 # endif
390 {
391  // Node handles
392  nh = ros::NodeHandle();
393  nh_priv = ros::NodeHandle("~");
394 #endif
395 
396  // Init bank_argument using parameters
397  BankArgument bank_argument;
400  nh_priv.param("ema_alpha", bank_argument.ema_alpha, default_ema_alpha);
401  nh_priv.param("nr_scans_in_bank", bank_argument.nr_scans_in_bank, default_nr_scans_in_bank);
402  nh_priv.param("nr_points_per_scan_in_bank", bank_argument.points_per_scan, default_nr_points_per_scan_in_bank);
403  nh_priv.param("bank_view_angle", bank_argument.angle_max, default_bank_view_angle);
404  bank_argument.angle_max /= 2.0;
405  bank_argument.angle_min = -bank_argument.angle_max;
406  nh_priv.param("sensor_frame_has_z_axis_forward", bank_argument.sensor_frame_has_z_axis_forward, default_sensor_frame_has_z_axis_forward);
407  nh_priv.param("object_threshold_edge_max_delta_range", bank_argument.object_threshold_edge_max_delta_range, default_object_threshold_edge_max_delta_range);
408  nh_priv.param("object_threshold_min_nr_points", bank_argument.object_threshold_min_nr_points, default_object_threshold_min_nr_points);
409  nh_priv.param("object_threshold_max_distance", bank_argument.object_threshold_max_distance, default_object_threshold_max_distance);
410  nh_priv.param("object_threshold_min_speed", bank_argument.object_threshold_min_speed, default_object_threshold_min_speed);
411  nh_priv.param("object_threshold_max_delta_width_in_points", bank_argument.object_threshold_max_delta_width_in_points, default_object_threshold_max_delta_width_in_points);
412  nh_priv.param("object_threshold_bank_tracking_max_delta_distance", bank_argument.object_threshold_bank_tracking_max_delta_distance, default_object_threshold_bank_tracking_max_delta_distance);
413  nh_priv.param("object_threshold_min_confidence", bank_argument.object_threshold_min_confidence, default_object_threshold_min_confidence);
414  nh_priv.param("base_confidence", bank_argument.base_confidence, default_base_confidence);
415  nh_priv.param("publish_ema", bank_argument.publish_ema, default_publish_ema);
416  nh_priv.param("publish_objects_closest_points_markers", bank_argument.publish_objects_closest_point_markers, default_publish_objects_closest_points_markers);
417  nh_priv.param("publish_objects_velocity_arrows", bank_argument.publish_objects_velocity_arrows, default_publish_objects_velocity_arrows);
418  nh_priv.param("publish_objects_delta_position_lines", bank_argument.publish_objects_delta_position_lines, default_publish_objects_delta_position_lines);
419  nh_priv.param("publish_objects_width_lines", bank_argument.publish_objects_width_lines, default_publish_objects_width_lines);
420  nh_priv.param("velocity_arrows_use_full_gray_scale", bank_argument.velocity_arrows_use_full_gray_scale, default_velocity_arrows_use_full_gray_scale);
421  nh_priv.param("velocity_arrows_use_sensor_frame", bank_argument.velocity_arrows_use_sensor_frame, default_velocity_arrows_use_sensor_frame);
422  nh_priv.param("velocity_arrows_use_base_frame", bank_argument.velocity_arrows_use_base_frame, default_velocity_arrows_use_base_frame);
423  nh_priv.param("velocity_arrows_use_fixed_frame", bank_argument.velocity_arrows_use_fixed_frame, default_velocity_arrows_use_fixed_frame);
424  nh_priv.param("publish_objects", bank_argument.publish_objects, default_publish_objects);
425  nh_priv.param("map_frame", bank_argument.map_frame, default_map_frame);
426  nh_priv.param("fixed_frame", bank_argument.fixed_frame, default_fixed_frame);
427  nh_priv.param("base_frame", bank_argument.base_frame, default_base_frame);
428  nh_priv.param("ns_velocity_arrows", bank_argument.velocity_arrow_ns, default_ns_velocity_arrows);
429  nh_priv.param("ns_delta_position_lines", bank_argument.delta_position_line_ns, default_ns_delta_position_lines);
430  nh_priv.param("ns_width_lines", bank_argument.width_line_ns, default_ns_width_lines);
431  nh_priv.param("topic_ema", bank_argument.topic_ema, default_topic_ema);
432  nh_priv.param("topic_objects_closest_points_markers", bank_argument.topic_objects_closest_point_markers, default_topic_objects_closest_points_markers);
433  nh_priv.param("topic_objects_velocity_arrows", bank_argument.topic_objects_velocity_arrows, default_topic_objects_velocity_arrows);
434  nh_priv.param("topic_objects_delta_position_lines", bank_argument.topic_objects_delta_position_lines, default_topic_objects_delta_position_lines);
435  nh_priv.param("topic_objects_width_lines", bank_argument.topic_objects_width_lines, default_topic_objects_width_lines);
436  nh_priv.param("topic_objects", bank_argument.topic_objects, default_topic_objects);
437  nh_priv.param("publish_buffer_size", bank_argument.publish_buffer_size, default_publish_buffer_size);
438 
439  // PointCloud2-specific
440  nh_priv.param("message_x_coordinate_field_name", bank_argument.PC2_message_x_coordinate_field_name, default_message_x_coordinate_field_name);
441  nh_priv.param("message_y_coordinate_field_name", bank_argument.PC2_message_y_coordinate_field_name, default_message_y_coordinate_field_name);
442  nh_priv.param("message_z_coordinate_field_name", bank_argument.PC2_message_z_coordinate_field_name, default_message_z_coordinate_field_name);
443  nh_priv.param("voxel_leaf_size", bank_argument.PC2_voxel_leaf_size, default_voxel_leaf_size);
444  nh_priv.param("threshold_z_min", bank_argument.PC2_threshold_z_min, default_threshold_z_min);
445  nh_priv.param("threshold_z_max", bank_argument.PC2_threshold_z_max, default_threshold_z_max);
446 
447  // Z threshold sanity check
448  if (bank_argument.PC2_threshold_z_max < bank_argument.PC2_threshold_z_min)
449  {
450  std::string err = "threshold_z_max cannot be smaller than threshold_z_min";
451 #ifdef NODELET
452  NODELET_ERROR("%s", err.c_str());
453 #endif
454 #ifdef NODE
455  ROS_ERROR("%s", err.c_str());
456 #endif
457  ROS_BREAK();
458  }
459 
460  // Add this as the first bank_argument
461  bank_arguments.push_back(bank_argument);
462 
463  // Optimize bank size?
466 
467  // If optimize_nr_scans_in_bank != 0, then yes
468  if (optimize_nr_scans_in_bank != 0.0)
469  {
471  }
472  else
473  {
474  state = INIT_BANKS;
475  }
476 
477  // Delta width confidence factor
478  nh_priv.param("delta_width_confidence_decrease_factor", width_factor, default_delta_width_confidence_decrease_factor);
479 
480  // Set up target frames for message filter
481  tf_filter_target_frames.push_back(bank_argument.map_frame);
482  if (strcmp(bank_argument.map_frame.c_str(), bank_argument.fixed_frame.c_str()) != 0)
483  {
484  tf_filter_target_frames.push_back(bank_argument.fixed_frame);
485  }
486  if (strcmp(bank_argument.map_frame.c_str(), bank_argument.base_frame.c_str()) != 0 &&
487  strcmp(bank_argument.fixed_frame.c_str(), bank_argument.base_frame.c_str()) != 0)
488  {
489  tf_filter_target_frames.push_back(bank_argument.base_frame);
490  }
491 
492  // Create tf2 buffer, listener, subscriber and filter
495 #ifdef PC2ARRAY
499 #else
501  tf_subscriber->subscribe(nh, subscribe_topic, subscribe_buffer_size);
503 #endif
504  tf_filter->setTargetFrames(tf_filter_target_frames);
505 
506  // Register callback in filter
507  tf_filter->registerCallback( boost::bind(
508 #ifdef NODELET
509 # ifdef PC2ARRAY
510  &PointCloud2ArrayInterpreterNodelet::pointCloud2ArrayCallback,
511 # else
513 # endif
514 #endif
515 #ifdef NODE
516 # ifdef PC2ARRAY
517  &PointCloud2ArrayInterpreterNode::pointCloud2ArrayCallback,
518 # else
520 # endif
521 #endif
522  this, _1) );
523 }
524 
525 } // namespace find_moving_objects
526 
527 
528 
529 #ifdef NODE
530 using namespace find_moving_objects;
531 
532 /* ENTRY POINT */
533 int main (int argc, char ** argv)
534 {
535 # ifdef PC2ARRAY
536  // Init ROS
537  ros::init(argc, argv, "pointcloud2array_interpreter", ros::init_options::AnonymousName);
538 
539  // Create and init node object
540  PointCloud2ArrayInterpreterNode pc2_interpreter;
541 # else
542  // Init ROS
543  ros::init(argc, argv, "pointcloud2_interpreter", ros::init_options::AnonymousName);
544 
545  // Create and init node object
546  PointCloud2InterpreterNode pc2_interpreter;
547 # endif
548 
549  // Enter receive loop
550  ros::spin();
551 
552  return 0;
553 }
554 #endif
#define NODELET_INFO_STREAM(...)
const bool default_publish_objects_width_lines
const bool default_publish_objects_closest_points_markers
const std::string default_ns_velocity_arrows
#define NODELET_ERROR(...)
const double default_object_threshold_edge_max_delta_range
const bool default_velocity_arrows_use_fixed_frame
const std::string default_message_z_coordinate_field_name
const bool default_publish_objects_delta_position_lines
const std::string default_message_y_coordinate_field_name
BankArgument bank_argument
Definition: bank.h:360
virtual long init(BankArgument bank_argument, const sensor_msgs::LaserScan *msg)
Definition: bank.cpp:2740
virtual long addMessage(const sensor_msgs::LaserScan *msg)
Definition: bank.cpp:2820
const double default_threshold_z_max
message_filters::Subscriber< sensor_msgs::LaserScan > * tf_subscriber
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
const double default_base_confidence
const double default_bank_view_angle
const std::string default_topic_objects_closest_points_markers
const double default_ema_alpha
const std::string default_subscribe_topic
const std::string default_topic_objects
const int default_subscribe_buffer_size
const bool default_velocity_arrows_use_full_gray_scale
const bool default_velocity_arrows_use_base_frame
ROSCPP_DECL void spin(Spinner &spinner)
const std::string default_topic_objects_width_lines
const double default_object_threshold_min_speed
const std::string default_message_x_coordinate_field_name
const double default_max_confidence_for_dt_match
const std::string default_ns_delta_position_lines
const std::string default_ns_width_lines
const double default_threshold_z_min
const int default_object_threshold_max_delta_width_in_points
const double default_delta_width_confidence_decrease_factor
const std::string default_topic_ema
std::vector< BankArgument > bank_arguments
const double default_optimize_nr_scans_in_bank
bool param(const std::string &param_name, T &param_val, const T &default_val) const
const double default_object_threshold_bank_tracking_max_delta_distance
const double default_object_threshold_min_confidence
const double default_voxel_leaf_size
const std::string default_fixed_frame
const int default_object_threshold_min_nr_points
int main(int argc, char **argv)
const std::string default_topic_objects_delta_position_lines
virtual double calculateConfidence(const find_moving_objects::MovingObject &mo, const find_moving_objects::BankArgument &ba, const double delta_time, const double mo_old_width)
const double default_object_threshold_max_distance
const int default_nr_points_per_scan_in_bank
#define ROS_DEBUG_STREAM(args)
const bool default_publish_objects
#define NODELET_DEBUG_STREAM(...)
tf2_ros::Buffer * tf_buffer
Definition: bank.h:378
tf2_ros::TransformListener * tf_listener
tf2_ros::MessageFilter< sensor_msgs::LaserScan > * tf_filter
const std::string default_base_frame
std::vector< Bank * > banks
const std::string default_map_frame
const bool default_velocity_arrows_use_sensor_frame
const bool default_sensor_frame_has_z_axis_forward
const int default_publish_buffer_size
#define ROS_INFO_STREAM(args)
void pointCloud2Callback(const sensor_msgs::PointCloud2::ConstPtr &msg)
static Time now()
const bool default_publish_objects_velocity_arrows
static bool waitForValid()
#define ROS_BREAK()
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
#define ROS_ERROR(...)
std::vector< std::string > tf_filter_target_frames
const std::string default_topic_objects_velocity_arrows


find_moving_objects
Author(s): Andreas Gustavsson
autogenerated on Mon Jun 10 2019 13:13:19