32 #include <pcl/point_cloud.h> 33 #include <pcl/point_types.h> 35 #include <pcl/io/pcd_io.h> 41 #include <sensor_msgs/PointCloud2.h> 105 double approxSyncMaxInterval = 0.0;
106 pnh.
param(
"queue_size", queueSize, queueSize);
109 pnh.
param(
"approx_sync", approx, approx);
110 pnh.
param(
"approx_sync_max_interval", approxSyncMaxInterval, approxSyncMaxInterval);
111 pnh.
param(
"count", count, count);
118 std::string subscribedTopicsMsg;
126 if(approxSyncMaxInterval > 0.0)
135 subscribedTopicsMsg =
uFormat(
"\n%s subscribed to (%s sync%s):\n %s,\n %s,\n %s,\n %s",
137 approx?
"approx":
"exact",
138 approx&&approxSyncMaxInterval!=0.0?
uFormat(
", max interval=%fs", approxSyncMaxInterval).c_str():
"",
150 if(approxSyncMaxInterval > 0.0)
159 subscribedTopicsMsg =
uFormat(
"\n%s subscribed to (%s sync%s):\n %s,\n %s,\n %s",
161 approx?
"approx":
"exact",
162 approx&&approxSyncMaxInterval!=0.0?
uFormat(
", max interval=%fs", approxSyncMaxInterval).c_str():
"",
172 if(approxSyncMaxInterval > 0.0)
181 subscribedTopicsMsg =
uFormat(
"\n%s subscribed to (%s sync%s):\n %s,\n %s",
183 approx?
"approx":
"exact",
184 approx&&approxSyncMaxInterval!=0.0?
uFormat(
", max interval=%fs", approxSyncMaxInterval).c_str():
"",
196 const sensor_msgs::PointCloud2ConstPtr & cloudMsg_2,
197 const sensor_msgs::PointCloud2ConstPtr & cloudMsg_3,
198 const sensor_msgs::PointCloud2ConstPtr & cloudMsg_4)
200 std::vector<sensor_msgs::PointCloud2ConstPtr> clouds;
201 clouds.push_back(cloudMsg_1);
202 clouds.push_back(cloudMsg_2);
203 clouds.push_back(cloudMsg_3);
204 clouds.push_back(cloudMsg_4);
209 const sensor_msgs::PointCloud2ConstPtr & cloudMsg_2,
210 const sensor_msgs::PointCloud2ConstPtr & cloudMsg_3)
212 std::vector<sensor_msgs::PointCloud2ConstPtr> clouds;
213 clouds.push_back(cloudMsg_1);
214 clouds.push_back(cloudMsg_2);
215 clouds.push_back(cloudMsg_3);
220 const sensor_msgs::PointCloud2ConstPtr & cloudMsg_2)
222 std::vector<sensor_msgs::PointCloud2ConstPtr> clouds;
223 clouds.push_back(cloudMsg_1);
224 clouds.push_back(cloudMsg_2);
228 void combineClouds(
const std::vector<sensor_msgs::PointCloud2ConstPtr> & cloudMsgs)
234 pcl::PCLPointCloud2::Ptr output(
new pcl::PCLPointCloud2);
237 if(!frameId.empty() && frameId.compare(cloudMsgs[0]->
header.frame_id) != 0)
239 sensor_msgs::PointCloud2 tmp;
246 frameId = cloudMsgs[0]->header.frame_id;
252 bool hasField[4] = {
false};
253 for(
size_t i=0; i<output->fields.size(); ++i)
255 if(output->fields[i].name.compare(
"x") == 0)
259 else if(output->fields[i].name.compare(
"y") == 0)
263 else if(output->fields[i].name.compare(
"z") == 0)
273 if(hasField[0] && hasField[1] && hasField[2] && !hasField[3])
279 pcl::PointCloud<pcl::PointXYZ> cloudxyz;
280 pcl::fromPCLPointCloud2(*output, cloudxyz);
281 pcl::toPCLPointCloud2(cloudxyz, *output);
285 for(
unsigned int i=1; i<cloudMsgs.size(); ++i)
289 cloudMsgs[0]->header.stamp != cloudMsgs[i]->header.stamp)
295 cloudMsgs[i]->
header.stamp,
296 cloudMsgs[0]->header.stamp,
301 pcl::PCLPointCloud2::Ptr cloud2(
new pcl::PCLPointCloud2);
302 if(frameId.compare(cloudMsgs[i]->header.frame_id) != 0)
304 sensor_msgs::PointCloud2 tmp;
306 if(!cloudDisplacement.
isNull())
308 sensor_msgs::PointCloud2 tmp2;
320 if(!cloudDisplacement.
isNull())
322 sensor_msgs::PointCloud2 tmp;
332 if(!cloud2->is_dense)
341 bool hasField[4] = {
false};
342 for(
size_t i=0; i<cloud2->fields.size(); ++i)
344 if(cloud2->fields[i].name.compare(
"x") == 0)
348 else if(cloud2->fields[i].name.compare(
"y") == 0)
352 else if(cloud2->fields[i].name.compare(
"z") == 0)
362 if(hasField[0] && hasField[1] && hasField[2] && !hasField[3])
368 pcl::PointCloud<pcl::PointXYZ> cloudxyz;
369 pcl::fromPCLPointCloud2(*cloud2, cloudxyz);
370 pcl::toPCLPointCloud2(cloudxyz, *cloud2);
374 if(output->data.empty())
378 else if(!cloud2->data.empty())
381 if(output->fields.size() != cloud2->fields.size())
383 ROS_WARN(
"%s: Input topics don't have all the " 384 "same number of fields (cloud1=%d, cloud%d=%d), concatenation " 385 "may fails. You can enable \"xyz_output\" option " 386 "to convert all inputs to XYZ.",
388 (
int)output->fields.size(),
390 (int)output->fields.size());
393 pcl::PCLPointCloud2::Ptr tmp_output(
new pcl::PCLPointCloud2);
394 #if PCL_VERSION_COMPARE(>=, 1, 10, 0) 395 pcl::concatenate(*output, *cloud2, *tmp_output);
400 tmp_output->row_step = tmp_output->width * tmp_output->point_step;
405 sensor_msgs::PointCloud2 rosCloud;
407 rosCloud.header.stamp = cloudMsgs[0]->header.stamp;
408 rosCloud.header.frame_id =
frameId;
413 void warningLoop(
const std::string & subscribedTopicsMsg,
bool approxSync)
421 ROS_WARN(
"%s: Did not receive data since 5 seconds! Make sure the input topics are " 422 "published (\"$ rostopic hz my_topic\") and the timestamps in their " 423 "header are set. %s%s",
425 approxSync?
"":
"Parameter \"approx_sync\" is false, which means that input " 426 "topics should have all the exact timestamp for the callback to be called.",
427 subscribedTopicsMsg.c_str());
message_filters::Synchronizer< ExactSync4Policy > * exactSync4_
message_filters::Subscriber< sensor_msgs::PointCloud2 > cloudSub_2_
std::string uFormat(const char *fmt,...)
std::string getTopic() const
message_filters::Subscriber< sensor_msgs::PointCloud2 > cloudSub_3_
ros::NodeHandle & getNodeHandle() const
message_filters::sync_policies::ExactTime< sensor_msgs::PointCloud2, sensor_msgs::PointCloud2, sensor_msgs::PointCloud2 > ExactSync3Policy
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP removeNaNFromPointCloud(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud)
message_filters::Synchronizer< ExactSync2Policy > * exactSync2_
ros::NodeHandle & getPrivateNodeHandle() const
void clouds3_callback(const sensor_msgs::PointCloud2ConstPtr &cloudMsg_1, const sensor_msgs::PointCloud2ConstPtr &cloudMsg_2, const sensor_msgs::PointCloud2ConstPtr &cloudMsg_3)
rtabmap::Transform getTransform(const std::string &fromFrameId, const std::string &toFrameId, const ros::Time &stamp, tf::TransformListener &listener, double waitForTransform)
message_filters::Synchronizer< ApproxSync3Policy > * approxSync3_
boost::thread * warningThread_
double waitForTransformDuration_
const std::string & getName() const
void combineClouds(const std::vector< sensor_msgs::PointCloud2ConstPtr > &cloudMsgs)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
void publish(const boost::shared_ptr< M > &message) const
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)
virtual ~PointCloudAggregator()
std::string fixedFrameId_
message_filters::sync_policies::ApproximateTime< sensor_msgs::PointCloud2, sensor_msgs::PointCloud2 > ApproxSync2Policy
message_filters::Synchronizer< ExactSync3Policy > * exactSync3_
void toPCL(const ros::Time &stamp, std::uint64_t &pcl_stamp)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
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 NODELET_INFO(...)
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)
tf::TransformListener tfListener_
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
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)
void clouds2_callback(const sensor_msgs::PointCloud2ConstPtr &cloudMsg_1, const sensor_msgs::PointCloud2ConstPtr &cloudMsg_2)
message_filters::Synchronizer< ApproxSync2Policy > * approxSync2_
uint32_t getNumSubscribers() const
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_
message_filters::Subscriber< sensor_msgs::PointCloud2 > cloudSub_1_
message_filters::Synchronizer< ApproxSync4Policy > * approxSync4_