point_cloud_aggregator.cpp
Go to the documentation of this file.
1 
2 #include <ros/ros.h>
4 #include <nodelet/nodelet.h>
5 
6 #include <pcl/point_cloud.h>
7 #include <pcl/point_types.h>
9 
10 #include <pcl_ros/transforms.h>
11 
12 #include <tf/transform_listener.h>
13 
14 #include <sensor_msgs/PointCloud2.h>
15 
18 
22 
25 
26 namespace rtabmap_ros
27 {
28 
30 {
31 public:
33  warningThread_(0),
35  exactSync4_(0),
36  approxSync4_(0),
37  exactSync3_(0),
38  approxSync3_(0),
39  exactSync2_(0),
40  approxSync2_(0)
41  {}
42 
44  {
45  if (exactSync4_!=0) delete exactSync4_;
46  if (approxSync4_!=0) delete approxSync4_;
47  if (exactSync3_!=0) delete exactSync3_;
48  if (approxSync3_!=0) delete approxSync3_;
49  if (exactSync2_!=0) delete exactSync2_;
50  if (approxSync2_!=0) delete approxSync2_;
51 
52  if(warningThread_)
53  {
54  callbackCalled_=true;
55  warningThread_->join();
56  delete warningThread_;
57  }
58  }
59 
60 private:
61  virtual void onInit()
62  {
65 
66  int queueSize = 5;
67  int count = 2;
68  bool approx=true;
69  pnh.param("queue_size", queueSize, queueSize);
70  pnh.param("frame_id", frameId_, frameId_);
71  pnh.param("approx_sync", approx, approx);
72  pnh.param("count", count, count);
73 
74  cloudSub_1_.subscribe(nh, "cloud1", 1);
75  cloudSub_2_.subscribe(nh, "cloud2", 1);
76 
77  std::string subscribedTopicsMsg;
78  if(count == 4)
79  {
80  cloudSub_3_.subscribe(nh, "cloud3", 1);
81  cloudSub_4_.subscribe(nh, "cloud4", 1);
82  if(approx)
83  {
85  approxSync4_->registerCallback(boost::bind(&rtabmap_ros::PointCloudAggregator::clouds4_callback, this, _1, _2, _3, _4));
86  }
87  else
88  {
90  exactSync4_->registerCallback(boost::bind(&rtabmap_ros::PointCloudAggregator::clouds4_callback, this, _1, _2, _3, _4));
91  }
92  subscribedTopicsMsg = uFormat("\n%s subscribed to (%s sync):\n %s,\n %s,\n %s,\n %s",
93  getName().c_str(),
94  approx?"approx":"exact",
95  cloudSub_1_.getTopic().c_str(),
96  cloudSub_2_.getTopic().c_str(),
97  cloudSub_3_.getTopic().c_str(),
98  cloudSub_4_.getTopic().c_str());
99  }
100  else if(count == 3)
101  {
102  cloudSub_3_.subscribe(nh, "cloud3", 1);
103  if(approx)
104  {
106  approxSync3_->registerCallback(boost::bind(&rtabmap_ros::PointCloudAggregator::clouds3_callback, this, _1, _2, _3));
107  }
108  else
109  {
111  exactSync3_->registerCallback(boost::bind(&rtabmap_ros::PointCloudAggregator::clouds3_callback, this, _1, _2, _3));
112  }
113  subscribedTopicsMsg = uFormat("\n%s subscribed to (%s sync):\n %s,\n %s,\n %s",
114  getName().c_str(),
115  approx?"approx":"exact",
116  cloudSub_1_.getTopic().c_str(),
117  cloudSub_2_.getTopic().c_str(),
118  cloudSub_3_.getTopic().c_str());
119  }
120  else
121  {
122  if(approx)
123  {
125  approxSync2_->registerCallback(boost::bind(&rtabmap_ros::PointCloudAggregator::clouds2_callback, this, _1, _2));
126  }
127  else
128  {
130  exactSync2_->registerCallback(boost::bind(&rtabmap_ros::PointCloudAggregator::clouds2_callback, this, _1, _2));
131  }
132  subscribedTopicsMsg = uFormat("\n%s subscribed to (%s sync):\n %s,\n %s",
133  getName().c_str(),
134  approx?"approx":"exact",
135  cloudSub_1_.getTopic().c_str(),
136  cloudSub_2_.getTopic().c_str());
137  }
138 
139  cloudPub_ = nh.advertise<sensor_msgs::PointCloud2>("combined_cloud", 1);
140 
141  warningThread_ = new boost::thread(boost::bind(&PointCloudAggregator::warningLoop, this, subscribedTopicsMsg, approx));
142  NODELET_INFO("%s", subscribedTopicsMsg.c_str());
143  }
144 
145  void clouds4_callback(const sensor_msgs::PointCloud2ConstPtr & cloudMsg_1,
146  const sensor_msgs::PointCloud2ConstPtr & cloudMsg_2,
147  const sensor_msgs::PointCloud2ConstPtr & cloudMsg_3,
148  const sensor_msgs::PointCloud2ConstPtr & cloudMsg_4)
149  {
150  std::vector<sensor_msgs::PointCloud2ConstPtr> clouds;
151  clouds.push_back(cloudMsg_1);
152  clouds.push_back(cloudMsg_2);
153  clouds.push_back(cloudMsg_3);
154  clouds.push_back(cloudMsg_4);
155 
156  combineClouds(clouds);
157  }
158  void clouds3_callback(const sensor_msgs::PointCloud2ConstPtr & cloudMsg_1,
159  const sensor_msgs::PointCloud2ConstPtr & cloudMsg_2,
160  const sensor_msgs::PointCloud2ConstPtr & cloudMsg_3)
161  {
162  std::vector<sensor_msgs::PointCloud2ConstPtr> clouds;
163  clouds.push_back(cloudMsg_1);
164  clouds.push_back(cloudMsg_2);
165  clouds.push_back(cloudMsg_3);
166 
167  combineClouds(clouds);
168  }
169  void clouds2_callback(const sensor_msgs::PointCloud2ConstPtr & cloudMsg_1,
170  const sensor_msgs::PointCloud2ConstPtr & cloudMsg_2)
171  {
172  std::vector<sensor_msgs::PointCloud2ConstPtr> clouds;
173  clouds.push_back(cloudMsg_1);
174  clouds.push_back(cloudMsg_2);
175 
176  combineClouds(clouds);
177  }
178  void combineClouds(const std::vector<sensor_msgs::PointCloud2ConstPtr> & cloudMsgs)
179  {
180  callbackCalled_ = true;
181  ROS_ASSERT(cloudMsgs.size() > 1);
183  {
184  pcl::PCLPointCloud2 output;
185 
186  std::string frameId = frameId_;
187  if(!frameId.empty() && frameId.compare(cloudMsgs[0]->header.frame_id) != 0)
188  {
189  sensor_msgs::PointCloud2 tmp;
190  pcl_ros::transformPointCloud(frameId, *cloudMsgs[0], tmp, tfListener_);
191  pcl_conversions::toPCL(tmp, output);
192  }
193  else
194  {
195  pcl_conversions::toPCL(*cloudMsgs[0], output);
196  frameId = cloudMsgs[0]->header.frame_id;
197  }
198 
199  for(unsigned int i=1; i<cloudMsgs.size(); ++i)
200  {
201  pcl::PCLPointCloud2 cloud2;
202  if(frameId.compare(cloudMsgs[i]->header.frame_id) != 0)
203  {
204  sensor_msgs::PointCloud2 tmp;
205  pcl_ros::transformPointCloud(frameId, *cloudMsgs[i], tmp, tfListener_);
206  pcl_conversions::toPCL(tmp, cloud2);
207  }
208  else
209  {
210  pcl_conversions::toPCL(*cloudMsgs[i], cloud2);
211  frameId = cloudMsgs[i]->header.frame_id;
212  }
213 
214  pcl::PCLPointCloud2 tmp_output;
215  pcl::concatenatePointCloud(output, cloud2, tmp_output);
216  output = tmp_output;
217  }
218 
219  sensor_msgs::PointCloud2 rosCloud;
220  pcl_conversions::moveFromPCL(output, rosCloud);
221  rosCloud.header.stamp = cloudMsgs[0]->header.stamp;
222  rosCloud.header.frame_id = frameId;
223  cloudPub_.publish(rosCloud);
224  }
225  }
226 
227  void warningLoop(const std::string & subscribedTopicsMsg, bool approxSync)
228  {
229  ros::Duration r(5.0);
230  while(!callbackCalled_)
231  {
232  r.sleep();
233  if(!callbackCalled_)
234  {
235  ROS_WARN("%s: Did not receive data since 5 seconds! Make sure the input topics are "
236  "published (\"$ rostopic hz my_topic\") and the timestamps in their "
237  "header are set. %s%s",
238  getName().c_str(),
239  approxSync?"":"Parameter \"approx_sync\" is false, which means that input "
240  "topics should have all the exact timestamp for the callback to be called.",
241  subscribedTopicsMsg.c_str());
242  }
243  }
244  }
245 
246  boost::thread * warningThread_;
248 
265 
267 
268  std::string frameId_;
270 };
271 
273 }
274 
message_filters::Synchronizer< ExactSync4Policy > * exactSync4_
std::string getTopic() const
message_filters::Subscriber< sensor_msgs::PointCloud2 > cloudSub_2_
std::string uFormat(const char *fmt,...)
void publish(const boost::shared_ptr< M > &message) const
message_filters::Subscriber< sensor_msgs::PointCloud2 > cloudSub_3_
message_filters::sync_policies::ExactTime< sensor_msgs::PointCloud2, sensor_msgs::PointCloud2, sensor_msgs::PointCloud2 > ExactSync3Policy
bool sleep() const
const std::string & getName() const
message_filters::Synchronizer< ExactSync2Policy > * exactSync2_
void clouds3_callback(const sensor_msgs::PointCloud2ConstPtr &cloudMsg_1, const sensor_msgs::PointCloud2ConstPtr &cloudMsg_2, const sensor_msgs::PointCloud2ConstPtr &cloudMsg_3)
#define ROS_WARN(...)
message_filters::Synchronizer< ApproxSync3Policy > * approxSync3_
ros::NodeHandle & getPrivateNodeHandle() const
void combineClouds(const std::vector< sensor_msgs::PointCloud2ConstPtr > &cloudMsgs)
void clouds4_callback(const sensor_msgs::PointCloud2ConstPtr &cloudMsg_1, const sensor_msgs::PointCloud2ConstPtr &cloudMsg_2, const sensor_msgs::PointCloud2ConstPtr &cloudMsg_3, const sensor_msgs::PointCloud2ConstPtr &cloudMsg_4)
message_filters::sync_policies::ApproximateTime< sensor_msgs::PointCloud2, sensor_msgs::PointCloud2 > ApproxSync2Policy
message_filters::Synchronizer< ExactSync3Policy > * exactSync3_
bool param(const std::string &param_name, T &param_val, const T &default_val) const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ros::NodeHandle & getNodeHandle() const
message_filters::sync_policies::ExactTime< sensor_msgs::PointCloud2, sensor_msgs::PointCloud2 > ExactSync2Policy
bool concatenatePointCloud(const sensor_msgs::PointCloud2 &cloud1, const sensor_msgs::PointCloud2 &cloud2, sensor_msgs::PointCloud2 &cloud_out)
#define false
#define NODELET_INFO(...)
uint32_t getNumSubscribers() const
void subscribe(ros::NodeHandle &nh, const std::string &topic, uint32_t queue_size, const ros::TransportHints &transport_hints=ros::TransportHints(), ros::CallbackQueueInterface *callback_queue=0)
void transformPointCloud(const pcl::PointCloud< PointT > &cloud_in, pcl::PointCloud< PointT > &cloud_out, const tf::Transform &transform)
message_filters::sync_policies::ApproximateTime< sensor_msgs::PointCloud2, sensor_msgs::PointCloud2, sensor_msgs::PointCloud2 > ApproxSync3Policy
const std::string header
message_filters::sync_policies::ExactTime< sensor_msgs::PointCloud2, sensor_msgs::PointCloud2, sensor_msgs::PointCloud2, sensor_msgs::PointCloud2 > ExactSync4Policy
PLUGINLIB_EXPORT_CLASS(rtabmap_ros::CoreWrapper, nodelet::Nodelet)
void moveFromPCL(pcl::PCLImage &pcl_image, sensor_msgs::Image &image)
#define ROS_ASSERT(cond)
void clouds2_callback(const sensor_msgs::PointCloud2ConstPtr &cloudMsg_1, const sensor_msgs::PointCloud2ConstPtr &cloudMsg_2)
message_filters::Synchronizer< ApproxSync2Policy > * approxSync2_
r
message_filters::sync_policies::ApproximateTime< sensor_msgs::PointCloud2, sensor_msgs::PointCloud2, sensor_msgs::PointCloud2, sensor_msgs::PointCloud2 > ApproxSync4Policy
void warningLoop(const std::string &subscribedTopicsMsg, bool approxSync)
message_filters::Subscriber< sensor_msgs::PointCloud2 > cloudSub_4_
void toPCL(const ros::Time &stamp, pcl::uint64_t &pcl_stamp)
message_filters::Subscriber< sensor_msgs::PointCloud2 > cloudSub_1_
message_filters::Synchronizer< ApproxSync4Policy > * approxSync4_


rtabmap_ros
Author(s): Mathieu Labbe
autogenerated on Fri Jun 7 2019 21:55:04