39 #include <pcl/PointIndices.h> 56 double cluster_tolerance;
57 if (!
pnh_->getParam (
"cluster_tolerance", cluster_tolerance))
59 NODELET_ERROR (
"[%s::onInit] Need a 'cluster_tolerance' parameter to be set before continuing!",
getName ().c_str ());
63 if (!
pnh_->getParam (
"spatial_locator", spatial_locator))
65 NODELET_ERROR (
"[%s::onInit] Need a 'spatial_locator' parameter to be set before continuing!",
getName ().c_str ());
78 srv_ = boost::make_shared <dynamic_reconfigure::Server<EuclideanClusterExtractionConfig> > (*pnh_);
80 srv_->setCallback (f);
82 NODELET_DEBUG (
"[%s::onInit] Nodelet successfully created with the following parameters:\n" 83 " - max_queue_size : %d\n" 84 " - use_indices : %s\n" 85 " - cluster_tolerance : %f\n",
91 impl_.setClusterTolerance (cluster_tolerance);
142 if (
impl_.getClusterTolerance () != config.cluster_tolerance)
144 impl_.setClusterTolerance (config.cluster_tolerance);
145 NODELET_DEBUG (
"[%s::config_callback] Setting new clustering tolerance to: %f.",
getName ().c_str (), config.cluster_tolerance);
147 if (
impl_.getMinClusterSize () != config.cluster_min_size)
149 impl_.setMinClusterSize (config.cluster_min_size);
150 NODELET_DEBUG (
"[%s::config_callback] Setting the minimum cluster size to: %d.",
getName ().c_str (), config.cluster_min_size);
152 if (
impl_.getMaxClusterSize () != config.cluster_max_size)
154 impl_.setMaxClusterSize (config.cluster_max_size);
155 NODELET_DEBUG (
"[%s::config_callback] Setting the maximum cluster size to: %d.",
getName ().c_str (), config.cluster_max_size);
160 NODELET_DEBUG (
"[%s::config_callback] Setting the maximum number of clusters to extract to: %d.",
getName ().c_str (), config.max_clusters);
180 if (indices && !
isValid (indices))
188 std_msgs::Header cloud_header =
fromPCL(cloud->header);
189 std_msgs::Header indices_header = indices->header;
191 " - PointCloud with %d data points (%s), stamp %f, and frame %s on topic %s received.\n" 192 " - PointIndices with %zu values, stamp %f, and frame %s on topic %s received.",
194 cloud->width * cloud->height,
pcl::getFieldsList (*cloud).c_str (), cloud_header.stamp.toSec (), cloud_header.frame_id.c_str (),
pnh_->resolveName (
"input").c_str (),
195 indices->indices.size (), indices_header.stamp.toSec (), indices_header.frame_id.c_str (),
pnh_->resolveName (
"indices").c_str ());
197 NODELET_DEBUG (
"[%s::input_callback] PointCloud with %d data points, stamp %f, and frame %s on topic %s received.",
getName ().c_str (), cloud->width * cloud->height,
fromPCL(cloud->header).stamp.toSec (), cloud->header.frame_id.c_str (),
pnh_->resolveName (
"input").c_str ());
203 indices_ptr.reset (
new std::vector<int> (indices->indices));
206 impl_.setIndices (indices_ptr);
208 std::vector<pcl::PointIndices> clusters;
209 impl_.extract (clusters);
213 for (
size_t i = 0; i < clusters.size (); ++i)
218 pcl_msgs::PointIndices ros_pi;
224 NODELET_DEBUG (
"[segmentAndPublish] Published %zu clusters (PointIndices) on topic %s", clusters.size (),
pnh_->resolveName (
"output").c_str ());
228 for (
size_t i = 0; i < clusters.size (); ++i)
233 copyPointCloud (*cloud, clusters[i].indices, output);
240 toPCL(header, output.header);
243 NODELET_DEBUG (
"[segmentAndPublish] Published cluster %zu (with %zu values and stamp %f) on topic %s",
244 i, clusters[i].indices.size (), header.stamp.toSec (),
pnh_->resolveName (
"output").c_str ());
std::string getFieldsList(const sensor_msgs::PointCloud2 &cloud)
#define NODELET_ERROR(...)
virtual void onInit()
Nodelet initialization routine. Reads in global parameters used by all nodelets.
message_filters::Subscriber< PointIndices > sub_indices_filter_
The message filter subscriber for PointIndices.
bool isValid(const PointCloud2::ConstPtr &cloud, const std::string &topic_name="input")
Test whether a given PointCloud message is "valid" (i.e., has points, and width and height are non-ze...
const std::string & getName() const
void publish(const boost::shared_ptr< M > &message) const
void toPCL(const ros::Time &stamp, std::uint64_t &pcl_stamp)
pcl::PointCloud< pcl::PointXYZ > PointCloud
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)
bool approximate_sync_
True if we use an approximate time synchronizer versus an exact one (false by default).
pcl::IndicesPtr IndicesPtr
int max_queue_size_
The maximum queue size (default: 3).
ros::Publisher pub_output_
The output PointCloud publisher.
void moveFromPCL(pcl::PCLImage &pcl_image, sensor_msgs::Image &image)
void fromPCL(const std::uint64_t &pcl_stamp, ros::Time &stamp)
uint32_t getNumSubscribers() const
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
boost::shared_ptr< T > pcl_ptr(const boost::shared_ptr< T > &p)
#define NODELET_DEBUG(...)
bool use_indices_
Set to true if point indices are used.
PointIndices::ConstPtr PointIndicesConstPtr
boost::shared_ptr< T > ros_ptr(const boost::shared_ptr< T > &p)
message_filters::Subscriber< PointCloud > sub_input_filter_
The message filter subscriber for PointCloud2.