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_