Apply ament_uncrustify --reformat (#297)

Signed-off-by: Sean Kelly <sean@seankelly.dev>
This commit is contained in:
Sean Kelly
2020-08-06 15:28:29 -04:00
committed by GitHub
parent 0ac6810688
commit 63cee139f1
88 changed files with 6019 additions and 5318 deletions
+33 -34
View File
@@ -45,44 +45,43 @@
namespace pcl_ros
{
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b BoundaryEstimation estimates whether a set of points is lying on surface boundaries using an angle
* criterion. The code makes use of the estimated surface normals at each point in the input dataset.
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a NormalEstimationOpenMP and \a NormalEstimationTBB for examples on how to extend this to parallel implementations.
* \author Radu Bogdan Rusu
*/
class BoundaryEstimation: public FeatureFromNormals
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b BoundaryEstimation estimates whether a set of points is lying on surface boundaries using an angle
* criterion. The code makes use of the estimated surface normals at each point in the input dataset.
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a NormalEstimationOpenMP and \a NormalEstimationTBB for examples on how to extend this to parallel implementations.
* \author Radu Bogdan Rusu
*/
class BoundaryEstimation : public FeatureFromNormals
{
private:
pcl::BoundaryEstimation<pcl::PointXYZ, pcl::Normal, pcl::Boundary> impl_;
typedef pcl::PointCloud<pcl::Boundary> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
pcl::BoundaryEstimation<pcl::PointXYZ, pcl::Normal, pcl::Boundary> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloudOut>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::Boundary> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloudOut> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudNConstPtr & normals,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudNConstPtr &normals,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_BOUNDARY_H_
+181 -170
View File
@@ -54,198 +54,209 @@
namespace pcl_ros
{
namespace sync_policies = message_filters::sync_policies;
namespace sync_policies = message_filters::sync_policies;
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b Feature represents the base feature class. Some generic 3D operations that
* are applicable to all features are defined here as static methods.
* \author Radu Bogdan Rusu
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b Feature represents the base feature class. Some generic 3D operations that
* are applicable to all features are defined here as static methods.
* \author Radu Bogdan Rusu
*/
class Feature : public PCLNodelet
{
public:
typedef pcl::KdTree<pcl::PointXYZ> KdTree;
typedef pcl::KdTree<pcl::PointXYZ>::Ptr KdTreePtr;
typedef pcl::PointCloud<pcl::PointXYZ> PointCloudIn;
typedef boost::shared_ptr<PointCloudIn> PointCloudInPtr;
typedef boost::shared_ptr<const PointCloudIn> PointCloudInConstPtr;
typedef pcl::IndicesPtr IndicesPtr;
typedef pcl::IndicesConstPtr IndicesConstPtr;
/** \brief Empty constructor. */
Feature()
: /*input_(), indices_(), surface_(), */ tree_(), k_(0), search_radius_(0),
use_surface_(false), spatial_locator_type_(-1)
{}
protected:
/** \brief The input point cloud dataset. */
//PointCloudInConstPtr input_;
/** \brief A pointer to the vector of point indices to use. */
//IndicesConstPtr indices_;
/** \brief An input point cloud describing the surface that is to be used for nearest neighbors estimation. */
//PointCloudInConstPtr surface_;
/** \brief A pointer to the spatial search object. */
KdTreePtr tree_;
/** \brief The number of K nearest neighbors to use for each point. */
int k_;
/** \brief The nearest neighbors search radius for each point. */
double search_radius_;
// ROS nodelet attributes
/** \brief The surface PointCloud subscriber filter. */
message_filters::Subscriber<PointCloudIn> sub_surface_filter_;
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief Set to true if the nodelet needs to listen for incoming point clouds representing the search surface. */
bool use_surface_;
/** \brief Parameter for the spatial locator tree. By convention, the values represent:
* 0: ANN (Approximate Nearest Neigbor library) kd-tree
* 1: FLANN (Fast Library for Approximate Nearest Neighbors) kd-tree
* 2: Organized spatial dataset index
*/
class Feature : public PCLNodelet
int spatial_locator_type_;
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<FeatureConfig>> srv_;
/** \brief Child initialization routine. Internal method. */
virtual bool childInit(ros::NodeHandle & nh) = 0;
/** \brief Publish an empty point cloud of the feature output type. */
virtual void emptyPublish(const PointCloudInConstPtr & cloud) = 0;
/** \brief Compute the feature and publish it. Internal method. */
virtual void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices) = 0;
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback(FeatureConfig & config, uint32_t level);
/** \brief Null passthrough filter, used for pushing empty elements in the
* synchronizer */
message_filters::PassThrough<PointIndices> nf_pi_;
message_filters::PassThrough<PointCloudIn> nf_pc_;
/** \brief Input point cloud callback.
* Because we want to use the same synchronizer object, we push back
* empty elements with the same timestamp.
*/
inline void
input_callback(const PointCloudInConstPtr & input)
{
public:
typedef pcl::KdTree<pcl::PointXYZ> KdTree;
typedef pcl::KdTree<pcl::PointXYZ>::Ptr KdTreePtr;
PointIndices indices;
indices.header.stamp = pcl_conversions::fromPCL(input->header).stamp;
PointCloudIn cloud;
cloud.header.stamp = input->header.stamp;
nf_pc_.add(ros_ptr(cloud.makeShared()));
nf_pi_.add(boost::make_shared<PointIndices>(indices));
}
typedef pcl::PointCloud<pcl::PointXYZ> PointCloudIn;
typedef boost::shared_ptr<PointCloudIn> PointCloudInPtr;
typedef boost::shared_ptr<const PointCloudIn> PointCloudInConstPtr;
private:
/** \brief Synchronized input, surface, and point indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloudIn,
PointCloudIn, PointIndices>>> sync_input_surface_indices_a_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloudIn,
PointCloudIn, PointIndices>>> sync_input_surface_indices_e_;
typedef pcl::IndicesPtr IndicesPtr;
typedef pcl::IndicesConstPtr IndicesConstPtr;
/** \brief Nodelet initialization routine. */
virtual void onInit();
/** \brief Empty constructor. */
Feature () : /*input_(), indices_(), surface_(), */tree_(), k_(0), search_radius_(0),
use_surface_(false), spatial_locator_type_(-1)
{};
/** \brief NodeletLazy connection routine. */
virtual void subscribe();
virtual void unsubscribe();
protected:
/** \brief The input point cloud dataset. */
//PointCloudInConstPtr input_;
/** \brief Input point cloud callback. Used when \a use_indices and \a use_surface are set.
* \param cloud the pointer to the input point cloud
* \param cloud_surface the pointer to the surface point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_surface_indices_callback(
const PointCloudInConstPtr & cloud,
const PointCloudInConstPtr & cloud_surface,
const PointIndicesConstPtr & indices);
/** \brief A pointer to the vector of point indices to use. */
//IndicesConstPtr indices_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
/** \brief An input point cloud describing the surface that is to be used for nearest neighbors estimation. */
//PointCloudInConstPtr surface_;
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
class FeatureFromNormals : public Feature
{
public:
typedef sensor_msgs::PointCloud2 PointCloud2;
/** \brief A pointer to the spatial search object. */
KdTreePtr tree_;
typedef pcl::PointCloud<pcl::Normal> PointCloudN;
typedef boost::shared_ptr<PointCloudN> PointCloudNPtr;
typedef boost::shared_ptr<const PointCloudN> PointCloudNConstPtr;
/** \brief The number of K nearest neighbors to use for each point. */
int k_;
FeatureFromNormals()
: normals_() {}
/** \brief The nearest neighbors search radius for each point. */
double search_radius_;
protected:
/** \brief A pointer to the input dataset that contains the point normals of the XYZ dataset. */
PointCloudNConstPtr normals_;
// ROS nodelet attributes
/** \brief The surface PointCloud subscriber filter. */
message_filters::Subscriber<PointCloudIn> sub_surface_filter_;
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief Child initialization routine. Internal method. */
virtual bool childInit(ros::NodeHandle & nh) = 0;
/** \brief Set to true if the nodelet needs to listen for incoming point clouds representing the search surface. */
bool use_surface_;
/** \brief Publish an empty point cloud of the feature output type. */
virtual void emptyPublish(const PointCloudInConstPtr & cloud) = 0;
/** \brief Parameter for the spatial locator tree. By convention, the values represent:
* 0: ANN (Approximate Nearest Neigbor library) kd-tree
* 1: FLANN (Fast Library for Approximate Nearest Neighbors) kd-tree
* 2: Organized spatial dataset index
*/
int spatial_locator_type_;
/** \brief Compute the feature and publish it. */
virtual void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudNConstPtr & normals,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices) = 0;
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr <dynamic_reconfigure::Server<FeatureConfig> > srv_;
private:
/** \brief The normals PointCloud subscriber filter. */
message_filters::Subscriber<PointCloudN> sub_normals_filter_;
/** \brief Child initialization routine. Internal method. */
virtual bool childInit (ros::NodeHandle &nh) = 0;
/** \brief Synchronized input, normals, surface, and point indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloudIn,
PointCloudN, PointCloudIn, PointIndices>>> sync_input_normals_surface_indices_a_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloudIn,
PointCloudN, PointCloudIn, PointIndices>>> sync_input_normals_surface_indices_e_;
/** \brief Publish an empty point cloud of the feature output type. */
virtual void emptyPublish (const PointCloudInConstPtr &cloud) = 0;
/** \brief Internal method. */
void computePublish(
const PointCloudInConstPtr &,
const PointCloudInConstPtr &,
const IndicesPtr &) {} // This should never be called
/** \brief Compute the feature and publish it. Internal method. */
virtual void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices) = 0;
/** \brief Nodelet initialization routine. */
virtual void onInit();
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback (FeatureConfig &config, uint32_t level);
/** \brief NodeletLazy connection routine. */
virtual void subscribe();
virtual void unsubscribe();
/** \brief Null passthrough filter, used for pushing empty elements in the
* synchronizer */
message_filters::PassThrough<PointIndices> nf_pi_;
message_filters::PassThrough<PointCloudIn> nf_pc_;
/** \brief Input point cloud callback. Used when \a use_indices and \a use_surface are set.
* \param cloud the pointer to the input point cloud
* \param cloud_normals the pointer to the input point cloud normals
* \param cloud_surface the pointer to the surface point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_normals_surface_indices_callback(
const PointCloudInConstPtr & cloud,
const PointCloudNConstPtr & cloud_normals,
const PointCloudInConstPtr & cloud_surface,
const PointIndicesConstPtr & indices);
/** \brief Input point cloud callback.
* Because we want to use the same synchronizer object, we push back
* empty elements with the same timestamp.
*/
inline void
input_callback (const PointCloudInConstPtr &input)
{
PointIndices indices;
indices.header.stamp = pcl_conversions::fromPCL(input->header).stamp;
PointCloudIn cloud;
cloud.header.stamp = input->header.stamp;
nf_pc_.add (ros_ptr(cloud.makeShared ()));
nf_pi_.add (boost::make_shared<PointIndices> (indices));
}
private:
/** \brief Synchronized input, surface, and point indices.*/
boost::shared_ptr <message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloudIn, PointCloudIn, PointIndices> > > sync_input_surface_indices_a_;
boost::shared_ptr <message_filters::Synchronizer<sync_policies::ExactTime<PointCloudIn, PointCloudIn, PointIndices> > > sync_input_surface_indices_e_;
/** \brief Nodelet initialization routine. */
virtual void onInit ();
/** \brief NodeletLazy connection routine. */
virtual void subscribe ();
virtual void unsubscribe ();
/** \brief Input point cloud callback. Used when \a use_indices and \a use_surface are set.
* \param cloud the pointer to the input point cloud
* \param cloud_surface the pointer to the surface point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_surface_indices_callback (const PointCloudInConstPtr &cloud,
const PointCloudInConstPtr &cloud_surface,
const PointIndicesConstPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
class FeatureFromNormals : public Feature
{
public:
typedef sensor_msgs::PointCloud2 PointCloud2;
typedef pcl::PointCloud<pcl::Normal> PointCloudN;
typedef boost::shared_ptr<PointCloudN> PointCloudNPtr;
typedef boost::shared_ptr<const PointCloudN> PointCloudNConstPtr;
FeatureFromNormals () : normals_() {};
protected:
/** \brief A pointer to the input dataset that contains the point normals of the XYZ dataset. */
PointCloudNConstPtr normals_;
/** \brief Child initialization routine. Internal method. */
virtual bool childInit (ros::NodeHandle &nh) = 0;
/** \brief Publish an empty point cloud of the feature output type. */
virtual void emptyPublish (const PointCloudInConstPtr &cloud) = 0;
/** \brief Compute the feature and publish it. */
virtual void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudNConstPtr &normals,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices) = 0;
private:
/** \brief The normals PointCloud subscriber filter. */
message_filters::Subscriber<PointCloudN> sub_normals_filter_;
/** \brief Synchronized input, normals, surface, and point indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloudIn, PointCloudN, PointCloudIn, PointIndices> > > sync_input_normals_surface_indices_a_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloudIn, PointCloudN, PointCloudIn, PointIndices> > > sync_input_normals_surface_indices_e_;
/** \brief Internal method. */
void computePublish (const PointCloudInConstPtr &,
const PointCloudInConstPtr &,
const IndicesPtr &) {} // This should never be called
/** \brief Nodelet initialization routine. */
virtual void onInit ();
/** \brief NodeletLazy connection routine. */
virtual void subscribe ();
virtual void unsubscribe ();
/** \brief Input point cloud callback. Used when \a use_indices and \a use_surface are set.
* \param cloud the pointer to the input point cloud
* \param cloud_normals the pointer to the input point cloud normals
* \param cloud_surface the pointer to the surface point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_normals_surface_indices_callback (const PointCloudInConstPtr &cloud,
const PointCloudNConstPtr &cloud_normals,
const PointCloudInConstPtr &cloud_surface,
const PointIndicesConstPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_FEATURE_H_
+47 -48
View File
@@ -43,58 +43,57 @@
namespace pcl_ros
{
/** \brief @b FPFHEstimation estimates the <b>Fast Point Feature Histogram (FPFH)</b> descriptor for a given point cloud
* dataset containing points and normals.
*
* @note If you use this code in any academic work, please cite:
*
* <ul>
* <li> R.B. Rusu, N. Blodow, M. Beetz.
* Fast Point Feature Histograms (FPFH) for 3D Registration.
* In Proceedings of the IEEE International Conference on Robotics and Automation (ICRA),
* Kobe, Japan, May 12-17 2009.
* </li>
* <li> R.B. Rusu, A. Holzbach, N. Blodow, M. Beetz.
* Fast Geometric Point Labeling using Conditional Random Fields.
* In Proceedings of the 22nd IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS),
* St. Louis, MO, USA, October 11-15 2009.
* </li>
* </ul>
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a FPFHEstimationOpenMP for examples on parallel implementations of the FPFH (Fast Point Feature Histogram).
* \author Radu Bogdan Rusu
*/
class FPFHEstimation : public FeatureFromNormals
/** \brief @b FPFHEstimation estimates the <b>Fast Point Feature Histogram (FPFH)</b> descriptor for a given point cloud
* dataset containing points and normals.
*
* @note If you use this code in any academic work, please cite:
*
* <ul>
* <li> R.B. Rusu, N. Blodow, M. Beetz.
* Fast Point Feature Histograms (FPFH) for 3D Registration.
* In Proceedings of the IEEE International Conference on Robotics and Automation (ICRA),
* Kobe, Japan, May 12-17 2009.
* </li>
* <li> R.B. Rusu, A. Holzbach, N. Blodow, M. Beetz.
* Fast Geometric Point Labeling using Conditional Random Fields.
* In Proceedings of the 22nd IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS),
* St. Louis, MO, USA, October 11-15 2009.
* </li>
* </ul>
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a FPFHEstimationOpenMP for examples on parallel implementations of the FPFH (Fast Point Feature Histogram).
* \author Radu Bogdan Rusu
*/
class FPFHEstimation : public FeatureFromNormals
{
private:
pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> impl_;
typedef pcl::PointCloud<pcl::FPFHSignature33> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloudOut>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::FPFHSignature33> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloudOut> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudNConstPtr & normals,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudNConstPtr &normals,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_FPFH_H_
+44 -44
View File
@@ -43,54 +43,54 @@
namespace pcl_ros
{
/** \brief @b FPFHEstimationOMP estimates the Fast Point Feature Histogram (FPFH) descriptor for a given point cloud
* dataset containing points and normals, in parallel, using the OpenMP standard.
*
* @note If you use this code in any academic work, please cite:
*
* <ul>
* <li> R.B. Rusu, N. Blodow, M. Beetz.
* Fast Point Feature Histograms (FPFH) for 3D Registration.
* In Proceedings of the IEEE International Conference on Robotics and Automation (ICRA),
* Kobe, Japan, May 12-17 2009.
* </li>
* <li> R.B. Rusu, A. Holzbach, N. Blodow, M. Beetz.
* Fast Geometric Point Labeling using Conditional Random Fields.
* In Proceedings of the 22nd IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS),
* St. Louis, MO, USA, October 11-15 2009.
* </li>
* </ul>
* \author Radu Bogdan Rusu
*/
class FPFHEstimationOMP : public FeatureFromNormals
/** \brief @b FPFHEstimationOMP estimates the Fast Point Feature Histogram (FPFH) descriptor for a given point cloud
* dataset containing points and normals, in parallel, using the OpenMP standard.
*
* @note If you use this code in any academic work, please cite:
*
* <ul>
* <li> R.B. Rusu, N. Blodow, M. Beetz.
* Fast Point Feature Histograms (FPFH) for 3D Registration.
* In Proceedings of the IEEE International Conference on Robotics and Automation (ICRA),
* Kobe, Japan, May 12-17 2009.
* </li>
* <li> R.B. Rusu, A. Holzbach, N. Blodow, M. Beetz.
* Fast Geometric Point Labeling using Conditional Random Fields.
* In Proceedings of the 22nd IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS),
* St. Louis, MO, USA, October 11-15 2009.
* </li>
* </ul>
* \author Radu Bogdan Rusu
*/
class FPFHEstimationOMP : public FeatureFromNormals
{
private:
pcl::FPFHEstimationOMP<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> impl_;
typedef pcl::PointCloud<pcl::FPFHSignature33> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
pcl::FPFHEstimationOMP<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloudOut>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::FPFHSignature33> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloudOut> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudNConstPtr & normals,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudNConstPtr &normals,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_FPFH_OMP_H_
@@ -43,41 +43,40 @@
namespace pcl_ros
{
/** \brief MomentInvariantsEstimation estimates the 3 moment invariants (j1, j2, j3) at each 3D point.
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a NormalEstimationOpenMP and \a NormalEstimationTBB for examples on how to extend this to parallel implementations.
* \author Radu Bogdan Rusu
*/
class MomentInvariantsEstimation: public Feature
/** \brief MomentInvariantsEstimation estimates the 3 moment invariants (j1, j2, j3) at each 3D point.
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a NormalEstimationOpenMP and \a NormalEstimationTBB for examples on how to extend this to parallel implementations.
* \author Radu Bogdan Rusu
*/
class MomentInvariantsEstimation : public Feature
{
private:
pcl::MomentInvariantsEstimation<pcl::PointXYZ, pcl::MomentInvariants> impl_;
typedef pcl::PointCloud<pcl::MomentInvariants> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
pcl::MomentInvariantsEstimation<pcl::PointXYZ, pcl::MomentInvariants> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloudOut>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::MomentInvariants> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloudOut> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_MOMENT_INVARIANTS_H_
+34 -34
View File
@@ -43,44 +43,44 @@
namespace pcl_ros
{
/** \brief @b NormalEstimation estimates local surface properties at each 3D point, such as surface normals and
* curvatures.
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a NormalEstimationOpenMP and \a NormalEstimationTBB for parallel implementations.
* \author Radu Bogdan Rusu
*/
class NormalEstimation: public Feature
/** \brief @b NormalEstimation estimates local surface properties at each 3D point, such as surface normals and
* curvatures.
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a NormalEstimationOpenMP and \a NormalEstimationTBB for parallel implementations.
* \author Radu Bogdan Rusu
*/
class NormalEstimation : public Feature
{
private:
/** \brief PCL implementation object. */
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> impl_;
typedef pcl::PointCloud<pcl::Normal> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
/** \brief PCL implementation object. */
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloudOut>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::Normal> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type.
* \param cloud the input point cloud to copy the header from.
*/
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloudOut> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type.
* \param cloud the input point cloud to copy the header from.
*/
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_NORMAL_3D_H_
@@ -43,37 +43,38 @@
namespace pcl_ros
{
/** \brief @b NormalEstimationOMP estimates local surface properties at each 3D point, such as surface normals and
* curvatures, in parallel, using the OpenMP standard.
* \author Radu Bogdan Rusu
*/
class NormalEstimationOMP: public Feature
/** \brief @b NormalEstimationOMP estimates local surface properties at each 3D point, such as surface normals and
* curvatures, in parallel, using the OpenMP standard.
* \author Radu Bogdan Rusu
*/
class NormalEstimationOMP : public Feature
{
private:
pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> impl_;
typedef pcl::PointCloud<pcl::Normal> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloudOut>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::Normal> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloudOut> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_NORMAL_3D_OMP_H_
@@ -46,41 +46,40 @@
namespace pcl_ros
{
/** \brief @b NormalEstimationTBB estimates local surface properties at each 3D point, such as surface normals and
* curvatures, in parallel, using Intel's Threading Building Blocks library.
* \author Radu Bogdan Rusu
*/
class NormalEstimationTBB: public Feature
/** \brief @b NormalEstimationTBB estimates local surface properties at each 3D point, such as surface normals and
* curvatures, in parallel, using Intel's Threading Building Blocks library.
* \author Radu Bogdan Rusu
*/
class NormalEstimationTBB : public Feature
{
private:
pcl::NormalEstimationTBB<pcl::PointXYZ, pcl::Normal> impl_;
typedef pcl::PointCloud<pcl::Normal> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
pcl::NormalEstimationTBB<pcl::PointXYZ, pcl::Normal> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloud>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::Normal> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloud> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
//#endif // HAVE_TBB
#endif //#ifndef PCL_ROS_NORMAL_3D_TBB_H_
+47 -48
View File
@@ -43,58 +43,57 @@
namespace pcl_ros
{
/** \brief @b PFHEstimation estimates the Point Feature Histogram (PFH) descriptor for a given point cloud dataset
* containing points and normals.
*
* @note If you use this code in any academic work, please cite:
*
* <ul>
* <li> R.B. Rusu, N. Blodow, Z.C. Marton, M. Beetz.
* Aligning Point Cloud Views using Persistent Feature Histograms.
* In Proceedings of the 21st IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS),
* Nice, France, September 22-26 2008.
* </li>
* <li> R.B. Rusu, Z.C. Marton, N. Blodow, M. Beetz.
* Learning Informative Point Classes for the Acquisition of Object Model Maps.
* In Proceedings of the 10th International Conference on Control, Automation, Robotics and Vision (ICARCV),
* Hanoi, Vietnam, December 17-20 2008.
* </li>
* </ul>
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a FPFHEstimationOpenMP for examples on parallel implementations of the FPFH (Fast Point Feature Histogram).
* \author Radu Bogdan Rusu
*/
class PFHEstimation : public FeatureFromNormals
/** \brief @b PFHEstimation estimates the Point Feature Histogram (PFH) descriptor for a given point cloud dataset
* containing points and normals.
*
* @note If you use this code in any academic work, please cite:
*
* <ul>
* <li> R.B. Rusu, N. Blodow, Z.C. Marton, M. Beetz.
* Aligning Point Cloud Views using Persistent Feature Histograms.
* In Proceedings of the 21st IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS),
* Nice, France, September 22-26 2008.
* </li>
* <li> R.B. Rusu, Z.C. Marton, N. Blodow, M. Beetz.
* Learning Informative Point Classes for the Acquisition of Object Model Maps.
* In Proceedings of the 10th International Conference on Control, Automation, Robotics and Vision (ICARCV),
* Hanoi, Vietnam, December 17-20 2008.
* </li>
* </ul>
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a FPFHEstimationOpenMP for examples on parallel implementations of the FPFH (Fast Point Feature Histogram).
* \author Radu Bogdan Rusu
*/
class PFHEstimation : public FeatureFromNormals
{
private:
pcl::PFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::PFHSignature125> impl_;
typedef pcl::PointCloud<pcl::PFHSignature125> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
pcl::PFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::PFHSignature125> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloudOut>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::PFHSignature125> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloudOut> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudNConstPtr & normals,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudNConstPtr &normals,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_PFH_H_
@@ -44,41 +44,42 @@
namespace pcl_ros
{
/** \brief @b PrincipalCurvaturesEstimation estimates the directions (eigenvectors) and magnitudes (eigenvalues) of
* principal surface curvatures for a given point cloud dataset containing points and normals.
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a NormalEstimationOpenMP and \a NormalEstimationTBB for examples on how to extend this to parallel implementations.
* \author Radu Bogdan Rusu, Jared Glover
*/
class PrincipalCurvaturesEstimation : public FeatureFromNormals
/** \brief @b PrincipalCurvaturesEstimation estimates the directions (eigenvectors) and magnitudes (eigenvalues) of
* principal surface curvatures for a given point cloud dataset containing points and normals.
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a NormalEstimationOpenMP and \a NormalEstimationTBB for examples on how to extend this to parallel implementations.
* \author Radu Bogdan Rusu, Jared Glover
*/
class PrincipalCurvaturesEstimation : public FeatureFromNormals
{
private:
pcl::PrincipalCurvaturesEstimation<pcl::PointXYZ, pcl::Normal, pcl::PrincipalCurvatures> impl_;
typedef pcl::PointCloud<pcl::PrincipalCurvatures> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
pcl::PrincipalCurvaturesEstimation<pcl::PointXYZ, pcl::Normal, pcl::PrincipalCurvatures> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloudOut>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::PrincipalCurvatures> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloudOut> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudNConstPtr & normals,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudNConstPtr &normals,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_PRINCIPAL_CURVATURES_H_
+28 -29
View File
@@ -42,39 +42,38 @@
namespace pcl_ros
{
/** \brief @b SHOTEstimation estimates SHOT descriptor.
*
*/
class SHOTEstimation : public FeatureFromNormals
/** \brief @b SHOTEstimation estimates SHOT descriptor.
*
*/
class SHOTEstimation : public FeatureFromNormals
{
private:
pcl::SHOTEstimation<pcl::PointXYZ, pcl::Normal, pcl::SHOT352> impl_;
typedef pcl::PointCloud<pcl::SHOT352> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
pcl::SHOTEstimation<pcl::PointXYZ, pcl::Normal, pcl::SHOT352> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloudOut>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::SHOT352> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloudOut> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudNConstPtr & normals,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudNConstPtr &normals,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_SHOT_H_
+27 -27
View File
@@ -42,37 +42,37 @@
namespace pcl_ros
{
/** \brief @b SHOTEstimation estimates SHOT descriptor using OpenMP.
*/
class SHOTEstimationOMP : public FeatureFromNormals
/** \brief @b SHOTEstimation estimates SHOT descriptor using OpenMP.
*/
class SHOTEstimationOMP : public FeatureFromNormals
{
private:
pcl::SHOTEstimationOMP<pcl::PointXYZ, pcl::Normal, pcl::SHOT352> impl_;
typedef pcl::PointCloud<pcl::SHOT352> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
pcl::SHOTEstimationOMP<pcl::PointXYZ, pcl::Normal, pcl::SHOT352> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloudOut>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::SHOT352> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloudOut> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudNConstPtr & normals,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudNConstPtr &normals,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_SHOT_OMP_H_
+32 -31
View File
@@ -43,41 +43,42 @@
namespace pcl_ros
{
/** \brief @b VFHEstimation estimates the <b>Viewpoint Feature Histogram (VFH)</b> descriptor for a given point cloud
* dataset containing points and normals.
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a FPFHEstimationOpenMP for examples on parallel implementations of the FPFH (Fast Point Feature Histogram).
* \author Radu Bogdan Rusu
*/
class VFHEstimation : public FeatureFromNormals
/** \brief @b VFHEstimation estimates the <b>Viewpoint Feature Histogram (VFH)</b> descriptor for a given point cloud
* dataset containing points and normals.
*
* @note The code is stateful as we do not expect this class to be multicore parallelized. Please look at
* \a FPFHEstimationOpenMP for examples on parallel implementations of the FPFH (Fast Point Feature Histogram).
* \author Radu Bogdan Rusu
*/
class VFHEstimation : public FeatureFromNormals
{
private:
pcl::VFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::VFHSignature308> impl_;
typedef pcl::PointCloud<pcl::VFHSignature308> PointCloudOut;
/** \brief Child initialization routine. Internal method. */
inline bool
childInit(ros::NodeHandle & nh)
{
private:
pcl::VFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::VFHSignature308> impl_;
// Create the output publisher
pub_output_ = advertise<PointCloudOut>(nh, "output", max_queue_size_);
return true;
}
typedef pcl::PointCloud<pcl::VFHSignature308> PointCloudOut;
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish(const PointCloudInConstPtr & cloud);
/** \brief Child initialization routine. Internal method. */
inline bool
childInit (ros::NodeHandle &nh)
{
// Create the output publisher
pub_output_ = advertise<PointCloudOut> (nh, "output", max_queue_size_);
return (true);
}
/** \brief Compute the feature and publish it. */
void computePublish(
const PointCloudInConstPtr & cloud,
const PointCloudNConstPtr & normals,
const PointCloudInConstPtr & surface,
const IndicesPtr & indices);
/** \brief Publish an empty point cloud of the feature output type. */
void emptyPublish (const PointCloudInConstPtr &cloud);
/** \brief Compute the feature and publish it. */
void computePublish (const PointCloudInConstPtr &cloud,
const PointCloudNConstPtr &normals,
const PointCloudInConstPtr &surface,
const IndicesPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_FEATURES_VFH_H_
+50 -48
View File
@@ -1,5 +1,5 @@
/*
*
*
* Software License Agreement (BSD License)
*
* Copyright (c) 2010, Willow Garage, Inc.
@@ -32,7 +32,7 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id: cropbox.cpp
* $Id: cropbox.cpp
*
*/
@@ -48,57 +48,59 @@
namespace pcl_ros
{
/** \brief @b CropBox is a filter that allows the user to filter all the data inside of a given box.
*
* \author Radu Bogdan Rusu
* \author Justin Rosen
* \author Marti Morta Garriga
/** \brief @b CropBox is a filter that allows the user to filter all the data inside of a given box.
*
* \author Radu Bogdan Rusu
* \author Justin Rosen
* \author Marti Morta Garriga
*/
class CropBox : public Filter
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<pcl_ros::CropBoxConfig>> srv_; // TODO
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
class CropBox : public Filter
inline void
filter(
const PointCloud2::ConstPtr & input, const IndicesPtr & indices,
PointCloud2 & output)
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr <dynamic_reconfigure::Server<pcl_ros::CropBoxConfig> > srv_; // TODO
boost::mutex::scoped_lock lock(mutex_);
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL(*(input), *(pcl_input));
impl_.setInputCloud(pcl_input);
impl_.setIndices(indices);
pcl::PCLPointCloud2 pcl_output;
impl_.filter(pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
inline void
filter (const PointCloud2::ConstPtr &input, const IndicesPtr &indices,
PointCloud2 &output)
{
boost::mutex::scoped_lock lock (mutex_);
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL (*(input), *(pcl_input));
impl_.setInputCloud (pcl_input);
impl_.setIndices (indices);
pcl::PCLPointCloud2 pcl_output;
impl_.filter (pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
bool
child_init(ros::NodeHandle & nh, bool & has_service);
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
bool
child_init (ros::NodeHandle &nh, bool &has_service);
/** \brief Dynamic reconfigure service callback.
* \param config the dynamic reconfigure CropBoxConfig object
* \param level the dynamic reconfigure level
*/
void
config_callback (pcl_ros::CropBoxConfig &config, uint32_t level);
/** \brief Dynamic reconfigure service callback.
* \param config the dynamic reconfigure CropBoxConfig object
* \param level the dynamic reconfigure level
*/
void
config_callback(pcl_ros::CropBoxConfig & config, uint32_t level);
private:
/** \brief The PCL filter implementation used. */
pcl::CropBox<pcl::PCLPointCloud2> impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
private:
/** \brief The PCL filter implementation used. */
pcl::CropBox<pcl::PCLPointCloud2> impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_FILTERS_CROPBOX_H_
@@ -46,53 +46,54 @@
namespace pcl_ros
{
/** \brief @b ExtractIndices extracts a set of indices from a PointCloud as a separate PointCloud.
* \note setFilterFieldName (), setFilterLimits (), and setFilterLimitNegative () are ignored.
* \author Radu Bogdan Rusu
/** \brief @b ExtractIndices extracts a set of indices from a PointCloud as a separate PointCloud.
* \note setFilterFieldName (), setFilterLimits (), and setFilterLimitNegative () are ignored.
* \author Radu Bogdan Rusu
*/
class ExtractIndices : public Filter
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<pcl_ros::ExtractIndicesConfig>> srv_;
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
class ExtractIndices : public Filter
inline void
filter(
const PointCloud2::ConstPtr & input, const IndicesPtr & indices,
PointCloud2 & output)
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr <dynamic_reconfigure::Server<pcl_ros::ExtractIndicesConfig> > srv_;
boost::mutex::scoped_lock lock(mutex_);
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL(*(input), *(pcl_input));
impl_.setInputCloud(pcl_input);
impl_.setIndices(indices);
pcl::PCLPointCloud2 pcl_output;
impl_.filter(pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
inline void
filter (const PointCloud2::ConstPtr &input, const IndicesPtr &indices,
PointCloud2 &output)
{
boost::mutex::scoped_lock lock (mutex_);
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL(*(input), *(pcl_input));
impl_.setInputCloud (pcl_input);
impl_.setIndices (indices);
pcl::PCLPointCloud2 pcl_output;
impl_.filter (pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
virtual bool
child_init(ros::NodeHandle & nh, bool & has_service);
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
virtual bool
child_init (ros::NodeHandle &nh, bool &has_service);
/** \brief Dynamic reconfigure service callback. */
void
config_callback(pcl_ros::ExtractIndicesConfig & config, uint32_t level);
/** \brief Dynamic reconfigure service callback. */
void
config_callback (pcl_ros::ExtractIndicesConfig &config, uint32_t level);
private:
/** \brief The PCL filter implementation used. */
pcl::ExtractIndices<pcl::PCLPointCloud2> impl_;
private:
/** \brief The PCL filter implementation used. */
pcl::ExtractIndices<pcl::PCLPointCloud2> impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_FILTERS_EXTRACTINDICES_H_
+96 -91
View File
@@ -48,110 +48,115 @@
namespace pcl_ros
{
namespace sync_policies = message_filters::sync_policies;
namespace sync_policies = message_filters::sync_policies;
/** \brief @b Filter represents the base filter class. Some generic 3D operations that are applicable to all filters
* are defined here as static methods.
* \author Radu Bogdan Rusu
/** \brief @b Filter represents the base filter class. Some generic 3D operations that are applicable to all filters
* are defined here as static methods.
* \author Radu Bogdan Rusu
*/
class Filter : public PCLNodelet
{
public:
typedef sensor_msgs::PointCloud2 PointCloud2;
typedef pcl::IndicesPtr IndicesPtr;
typedef pcl::IndicesConstPtr IndicesConstPtr;
Filter() {}
protected:
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
message_filters::Subscriber<PointCloud2> sub_input_filter_;
/** \brief The desired user filter field name. */
std::string filter_field_name_;
/** \brief The minimum allowed filter value a point will be considered from. */
double filter_limit_min_;
/** \brief The maximum allowed filter value a point will be considered from. */
double filter_limit_max_;
/** \brief Set to true if we want to return the data outside (\a filter_limit_min_;\a filter_limit_max_). Default: false. */
bool filter_limit_negative_;
/** \brief The input TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_input_frame_;
/** \brief The original data input TF frame. */
std::string tf_input_orig_frame_;
/** \brief The output TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_output_frame_;
/** \brief Internal mutex. */
boost::mutex mutex_;
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
class Filter : public PCLNodelet
virtual bool
child_init(ros::NodeHandle & nh, bool & has_service)
{
public:
typedef sensor_msgs::PointCloud2 PointCloud2;
has_service = false;
return true;
}
typedef pcl::IndicesPtr IndicesPtr;
typedef pcl::IndicesConstPtr IndicesConstPtr;
/** \brief Virtual abstract filter method. To be implemented by every child.
* \param input the input point cloud dataset.
* \param indices a pointer to the vector of point indices to use.
* \param output the resultant filtered PointCloud2
*/
virtual void
filter(
const PointCloud2::ConstPtr & input, const IndicesPtr & indices,
PointCloud2 & output) = 0;
Filter () {}
/** \brief Lazy transport subscribe routine. */
virtual void
subscribe();
protected:
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief Lazy transport unsubscribe routine. */
virtual void
unsubscribe();
message_filters::Subscriber<PointCloud2> sub_input_filter_;
/** \brief Nodelet initialization routine. */
virtual void
onInit();
/** \brief The desired user filter field name. */
std::string filter_field_name_;
/** \brief Call the child filter () method, optionally transform the result, and publish it.
* \param input the input point cloud dataset.
* \param indices a pointer to the vector of point indices to use.
*/
void
computePublish(const PointCloud2::ConstPtr & input, const IndicesPtr & indices);
/** \brief The minimum allowed filter value a point will be considered from. */
double filter_limit_min_;
private:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<pcl_ros::FilterConfig>> srv_;
/** \brief The maximum allowed filter value a point will be considered from. */
double filter_limit_max_;
/** \brief Synchronized input, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud2,
PointIndices>>> sync_input_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud2,
PointIndices>>> sync_input_indices_a_;
/** \brief Set to true if we want to return the data outside (\a filter_limit_min_;\a filter_limit_max_). Default: false. */
bool filter_limit_negative_;
/** \brief Dynamic reconfigure service callback. */
virtual void
config_callback(pcl_ros::FilterConfig & config, uint32_t level);
/** \brief The input TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_input_frame_;
/** \brief PointCloud2 + Indices data callback. */
void
input_indices_callback(
const PointCloud2::ConstPtr & cloud,
const PointIndicesConstPtr & indices);
/** \brief The original data input TF frame. */
std::string tf_input_orig_frame_;
/** \brief The output TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_output_frame_;
/** \brief Internal mutex. */
boost::mutex mutex_;
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
virtual bool
child_init (ros::NodeHandle &nh, bool &has_service)
{
has_service = false;
return (true);
}
/** \brief Virtual abstract filter method. To be implemented by every child.
* \param input the input point cloud dataset.
* \param indices a pointer to the vector of point indices to use.
* \param output the resultant filtered PointCloud2
*/
virtual void
filter (const PointCloud2::ConstPtr &input, const IndicesPtr &indices,
PointCloud2 &output) = 0;
/** \brief Lazy transport subscribe routine. */
virtual void
subscribe();
/** \brief Lazy transport unsubscribe routine. */
virtual void
unsubscribe();
/** \brief Nodelet initialization routine. */
virtual void
onInit ();
/** \brief Call the child filter () method, optionally transform the result, and publish it.
* \param input the input point cloud dataset.
* \param indices a pointer to the vector of point indices to use.
*/
void
computePublish (const PointCloud2::ConstPtr &input, const IndicesPtr &indices);
private:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<pcl_ros::FilterConfig> > srv_;
/** \brief Synchronized input, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud2, PointIndices> > > sync_input_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud2, PointIndices> > > sync_input_indices_a_;
/** \brief Dynamic reconfigure service callback. */
virtual void
config_callback (pcl_ros::FilterConfig &config, uint32_t level);
/** \brief PointCloud2 + Indices data callback. */
void
input_indices_callback (const PointCloud2::ConstPtr &cloud,
const PointIndicesConstPtr &indices);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_FILTER_H_
+46 -44
View File
@@ -44,55 +44,57 @@
namespace pcl_ros
{
/** \brief @b PassThrough uses the base Filter class methods to pass through all data that satisfies the user given
* constraints.
* \author Radu Bogdan Rusu
/** \brief @b PassThrough uses the base Filter class methods to pass through all data that satisfies the user given
* constraints.
* \author Radu Bogdan Rusu
*/
class PassThrough : public Filter
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<pcl_ros::FilterConfig>> srv_;
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
class PassThrough : public Filter
inline void
filter(
const PointCloud2::ConstPtr & input, const IndicesPtr & indices,
PointCloud2 & output)
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr <dynamic_reconfigure::Server<pcl_ros::FilterConfig> > srv_;
boost::mutex::scoped_lock lock(mutex_);
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL(*(input), *(pcl_input));
impl_.setInputCloud(pcl_input);
impl_.setIndices(indices);
pcl::PCLPointCloud2 pcl_output;
impl_.filter(pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
inline void
filter (const PointCloud2::ConstPtr &input, const IndicesPtr &indices,
PointCloud2 &output)
{
boost::mutex::scoped_lock lock (mutex_);
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL (*(input), *(pcl_input));
impl_.setInputCloud (pcl_input);
impl_.setIndices (indices);
pcl::PCLPointCloud2 pcl_output;
impl_.filter (pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
bool
child_init(ros::NodeHandle & nh, bool & has_service);
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
bool
child_init (ros::NodeHandle &nh, bool &has_service);
/** \brief Dynamic reconfigure service callback.
* \param config the dynamic reconfigure FilterConfig object
* \param level the dynamic reconfigure level
*/
void
config_callback (pcl_ros::FilterConfig &config, uint32_t level);
/** \brief Dynamic reconfigure service callback.
* \param config the dynamic reconfigure FilterConfig object
* \param level the dynamic reconfigure level
*/
void
config_callback(pcl_ros::FilterConfig & config, uint32_t level);
private:
/** \brief The PCL filter implementation used. */
pcl::PassThrough<pcl::PCLPointCloud2> impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
private:
/** \brief The PCL filter implementation used. */
pcl::PassThrough<pcl::PCLPointCloud2> impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_FILTERS_PASSTHROUGH_H_
@@ -46,69 +46,75 @@
namespace pcl_ros
{
namespace sync_policies = message_filters::sync_policies;
namespace sync_policies = message_filters::sync_policies;
/** \brief @b ProjectInliers uses a model and a set of inlier indices from a PointCloud to project them into a
* separate PointCloud.
* \note setFilterFieldName (), setFilterLimits (), and setFilterLimitNegative () are ignored.
* \author Radu Bogdan Rusu
/** \brief @b ProjectInliers uses a model and a set of inlier indices from a PointCloud to project them into a
* separate PointCloud.
* \note setFilterFieldName (), setFilterLimits (), and setFilterLimitNegative () are ignored.
* \author Radu Bogdan Rusu
*/
class ProjectInliers : public Filter
{
public:
ProjectInliers()
: model_() {}
protected:
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
class ProjectInliers : public Filter
inline void
filter(
const PointCloud2::ConstPtr & input, const IndicesPtr & indices,
PointCloud2 & output)
{
public:
ProjectInliers () : model_ () {}
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL(*(input), *(pcl_input));
impl_.setInputCloud(pcl_input);
impl_.setIndices(indices);
pcl::ModelCoefficients::Ptr pcl_model(new pcl::ModelCoefficients);
pcl_conversions::toPCL(*(model_), *(pcl_model));
impl_.setModelCoefficients(pcl_model);
pcl::PCLPointCloud2 pcl_output;
impl_.filter(pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
protected:
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
inline void
filter (const PointCloud2::ConstPtr &input, const IndicesPtr &indices,
PointCloud2 &output)
{
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL (*(input), *(pcl_input));
impl_.setInputCloud (pcl_input);
impl_.setIndices (indices);
pcl::ModelCoefficients::Ptr pcl_model(new pcl::ModelCoefficients);
pcl_conversions::toPCL(*(model_), *(pcl_model));
impl_.setModelCoefficients (pcl_model);
pcl::PCLPointCloud2 pcl_output;
impl_.filter (pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
private:
/** \brief A pointer to the vector of model coefficients. */
ModelCoefficientsConstPtr model_;
private:
/** \brief A pointer to the vector of model coefficients. */
ModelCoefficientsConstPtr model_;
/** \brief The message filter subscriber for model coefficients. */
message_filters::Subscriber<ModelCoefficients> sub_model_;
/** \brief The message filter subscriber for model coefficients. */
message_filters::Subscriber<ModelCoefficients> sub_model_;
/** \brief Synchronized input, indices, and model coefficients.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud2,
PointIndices, ModelCoefficients>>> sync_input_indices_model_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud2,
PointIndices, ModelCoefficients>>> sync_input_indices_model_a_;
/** \brief The PCL filter implementation used. */
pcl::ProjectInliers<pcl::PCLPointCloud2> impl_;
/** \brief Synchronized input, indices, and model coefficients.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud2, PointIndices, ModelCoefficients> > > sync_input_indices_model_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud2, PointIndices, ModelCoefficients> > > sync_input_indices_model_a_;
/** \brief The PCL filter implementation used. */
pcl::ProjectInliers<pcl::PCLPointCloud2> impl_;
/** \brief Nodelet initialization routine. */
virtual void
onInit();
/** \brief Nodelet initialization routine. */
virtual void
onInit ();
/** \brief NodeletLazy connection routine. */
void subscribe();
void unsubscribe();
/** \brief NodeletLazy connection routine. */
void subscribe ();
void unsubscribe ();
/** \brief PointCloud2 + Indices + Model data callback. */
void
input_indices_model_callback(
const PointCloud2::ConstPtr & cloud,
const PointIndicesConstPtr & indices,
const ModelCoefficientsConstPtr & model);
/** \brief PointCloud2 + Indices + Model data callback. */
void
input_indices_model_callback (const PointCloud2::ConstPtr &cloud,
const PointIndicesConstPtr &indices,
const ModelCoefficientsConstPtr &model);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_FILTERS_PROJECT_INLIERS_H_
@@ -47,54 +47,55 @@
namespace pcl_ros
{
/** \brief @b RadiusOutlierRemoval is a simple filter that removes outliers if the number of neighbors in a certain
* search radius is smaller than a given K.
* \note setFilterFieldName (), setFilterLimits (), and setFilterLimitNegative () are ignored.
* \author Radu Bogdan Rusu
/** \brief @b RadiusOutlierRemoval is a simple filter that removes outliers if the number of neighbors in a certain
* search radius is smaller than a given K.
* \note setFilterFieldName (), setFilterLimits (), and setFilterLimitNegative () are ignored.
* \author Radu Bogdan Rusu
*/
class RadiusOutlierRemoval : public Filter
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<pcl_ros::RadiusOutlierRemovalConfig>> srv_;
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
class RadiusOutlierRemoval : public Filter
inline void
filter(
const PointCloud2::ConstPtr & input, const IndicesPtr & indices,
PointCloud2 & output)
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr <dynamic_reconfigure::Server<pcl_ros::RadiusOutlierRemovalConfig> > srv_;
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL(*(input), *(pcl_input));
impl_.setInputCloud(pcl_input);
impl_.setIndices(indices);
pcl::PCLPointCloud2 pcl_output;
impl_.filter(pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
inline void
filter (const PointCloud2::ConstPtr &input, const IndicesPtr &indices,
PointCloud2 &output)
{
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL (*(input), *(pcl_input));
impl_.setInputCloud (pcl_input);
impl_.setIndices (indices);
pcl::PCLPointCloud2 pcl_output;
impl_.filter (pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
virtual inline bool child_init(ros::NodeHandle & nh, bool & has_service);
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
virtual inline bool child_init (ros::NodeHandle &nh, bool &has_service);
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback(pcl_ros::RadiusOutlierRemovalConfig & config, uint32_t level);
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback (pcl_ros::RadiusOutlierRemovalConfig &config, uint32_t level);
private:
/** \brief The PCL filter implementation used. */
pcl::RadiusOutlierRemoval<pcl::PCLPointCloud2> impl_;
private:
/** \brief The PCL filter implementation used. */
pcl::RadiusOutlierRemoval<pcl::PCLPointCloud2> impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_FILTERS_RADIUSOUTLIERREMOVAL_H_
@@ -47,60 +47,62 @@
namespace pcl_ros
{
/** \brief @b StatisticalOutlierRemoval uses point neighborhood statistics to filter outlier data. For more
* information check:
* <ul>
* <li> R. B. Rusu, Z. C. Marton, N. Blodow, M. Dolha, and M. Beetz.
* Towards 3D Point Cloud Based Object Maps for Household Environments
* Robotics and Autonomous Systems Journal (Special Issue on Semantic Knowledge), 2008.
* </ul>
*
* \note setFilterFieldName (), setFilterLimits (), and setFilterLimitNegative () are ignored.
* \author Radu Bogdan Rusu
/** \brief @b StatisticalOutlierRemoval uses point neighborhood statistics to filter outlier data. For more
* information check:
* <ul>
* <li> R. B. Rusu, Z. C. Marton, N. Blodow, M. Dolha, and M. Beetz.
* Towards 3D Point Cloud Based Object Maps for Household Environments
* Robotics and Autonomous Systems Journal (Special Issue on Semantic Knowledge), 2008.
* </ul>
*
* \note setFilterFieldName (), setFilterLimits (), and setFilterLimitNegative () are ignored.
* \author Radu Bogdan Rusu
*/
class StatisticalOutlierRemoval : public Filter
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<pcl_ros::StatisticalOutlierRemovalConfig>> srv_;
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
class StatisticalOutlierRemoval : public Filter
inline void
filter(
const PointCloud2::ConstPtr & input, const IndicesPtr & indices,
PointCloud2 & output)
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr <dynamic_reconfigure::Server<pcl_ros::StatisticalOutlierRemovalConfig> > srv_;
boost::mutex::scoped_lock lock(mutex_);
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL(*(input), *(pcl_input));
impl_.setInputCloud(pcl_input);
impl_.setIndices(indices);
pcl::PCLPointCloud2 pcl_output;
impl_.filter(pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
inline void
filter (const PointCloud2::ConstPtr &input, const IndicesPtr &indices,
PointCloud2 &output)
{
boost::mutex::scoped_lock lock (mutex_);
pcl::PCLPointCloud2::Ptr pcl_input(new pcl::PCLPointCloud2);
pcl_conversions::toPCL(*(input), *(pcl_input));
impl_.setInputCloud (pcl_input);
impl_.setIndices (indices);
pcl::PCLPointCloud2 pcl_output;
impl_.filter (pcl_output);
pcl_conversions::moveFromPCL(pcl_output, output);
}
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
bool child_init(ros::NodeHandle & nh, bool & has_service);
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
bool child_init (ros::NodeHandle &nh, bool &has_service);
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback(pcl_ros::StatisticalOutlierRemovalConfig & config, uint32_t level);
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback (pcl_ros::StatisticalOutlierRemovalConfig &config, uint32_t level);
private:
/** \brief The PCL filter implementation used. */
pcl::StatisticalOutlierRemoval<pcl::PCLPointCloud2> impl_;
private:
/** \brief The PCL filter implementation used. */
pcl::StatisticalOutlierRemoval<pcl::PCLPointCloud2> impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_FILTERS_STATISTICALOUTLIERREMOVAL_H_
+35 -33
View File
@@ -47,43 +47,45 @@
namespace pcl_ros
{
/** \brief @b VoxelGrid assembles a local 3D grid over a given PointCloud, and downsamples + filters the data.
* \author Radu Bogdan Rusu
/** \brief @b VoxelGrid assembles a local 3D grid over a given PointCloud, and downsamples + filters the data.
* \author Radu Bogdan Rusu
*/
class VoxelGrid : public Filter
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<pcl_ros::VoxelGridConfig>> srv_;
/** \brief The PCL filter implementation used. */
pcl::VoxelGrid<pcl::PCLPointCloud2> impl_;
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
class VoxelGrid : public Filter
{
protected:
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr <dynamic_reconfigure::Server<pcl_ros::VoxelGridConfig> > srv_;
virtual void
filter(
const PointCloud2::ConstPtr & input, const IndicesPtr & indices,
PointCloud2 & output);
/** \brief The PCL filter implementation used. */
pcl::VoxelGrid<pcl::PCLPointCloud2> impl_;
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
bool
child_init(ros::NodeHandle & nh, bool & has_service);
/** \brief Call the actual filter.
* \param input the input point cloud dataset
* \param indices the input set of indices to use from \a input
* \param output the resultant filtered dataset
*/
virtual void
filter (const PointCloud2::ConstPtr &input, const IndicesPtr &indices,
PointCloud2 &output);
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void
config_callback(pcl_ros::VoxelGridConfig & config, uint32_t level);
/** \brief Child initialization routine.
* \param nh ROS node handle
* \param has_service set to true if the child has a Dynamic Reconfigure service
*/
bool
child_init (ros::NodeHandle &nh, bool &has_service);
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void
config_callback (pcl_ros::VoxelGridConfig &config, uint32_t level);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_FILTERS_VOXEL_H_
+104 -106
View File
@@ -46,178 +46,176 @@ using pcl_conversions::toPCL;
namespace pcl_ros
{
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
transformPointCloudWithNormals (const pcl::PointCloud <PointT> &cloud_in,
pcl::PointCloud <PointT> &cloud_out, const tf::Transform &transform)
template<typename PointT>
void
transformPointCloudWithNormals(
const pcl::PointCloud<PointT> & cloud_in,
pcl::PointCloud<PointT> & cloud_out, const tf::Transform & transform)
{
// Bullet (used by tf) and Eigen both store quaternions in x,y,z,w order, despite the ordering
// of arguments in Eigen's constructor. We could use an Eigen Map to convert without copy, but
// this only works if Bullet uses floats, that is if BT_USE_DOUBLE_PRECISION is not defined.
// Rather that risking a mistake, we copy the quaternion, which is a small cost compared to
// the conversion of the point cloud anyway. Idem for the origin.
tf::Quaternion q = transform.getRotation ();
Eigen::Quaternionf rotation (q.w (), q.x (), q.y (), q.z ()); // internally stored as (x,y,z,w)
tf::Vector3 v = transform.getOrigin ();
Eigen::Vector3f origin (v.x (), v.y (), v.z ());
tf::Quaternion q = transform.getRotation();
Eigen::Quaternionf rotation(q.w(), q.x(), q.y(), q.z()); // internally stored as (x,y,z,w)
tf::Vector3 v = transform.getOrigin();
Eigen::Vector3f origin(v.x(), v.y(), v.z());
// Eigen::Translation3f translation(v);
// Assemble an Eigen Transform
//Eigen::Transform3f t;
//t = translation * rotation;
transformPointCloudWithNormals (cloud_in, cloud_out, origin, rotation);
transformPointCloudWithNormals(cloud_in, cloud_out, origin, rotation);
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
transformPointCloud (const pcl::PointCloud <PointT> &cloud_in,
pcl::PointCloud <PointT> &cloud_out, const tf::Transform &transform)
template<typename PointT>
void
transformPointCloud(
const pcl::PointCloud<PointT> & cloud_in,
pcl::PointCloud<PointT> & cloud_out, const tf::Transform & transform)
{
// Bullet (used by tf) and Eigen both store quaternions in x,y,z,w order, despite the ordering
// of arguments in Eigen's constructor. We could use an Eigen Map to convert without copy, but
// this only works if Bullet uses floats, that is if BT_USE_DOUBLE_PRECISION is not defined.
// Rather that risking a mistake, we copy the quaternion, which is a small cost compared to
// the conversion of the point cloud anyway. Idem for the origin.
tf::Quaternion q = transform.getRotation ();
Eigen::Quaternionf rotation (q.w (), q.x (), q.y (), q.z ()); // internally stored as (x,y,z,w)
tf::Vector3 v = transform.getOrigin ();
Eigen::Vector3f origin (v.x (), v.y (), v.z ());
tf::Quaternion q = transform.getRotation();
Eigen::Quaternionf rotation(q.w(), q.x(), q.y(), q.z()); // internally stored as (x,y,z,w)
tf::Vector3 v = transform.getOrigin();
Eigen::Vector3f origin(v.x(), v.y(), v.z());
// Eigen::Translation3f translation(v);
// Assemble an Eigen Transform
//Eigen::Transform3f t;
//t = translation * rotation;
transformPointCloud (cloud_in, cloud_out, origin, rotation);
transformPointCloud(cloud_in, cloud_out, origin, rotation);
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
transformPointCloudWithNormals (const std::string &target_frame,
const pcl::PointCloud <PointT> &cloud_in,
pcl::PointCloud <PointT> &cloud_out,
const tf::TransformListener &tf_listener)
template<typename PointT>
bool
transformPointCloudWithNormals(
const std::string & target_frame,
const pcl::PointCloud<PointT> & cloud_in,
pcl::PointCloud<PointT> & cloud_out,
const tf::TransformListener & tf_listener)
{
if (cloud_in.header.frame_id == target_frame)
{
if (cloud_in.header.frame_id == target_frame) {
cloud_out = cloud_in;
return (true);
return true;
}
tf::StampedTransform transform;
try
{
tf_listener.lookupTransform (target_frame, cloud_in.header.frame_id, fromPCL(cloud_in.header).stamp, transform);
}
catch (tf::LookupException &e)
{
ROS_ERROR ("%s", e.what ());
return (false);
}
catch (tf::ExtrapolationException &e)
{
ROS_ERROR ("%s", e.what ());
return (false);
try {
tf_listener.lookupTransform(
target_frame, cloud_in.header.frame_id, fromPCL(
cloud_in.header).stamp, transform);
} catch (tf::LookupException & e) {
ROS_ERROR("%s", e.what());
return false;
} catch (tf::ExtrapolationException & e) {
ROS_ERROR("%s", e.what());
return false;
}
transformPointCloudWithNormals (cloud_in, cloud_out, transform);
transformPointCloudWithNormals(cloud_in, cloud_out, transform);
cloud_out.header.frame_id = target_frame;
return (true);
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
transformPointCloud (const std::string &target_frame,
const pcl::PointCloud <PointT> &cloud_in,
pcl::PointCloud <PointT> &cloud_out,
const tf::TransformListener &tf_listener)
template<typename PointT>
bool
transformPointCloud(
const std::string & target_frame,
const pcl::PointCloud<PointT> & cloud_in,
pcl::PointCloud<PointT> & cloud_out,
const tf::TransformListener & tf_listener)
{
if (cloud_in.header.frame_id == target_frame)
{
if (cloud_in.header.frame_id == target_frame) {
cloud_out = cloud_in;
return (true);
return true;
}
tf::StampedTransform transform;
try
{
tf_listener.lookupTransform (target_frame, cloud_in.header.frame_id, fromPCL(cloud_in.header).stamp, transform);
try {
tf_listener.lookupTransform(
target_frame, cloud_in.header.frame_id, fromPCL(
cloud_in.header).stamp, transform);
} catch (tf::LookupException & e) {
ROS_ERROR("%s", e.what());
return false;
} catch (tf::ExtrapolationException & e) {
ROS_ERROR("%s", e.what());
return false;
}
catch (tf::LookupException &e)
{
ROS_ERROR ("%s", e.what ());
return (false);
}
catch (tf::ExtrapolationException &e)
{
ROS_ERROR ("%s", e.what ());
return (false);
}
transformPointCloud (cloud_in, cloud_out, transform);
transformPointCloud(cloud_in, cloud_out, transform);
cloud_out.header.frame_id = target_frame;
return (true);
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
transformPointCloud (const std::string &target_frame,
const ros::Time & target_time,
const pcl::PointCloud <PointT> &cloud_in,
const std::string &fixed_frame,
pcl::PointCloud <PointT> &cloud_out,
const tf::TransformListener &tf_listener)
template<typename PointT>
bool
transformPointCloud(
const std::string & target_frame,
const ros::Time & target_time,
const pcl::PointCloud<PointT> & cloud_in,
const std::string & fixed_frame,
pcl::PointCloud<PointT> & cloud_out,
const tf::TransformListener & tf_listener)
{
tf::StampedTransform transform;
try
{
tf_listener.lookupTransform (target_frame, target_time, cloud_in.header.frame_id, fromPCL(cloud_in.header).stamp, fixed_frame, transform);
}
catch (tf::LookupException &e)
{
ROS_ERROR ("%s", e.what ());
return (false);
}
catch (tf::ExtrapolationException &e)
{
ROS_ERROR ("%s", e.what ());
return (false);
try {
tf_listener.lookupTransform(
target_frame, target_time, cloud_in.header.frame_id,
fromPCL(cloud_in.header).stamp, fixed_frame, transform);
} catch (tf::LookupException & e) {
ROS_ERROR("%s", e.what());
return false;
} catch (tf::ExtrapolationException & e) {
ROS_ERROR("%s", e.what());
return false;
}
transformPointCloud (cloud_in, cloud_out, transform);
transformPointCloud(cloud_in, cloud_out, transform);
cloud_out.header.frame_id = target_frame;
std_msgs::Header header;
header.stamp = target_time;
cloud_out.header = toPCL(header);
return (true);
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
transformPointCloudWithNormals (const std::string &target_frame,
const ros::Time & target_time,
const pcl::PointCloud <PointT> &cloud_in,
const std::string &fixed_frame,
pcl::PointCloud <PointT> &cloud_out,
const tf::TransformListener &tf_listener)
template<typename PointT>
bool
transformPointCloudWithNormals(
const std::string & target_frame,
const ros::Time & target_time,
const pcl::PointCloud<PointT> & cloud_in,
const std::string & fixed_frame,
pcl::PointCloud<PointT> & cloud_out,
const tf::TransformListener & tf_listener)
{
tf::StampedTransform transform;
try
{
tf_listener.lookupTransform (target_frame, target_time, cloud_in.header.frame_id, fromPCL(cloud_in.header).stamp, fixed_frame, transform);
}
catch (tf::LookupException &e)
{
ROS_ERROR ("%s", e.what ());
return (false);
}
catch (tf::ExtrapolationException &e)
{
ROS_ERROR ("%s", e.what ());
return (false);
try {
tf_listener.lookupTransform(
target_frame, target_time, cloud_in.header.frame_id,
fromPCL(cloud_in.header).stamp, fixed_frame, transform);
} catch (tf::LookupException & e) {
ROS_ERROR("%s", e.what());
return false;
} catch (tf::ExtrapolationException & e) {
ROS_ERROR("%s", e.what());
return false;
}
transformPointCloudWithNormals (cloud_in, cloud_out, transform);
transformPointCloudWithNormals(cloud_in, cloud_out, transform);
cloud_out.header.frame_id = target_frame;
std_msgs::Header header;
header.stamp = target_time;
cloud_out.header = toPCL(header);
return (true);
return true;
}
} // namespace pcl_ros
+66 -65
View File
@@ -45,85 +45,86 @@
namespace pcl_ros
{
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief BAG PointCloud file format reader.
* \author Radu Bogdan Rusu
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief BAG PointCloud file format reader.
* \author Radu Bogdan Rusu
*/
class BAGReader : public nodelet::Nodelet
{
public:
typedef sensor_msgs::PointCloud2 PointCloud;
typedef PointCloud::Ptr PointCloudPtr;
typedef PointCloud::ConstPtr PointCloudConstPtr;
/** \brief Empty constructor. */
BAGReader()
: publish_rate_(0), output_() /*, cloud_received_ (false)*/ {}
/** \brief Set the publishing rate in seconds.
* \param publish_rate the publishing rate in seconds
*/
class BAGReader: public nodelet::Nodelet
inline void setPublishRate(double publish_rate) {publish_rate_ = publish_rate;}
/** \brief Get the publishing rate in seconds. */
inline double getPublishRate() {return publish_rate_;}
/** \brief Get the next point cloud dataset in the BAG file.
* \return the next point cloud dataset as read from the file
*/
inline PointCloudConstPtr
getNextCloud()
{
public:
typedef sensor_msgs::PointCloud2 PointCloud;
typedef PointCloud::Ptr PointCloudPtr;
typedef PointCloud::ConstPtr PointCloudConstPtr;
if (it_ != view_.end()) {
output_ = it_->instantiate<sensor_msgs::PointCloud2>();
++it_;
}
return output_;
}
/** \brief Empty constructor. */
BAGReader () : publish_rate_ (0), output_ ()/*, cloud_received_ (false)*/ {};
/** \brief Open a BAG file for reading and select a specified topic
* \param file_name the BAG file to open
* \param topic_name the topic that we want to read data from
*/
bool open(const std::string & file_name, const std::string & topic_name);
/** \brief Set the publishing rate in seconds.
* \param publish_rate the publishing rate in seconds
*/
inline void setPublishRate (double publish_rate) { publish_rate_ = publish_rate; }
/** \brief Close an open BAG file. */
inline void
close()
{
bag_.close();
}
/** \brief Get the publishing rate in seconds. */
inline double getPublishRate () { return (publish_rate_); }
/** \brief Nodelet initialization routine. */
virtual void onInit();
/** \brief Get the next point cloud dataset in the BAG file.
* \return the next point cloud dataset as read from the file
*/
inline PointCloudConstPtr
getNextCloud ()
{
if (it_ != view_.end ())
{
output_ = it_->instantiate<sensor_msgs::PointCloud2> ();
++it_;
}
return (output_);
}
private:
/** \brief The publishing interval in seconds. Set to 0 to publish once (default). */
double publish_rate_;
/** \brief Open a BAG file for reading and select a specified topic
* \param file_name the BAG file to open
* \param topic_name the topic that we want to read data from
*/
bool open (const std::string &file_name, const std::string &topic_name);
/** \brief The BAG object. */
rosbag::Bag bag_;
/** \brief Close an open BAG file. */
inline void
close ()
{
bag_.close ();
}
/** \brief The BAG view object. */
rosbag::View view_;
/** \brief Nodelet initialization routine. */
virtual void onInit ();
/** \brief The BAG view iterator object. */
rosbag::View::iterator it_;
private:
/** \brief The publishing interval in seconds. Set to 0 to publish once (default). */
double publish_rate_;
/** \brief The name of the topic that contains the PointCloud data. */
std::string topic_name_;
/** \brief The BAG object. */
rosbag::Bag bag_;
/** \brief The name of the BAG file that contains the PointCloud data. */
std::string file_name_;
/** \brief The BAG view object. */
rosbag::View view_;
/** \brief The output point cloud dataset containing the points loaded from the file. */
PointCloudPtr output_;
/** \brief The BAG view iterator object. */
rosbag::View::iterator it_;
/** \brief Signals that a new PointCloud2 message has been read from the file. */
//bool cloud_received_;
/** \brief The name of the topic that contains the PointCloud data. */
std::string topic_name_;
/** \brief The name of the BAG file that contains the PointCloud data. */
std::string file_name_;
/** \brief The output point cloud dataset containing the points loaded from the file. */
PointCloudPtr output_;
/** \brief Signals that a new PointCloud2 message has been read from the file. */
//bool cloud_received_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
+83 -77
View File
@@ -49,88 +49,94 @@
namespace pcl_ros
{
namespace sync_policies = message_filters::sync_policies;
namespace sync_policies = message_filters::sync_policies;
/** \brief @b PointCloudConcatenateFieldsSynchronizer is a special form of data
* synchronizer: it listens for a set of input PointCloud messages on the same topic,
* checks their timestamps, and concatenates their fields together into a single
* PointCloud output message.
* \author Radu Bogdan Rusu
/** \brief @b PointCloudConcatenateFieldsSynchronizer is a special form of data
* synchronizer: it listens for a set of input PointCloud messages on the same topic,
* checks their timestamps, and concatenates their fields together into a single
* PointCloud output message.
* \author Radu Bogdan Rusu
*/
class PointCloudConcatenateDataSynchronizer : public nodelet_topic_tools::NodeletLazy
{
public:
typedef sensor_msgs::PointCloud2 PointCloud2;
typedef PointCloud2::Ptr PointCloud2Ptr;
typedef PointCloud2::ConstPtr PointCloud2ConstPtr;
/** \brief Empty constructor. */
PointCloudConcatenateDataSynchronizer()
: maximum_queue_size_(3) {}
/** \brief Empty constructor.
* \param queue_size the maximum queue size
*/
class PointCloudConcatenateDataSynchronizer: public nodelet_topic_tools::NodeletLazy
PointCloudConcatenateDataSynchronizer(int queue_size)
: maximum_queue_size_(queue_size), approximate_sync_(false) {}
/** \brief Empty destructor. */
virtual ~PointCloudConcatenateDataSynchronizer() {}
void onInit();
void subscribe();
void unsubscribe();
private:
/** \brief The output PointCloud publisher. */
ros::Publisher pub_output_;
/** \brief The maximum number of messages that we can store in the queue. */
int maximum_queue_size_;
/** \brief True if we use an approximate time synchronizer versus an exact one (false by default). */
bool approximate_sync_;
/** \brief A vector of message filters. */
std::vector<boost::shared_ptr<message_filters::Subscriber<PointCloud2>>> filters_;
/** \brief Output TF frame the concatenated points should be transformed to. */
std::string output_frame_;
/** \brief Input point cloud topics. */
XmlRpc::XmlRpcValue input_topics_;
/** \brief TF listener object. */
tf::TransformListener tf_;
/** \brief Null passthrough filter, used for pushing empty elements in the
* synchronizer */
message_filters::PassThrough<PointCloud2> nf_;
/** \brief Synchronizer.
* \note This will most likely be rewritten soon using the DynamicTimeSynchronizer.
*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud2,
PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2,
PointCloud2>>> ts_a_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud2, PointCloud2,
PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2>>> ts_e_;
/** \brief Input point cloud callback.
* Because we want to use the same synchronizer object, we push back
* empty elements with the same timestamp.
*/
inline void
input_callback(const PointCloud2ConstPtr & input)
{
public:
typedef sensor_msgs::PointCloud2 PointCloud2;
typedef PointCloud2::Ptr PointCloud2Ptr;
typedef PointCloud2::ConstPtr PointCloud2ConstPtr;
PointCloud2 cloud;
cloud.header.stamp = input->header.stamp;
nf_.add(boost::make_shared<PointCloud2>(cloud));
}
/** \brief Empty constructor. */
PointCloudConcatenateDataSynchronizer () : maximum_queue_size_ (3) {};
/** \brief Input callback for 8 synchronized topics. */
void input(
const PointCloud2::ConstPtr & in1, const PointCloud2::ConstPtr & in2,
const PointCloud2::ConstPtr & in3, const PointCloud2::ConstPtr & in4,
const PointCloud2::ConstPtr & in5, const PointCloud2::ConstPtr & in6,
const PointCloud2::ConstPtr & in7, const PointCloud2::ConstPtr & in8);
/** \brief Empty constructor.
* \param queue_size the maximum queue size
*/
PointCloudConcatenateDataSynchronizer (int queue_size) : maximum_queue_size_(queue_size), approximate_sync_(false) {};
/** \brief Empty destructor. */
virtual ~PointCloudConcatenateDataSynchronizer () {};
void onInit ();
void subscribe ();
void unsubscribe ();
private:
/** \brief The output PointCloud publisher. */
ros::Publisher pub_output_;
/** \brief The maximum number of messages that we can store in the queue. */
int maximum_queue_size_;
/** \brief True if we use an approximate time synchronizer versus an exact one (false by default). */
bool approximate_sync_;
/** \brief A vector of message filters. */
std::vector<boost::shared_ptr<message_filters::Subscriber<PointCloud2> > > filters_;
/** \brief Output TF frame the concatenated points should be transformed to. */
std::string output_frame_;
/** \brief Input point cloud topics. */
XmlRpc::XmlRpcValue input_topics_;
/** \brief TF listener object. */
tf::TransformListener tf_;
/** \brief Null passthrough filter, used for pushing empty elements in the
* synchronizer */
message_filters::PassThrough<PointCloud2> nf_;
/** \brief Synchronizer.
* \note This will most likely be rewritten soon using the DynamicTimeSynchronizer.
*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2> > > ts_a_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2, PointCloud2> > > ts_e_;
/** \brief Input point cloud callback.
* Because we want to use the same synchronizer object, we push back
* empty elements with the same timestamp.
*/
inline void
input_callback (const PointCloud2ConstPtr &input)
{
PointCloud2 cloud;
cloud.header.stamp = input->header.stamp;
nf_.add (boost::make_shared<PointCloud2> (cloud));
}
/** \brief Input callback for 8 synchronized topics. */
void input (const PointCloud2::ConstPtr &in1, const PointCloud2::ConstPtr &in2,
const PointCloud2::ConstPtr &in3, const PointCloud2::ConstPtr &in4,
const PointCloud2::ConstPtr &in5, const PointCloud2::ConstPtr &in6,
const PointCloud2::ConstPtr &in7, const PointCloud2::ConstPtr &in8);
void combineClouds (const PointCloud2 &in1, const PointCloud2 &in2, PointCloud2 &out);
};
void combineClouds(const PointCloud2 & in1, const PointCloud2 & in2, PointCloud2 & out);
};
}
#endif //#ifndef PCL_ROS_IO_CONCATENATE_H_
@@ -49,53 +49,55 @@
namespace pcl_ros
{
/** \brief @b PointCloudConcatenateFieldsSynchronizer is a special form of data synchronizer: it listens for a set of
* input PointCloud messages on the same topic, checks their timestamps, and concatenates their fields together into
* a single PointCloud output message.
* \author Radu Bogdan Rusu
/** \brief @b PointCloudConcatenateFieldsSynchronizer is a special form of data synchronizer: it listens for a set of
* input PointCloud messages on the same topic, checks their timestamps, and concatenates their fields together into
* a single PointCloud output message.
* \author Radu Bogdan Rusu
*/
class PointCloudConcatenateFieldsSynchronizer : public nodelet_topic_tools::NodeletLazy
{
public:
typedef sensor_msgs::PointCloud2 PointCloud;
typedef PointCloud::Ptr PointCloudPtr;
typedef PointCloud::ConstPtr PointCloudConstPtr;
/** \brief Empty constructor. */
PointCloudConcatenateFieldsSynchronizer()
: maximum_queue_size_(3), maximum_seconds_(0) {}
/** \brief Empty constructor.
* \param queue_size the maximum queue size
*/
class PointCloudConcatenateFieldsSynchronizer: public nodelet_topic_tools::NodeletLazy
{
public:
typedef sensor_msgs::PointCloud2 PointCloud;
typedef PointCloud::Ptr PointCloudPtr;
typedef PointCloud::ConstPtr PointCloudConstPtr;
PointCloudConcatenateFieldsSynchronizer(int queue_size)
: maximum_queue_size_(queue_size), maximum_seconds_(0) {}
/** \brief Empty constructor. */
PointCloudConcatenateFieldsSynchronizer () : maximum_queue_size_ (3), maximum_seconds_ (0) {};
/** \brief Empty destructor. */
virtual ~PointCloudConcatenateFieldsSynchronizer() {}
/** \brief Empty constructor.
* \param queue_size the maximum queue size
*/
PointCloudConcatenateFieldsSynchronizer (int queue_size) : maximum_queue_size_ (queue_size), maximum_seconds_ (0) {};
void onInit();
void subscribe();
void unsubscribe();
void input_callback(const PointCloudConstPtr & cloud);
/** \brief Empty destructor. */
virtual ~PointCloudConcatenateFieldsSynchronizer () {};
private:
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
void onInit ();
void subscribe ();
void unsubscribe ();
void input_callback (const PointCloudConstPtr &cloud);
/** \brief The output PointCloud publisher. */
ros::Publisher pub_output_;
private:
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief The number of input messages that we expect on the input topic. */
int input_messages_;
/** \brief The output PointCloud publisher. */
ros::Publisher pub_output_;
/** \brief The maximum number of messages that we can store in the queue. */
int maximum_queue_size_;
/** \brief The number of input messages that we expect on the input topic. */
int input_messages_;
/** \brief The maximum number of seconds to wait until we drop the synchronization. */
double maximum_seconds_;
/** \brief The maximum number of messages that we can store in the queue. */
int maximum_queue_size_;
/** \brief The maximum number of seconds to wait until we drop the synchronization. */
double maximum_seconds_;
/** \brief A queue for messages. */
std::map<ros::Time, std::vector<PointCloudConstPtr> > queue_;
};
/** \brief A queue for messages. */
std::map<ros::Time, std::vector<PointCloudConstPtr>> queue_;
};
}
#endif //#ifndef PCL_IO_CONCATENATE_H_
+78 -74
View File
@@ -43,90 +43,94 @@
namespace pcl_ros
{
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** \brief Point Cloud Data (PCD) file format reader.
* \author Radu Bogdan Rusu
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** \brief Point Cloud Data (PCD) file format reader.
* \author Radu Bogdan Rusu
*/
class PCDReader : public PCLNodelet
{
public:
typedef sensor_msgs::PointCloud2 PointCloud2;
typedef PointCloud2::Ptr PointCloud2Ptr;
typedef PointCloud2::ConstPtr PointCloud2ConstPtr;
/** \brief Empty constructor. */
PCDReader()
: publish_rate_(0), tf_frame_("/base_link") {}
virtual void onInit();
/** \brief Set the publishing rate in seconds.
* \param publish_rate the publishing rate in seconds
*/
class PCDReader : public PCLNodelet
{
public:
typedef sensor_msgs::PointCloud2 PointCloud2;
typedef PointCloud2::Ptr PointCloud2Ptr;
typedef PointCloud2::ConstPtr PointCloud2ConstPtr;
inline void setPublishRate(double publish_rate) {publish_rate_ = publish_rate;}
/** \brief Empty constructor. */
PCDReader () : publish_rate_ (0), tf_frame_ ("/base_link") {};
/** \brief Get the publishing rate in seconds. */
inline double getPublishRate() {return publish_rate_;}
virtual void onInit ();
/** \brief Set the publishing rate in seconds.
* \param publish_rate the publishing rate in seconds
*/
inline void setPublishRate (double publish_rate) { publish_rate_ = publish_rate; }
/** \brief Get the publishing rate in seconds. */
inline double getPublishRate () { return (publish_rate_); }
/** \brief Set the TF frame the PointCloud will be published in.
* \param tf_frame the TF frame the PointCloud will be published in
*/
inline void setTFframe (std::string tf_frame) { tf_frame_ = tf_frame; }
/** \brief Get the TF frame the PointCloud is published in. */
inline std::string getTFframe () { return (tf_frame_); }
protected:
/** \brief The publishing interval in seconds. Set to 0 to only publish once (default). */
double publish_rate_;
/** \brief The TF frame the data should be published in ("/base_link" by default). */
std::string tf_frame_;
/** \brief The name of the file that contains the PointCloud data. */
std::string file_name_;
/** \brief The output point cloud dataset containing the points loaded from the file. */
PointCloud2Ptr output_;
private:
/** \brief The PCL implementation used. */
pcl::PCDReader impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** \brief Point Cloud Data (PCD) file format writer.
* \author Radu Bogdan Rusu
/** \brief Set the TF frame the PointCloud will be published in.
* \param tf_frame the TF frame the PointCloud will be published in
*/
class PCDWriter : public PCLNodelet
{
public:
PCDWriter () : file_name_ (""), binary_mode_ (true) {}
inline void setTFframe(std::string tf_frame) {tf_frame_ = tf_frame;}
typedef sensor_msgs::PointCloud2 PointCloud2;
typedef PointCloud2::Ptr PointCloud2Ptr;
typedef PointCloud2::ConstPtr PointCloud2ConstPtr;
/** \brief Get the TF frame the PointCloud is published in. */
inline std::string getTFframe() {return tf_frame_;}
virtual void onInit ();
void input_callback (const PointCloud2ConstPtr &cloud);
protected:
/** \brief The publishing interval in seconds. Set to 0 to only publish once (default). */
double publish_rate_;
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief The TF frame the data should be published in ("/base_link" by default). */
std::string tf_frame_;
protected:
/** \brief The name of the file that contains the PointCloud data. */
std::string file_name_;
/** \brief The name of the file that contains the PointCloud data. */
std::string file_name_;
/** \brief Set to true if the output files should be saved in binary mode (true). */
bool binary_mode_;
/** \brief The output point cloud dataset containing the points loaded from the file. */
PointCloud2Ptr output_;
private:
/** \brief The PCL implementation used. */
pcl::PCDWriter impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
private:
/** \brief The PCL implementation used. */
pcl::PCDReader impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** \brief Point Cloud Data (PCD) file format writer.
* \author Radu Bogdan Rusu
*/
class PCDWriter : public PCLNodelet
{
public:
PCDWriter()
: file_name_(""), binary_mode_(true) {}
typedef sensor_msgs::PointCloud2 PointCloud2;
typedef PointCloud2::Ptr PointCloud2Ptr;
typedef PointCloud2::ConstPtr PointCloud2ConstPtr;
virtual void onInit();
void input_callback(const PointCloud2ConstPtr & cloud);
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
protected:
/** \brief The name of the file that contains the PointCloud data. */
std::string file_name_;
/** \brief Set to true if the output files should be saved in binary mode (true). */
bool binary_mode_;
private:
/** \brief The PCL implementation used. */
pcl::PCDWriter impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_IO_PCD_IO_H_
+159 -150
View File
@@ -66,168 +66,177 @@ using pcl_conversions::fromPCL;
namespace pcl_ros
{
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b PCLNodelet represents the base PCL Nodelet class. All PCL nodelets should inherit from this class. */
class PCLNodelet : public nodelet_topic_tools::NodeletLazy
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b PCLNodelet represents the base PCL Nodelet class. All PCL nodelets should inherit from this class. */
class PCLNodelet : public nodelet_topic_tools::NodeletLazy
{
public:
typedef sensor_msgs::PointCloud2 PointCloud2;
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
typedef pcl_msgs::PointIndices PointIndices;
typedef PointIndices::Ptr PointIndicesPtr;
typedef PointIndices::ConstPtr PointIndicesConstPtr;
typedef pcl_msgs::ModelCoefficients ModelCoefficients;
typedef ModelCoefficients::Ptr ModelCoefficientsPtr;
typedef ModelCoefficients::ConstPtr ModelCoefficientsConstPtr;
typedef pcl::IndicesPtr IndicesPtr;
typedef pcl::IndicesConstPtr IndicesConstPtr;
/** \brief Empty constructor. */
PCLNodelet()
: use_indices_(false), latched_indices_(false),
max_queue_size_(3), approximate_sync_(false) {}
protected:
/** \brief Set to true if point indices are used.
*
* When receiving a point cloud, if use_indices_ is false, the entire
* point cloud is processed for the given operation. If use_indices_ is
* true, then the ~indices topic is read to get the vector of point
* indices specifying the subset of the point cloud that will be used for
* the operation. In the case where use_indices_ is true, the ~input and
* ~indices topics must be synchronised in time, either exact or within a
* specified jitter. See also @ref latched_indices_ and approximate_sync.
**/
bool use_indices_;
/** \brief Set to true if the indices topic is latched.
*
* If use_indices_ is true, the ~input and ~indices topics generally must
* be synchronised in time. By setting this flag to true, the most recent
* value from ~indices can be used instead of requiring a synchronised
* message.
**/
bool latched_indices_;
/** \brief The message filter subscriber for PointCloud2. */
message_filters::Subscriber<PointCloud> sub_input_filter_;
/** \brief The message filter subscriber for PointIndices. */
message_filters::Subscriber<PointIndices> sub_indices_filter_;
/** \brief The output PointCloud publisher. */
ros::Publisher pub_output_;
/** \brief The maximum queue size (default: 3). */
int max_queue_size_;
/** \brief True if we use an approximate time synchronizer versus an exact one (false by default). */
bool approximate_sync_;
/** \brief TF listener object. */
tf::TransformListener tf_listener_;
/** \brief Test whether a given PointCloud message is "valid" (i.e., has points, and width and height are non-zero).
* \param cloud the point cloud to test
* \param topic_name an optional topic name (only used for printing, defaults to "input")
*/
inline bool
isValid(const PointCloud2::ConstPtr & cloud, const std::string & topic_name = "input")
{
public:
typedef sensor_msgs::PointCloud2 PointCloud2;
if (cloud->width * cloud->height * cloud->point_step != cloud->data.size()) {
NODELET_WARN(
"[%s] Invalid PointCloud (data = %zu, width = %d, height = %d, step = %d) with stamp %f, and frame %s on topic %s received!",
getName().c_str(),
cloud->data.size(), cloud->width, cloud->height, cloud->point_step,
cloud->header.stamp.toSec(), cloud->header.frame_id.c_str(), pnh_->resolveName(
topic_name).c_str());
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
return false;
}
return true;
}
typedef pcl_msgs::PointIndices PointIndices;
typedef PointIndices::Ptr PointIndicesPtr;
typedef PointIndices::ConstPtr PointIndicesConstPtr;
/** \brief Test whether a given PointCloud message is "valid" (i.e., has points, and width and height are non-zero).
* \param cloud the point cloud to test
* \param topic_name an optional topic name (only used for printing, defaults to "input")
*/
inline bool
isValid(const PointCloudConstPtr & cloud, const std::string & topic_name = "input")
{
if (cloud->width * cloud->height != cloud->points.size()) {
NODELET_WARN(
"[%s] Invalid PointCloud (points = %zu, width = %d, height = %d) with stamp %f, and frame %s on topic %s received!",
getName().c_str(), cloud->points.size(), cloud->width, cloud->height,
fromPCL(cloud->header).stamp.toSec(), cloud->header.frame_id.c_str(),
pnh_->resolveName(topic_name).c_str());
typedef pcl_msgs::ModelCoefficients ModelCoefficients;
typedef ModelCoefficients::Ptr ModelCoefficientsPtr;
typedef ModelCoefficients::ConstPtr ModelCoefficientsConstPtr;
return false;
}
return true;
}
typedef pcl::IndicesPtr IndicesPtr;
typedef pcl::IndicesConstPtr IndicesConstPtr;
/** \brief Test whether a given PointIndices message is "valid" (i.e., has values).
* \param indices the point indices message to test
* \param topic_name an optional topic name (only used for printing, defaults to "indices")
*/
inline bool
isValid(const PointIndicesConstPtr & indices, const std::string & topic_name = "indices")
{
/*if (indices->indices.empty ())
{
NODELET_WARN ("[%s] Empty indices (values = %zu) with stamp %f, and frame %s on topic %s received!", getName ().c_str (), indices->indices.size (), indices->header.stamp.toSec (), indices->header.frame_id.c_str (), pnh_->resolveName (topic_name).c_str ());
return (true);
}*/
return true;
}
/** \brief Empty constructor. */
PCLNodelet () : use_indices_ (false), latched_indices_ (false),
max_queue_size_ (3), approximate_sync_ (false) {};
/** \brief Test whether a given ModelCoefficients message is "valid" (i.e., has values).
* \param model the model coefficients to test
* \param topic_name an optional topic name (only used for printing, defaults to "model")
*/
inline bool
isValid(const ModelCoefficientsConstPtr & model, const std::string & topic_name = "model")
{
/*if (model->values.empty ())
{
NODELET_WARN ("[%s] Empty model (values = %zu) with stamp %f, and frame %s on topic %s received!", getName ().c_str (), model->values.size (), model->header.stamp.toSec (), model->header.frame_id.c_str (), pnh_->resolveName (topic_name).c_str ());
return (false);
}*/
return true;
}
protected:
/** \brief Set to true if point indices are used.
*
* When receiving a point cloud, if use_indices_ is false, the entire
* point cloud is processed for the given operation. If use_indices_ is
* true, then the ~indices topic is read to get the vector of point
* indices specifying the subset of the point cloud that will be used for
* the operation. In the case where use_indices_ is true, the ~input and
* ~indices topics must be synchronised in time, either exact or within a
* specified jitter. See also @ref latched_indices_ and approximate_sync.
**/
bool use_indices_;
/** \brief Set to true if the indices topic is latched.
*
* If use_indices_ is true, the ~input and ~indices topics generally must
* be synchronised in time. By setting this flag to true, the most recent
* value from ~indices can be used instead of requiring a synchronised
* message.
**/
bool latched_indices_;
/** \brief Lazy transport subscribe/unsubscribe routine. It is optional for backward compatibility. */
virtual void subscribe() {}
virtual void unsubscribe() {}
/** \brief The message filter subscriber for PointCloud2. */
message_filters::Subscriber<PointCloud> sub_input_filter_;
/** \brief Nodelet initialization routine. Reads in global parameters used by all nodelets. */
virtual void
onInit()
{
nodelet_topic_tools::NodeletLazy::onInit();
/** \brief The message filter subscriber for PointIndices. */
message_filters::Subscriber<PointIndices> sub_indices_filter_;
// Parameters that we care about only at startup
pnh_->getParam("max_queue_size", max_queue_size_);
/** \brief The output PointCloud publisher. */
ros::Publisher pub_output_;
// ---[ Optional parameters
pnh_->getParam("use_indices", use_indices_);
pnh_->getParam("latched_indices", latched_indices_);
pnh_->getParam("approximate_sync", approximate_sync_);
/** \brief The maximum queue size (default: 3). */
int max_queue_size_;
NODELET_DEBUG(
"[%s::onInit] PCL Nodelet successfully created with the following parameters:\n"
" - approximate_sync : %s\n"
" - use_indices : %s\n"
" - latched_indices : %s\n"
" - max_queue_size : %d",
getName().c_str(),
(approximate_sync_) ? "true" : "false",
(use_indices_) ? "true" : "false",
(latched_indices_) ? "true" : "false",
max_queue_size_);
}
/** \brief True if we use an approximate time synchronizer versus an exact one (false by default). */
bool approximate_sync_;
/** \brief TF listener object. */
tf::TransformListener tf_listener_;
/** \brief Test whether a given PointCloud message is "valid" (i.e., has points, and width and height are non-zero).
* \param cloud the point cloud to test
* \param topic_name an optional topic name (only used for printing, defaults to "input")
*/
inline bool
isValid (const PointCloud2::ConstPtr &cloud, const std::string &topic_name = "input")
{
if (cloud->width * cloud->height * cloud->point_step != cloud->data.size ())
{
NODELET_WARN ("[%s] Invalid PointCloud (data = %zu, width = %d, height = %d, step = %d) with stamp %f, and frame %s on topic %s received!", getName ().c_str (), cloud->data.size (), cloud->width, cloud->height, cloud->point_step, cloud->header.stamp.toSec (), cloud->header.frame_id.c_str (), pnh_->resolveName (topic_name).c_str ());
return (false);
}
return (true);
}
/** \brief Test whether a given PointCloud message is "valid" (i.e., has points, and width and height are non-zero).
* \param cloud the point cloud to test
* \param topic_name an optional topic name (only used for printing, defaults to "input")
*/
inline bool
isValid (const PointCloudConstPtr &cloud, const std::string &topic_name = "input")
{
if (cloud->width * cloud->height != cloud->points.size ())
{
NODELET_WARN ("[%s] Invalid PointCloud (points = %zu, width = %d, height = %d) with stamp %f, and frame %s on topic %s received!", getName ().c_str (), cloud->points.size (), cloud->width, cloud->height, fromPCL(cloud->header).stamp.toSec (), cloud->header.frame_id.c_str (), pnh_->resolveName (topic_name).c_str ());
return (false);
}
return (true);
}
/** \brief Test whether a given PointIndices message is "valid" (i.e., has values).
* \param indices the point indices message to test
* \param topic_name an optional topic name (only used for printing, defaults to "indices")
*/
inline bool
isValid (const PointIndicesConstPtr &indices, const std::string &topic_name = "indices")
{
/*if (indices->indices.empty ())
{
NODELET_WARN ("[%s] Empty indices (values = %zu) with stamp %f, and frame %s on topic %s received!", getName ().c_str (), indices->indices.size (), indices->header.stamp.toSec (), indices->header.frame_id.c_str (), pnh_->resolveName (topic_name).c_str ());
return (true);
}*/
return (true);
}
/** \brief Test whether a given ModelCoefficients message is "valid" (i.e., has values).
* \param model the model coefficients to test
* \param topic_name an optional topic name (only used for printing, defaults to "model")
*/
inline bool
isValid (const ModelCoefficientsConstPtr &model, const std::string &topic_name = "model")
{
/*if (model->values.empty ())
{
NODELET_WARN ("[%s] Empty model (values = %zu) with stamp %f, and frame %s on topic %s received!", getName ().c_str (), model->values.size (), model->header.stamp.toSec (), model->header.frame_id.c_str (), pnh_->resolveName (topic_name).c_str ());
return (false);
}*/
return (true);
}
/** \brief Lazy transport subscribe/unsubscribe routine. It is optional for backward compatibility. */
virtual void subscribe () {}
virtual void unsubscribe () {}
/** \brief Nodelet initialization routine. Reads in global parameters used by all nodelets. */
virtual void
onInit ()
{
nodelet_topic_tools::NodeletLazy::onInit();
// Parameters that we care about only at startup
pnh_->getParam ("max_queue_size", max_queue_size_);
// ---[ Optional parameters
pnh_->getParam ("use_indices", use_indices_);
pnh_->getParam ("latched_indices", latched_indices_);
pnh_->getParam ("approximate_sync", approximate_sync_);
NODELET_DEBUG ("[%s::onInit] PCL Nodelet successfully created with the following parameters:\n"
" - approximate_sync : %s\n"
" - use_indices : %s\n"
" - latched_indices : %s\n"
" - max_queue_size : %d",
getName ().c_str (),
(approximate_sync_) ? "true" : "false",
(use_indices_) ? "true" : "false",
(latched_indices_) ? "true" : "false",
max_queue_size_);
}
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_NODELET_H_
+334 -327
View File
@@ -11,286 +11,295 @@
#include <boost/mpl/size.hpp>
#include <boost/ref.hpp>
namespace pcl
namespace pcl
{
namespace detail
namespace detail
{
template<typename Stream, typename PointT>
struct FieldStreamer
{
FieldStreamer(Stream & stream)
: stream_(stream) {}
template<typename U>
void operator()()
{
template<typename Stream, typename PointT>
struct FieldStreamer
{
FieldStreamer(Stream& stream) : stream_(stream) {}
const char * name = traits::name<PointT, U>::value;
std::uint32_t name_length = strlen(name);
stream_.next(name_length);
if (name_length > 0) {
memcpy(stream_.advance(name_length), name, name_length);
}
template<typename U> void operator() ()
{
const char* name = traits::name<PointT, U>::value;
std::uint32_t name_length = strlen(name);
stream_.next(name_length);
if (name_length > 0)
memcpy(stream_.advance(name_length), name, name_length);
std::uint32_t offset = traits::offset<PointT, U>::value;
stream_.next(offset);
std::uint32_t offset = traits::offset<PointT, U>::value;
stream_.next(offset);
std::uint8_t datatype = traits::datatype<PointT, U>::value;
stream_.next(datatype);
std::uint8_t datatype = traits::datatype<PointT, U>::value;
stream_.next(datatype);
std::uint32_t count = traits::datatype<PointT, U>::size;
stream_.next(count);
}
std::uint32_t count = traits::datatype<PointT, U>::size;
stream_.next(count);
}
Stream & stream_;
};
Stream& stream_;
};
template<typename PointT>
struct FieldsLength
{
FieldsLength()
: length(0) {}
template<typename PointT>
struct FieldsLength
{
FieldsLength() : length(0) {}
template<typename U>
void operator()()
{
std::uint32_t name_length = strlen(traits::name<PointT, U>::value);
length += name_length + 13;
}
template<typename U> void operator() ()
{
std::uint32_t name_length = strlen(traits::name<PointT, U>::value);
length += name_length + 13;
}
std::uint32_t length;
};
} // namespace pcl::detail
std::uint32_t length;
};
} // namespace pcl::detail
} // namespace pcl
namespace ros
namespace ros
{
// In ROS 1.3.1+, we can specialize the functor used to create PointCloud<T> objects
// on the subscriber side. This allows us to generate the mapping between message
// data and object fields only once and reuse it.
// In ROS 1.3.1+, we can specialize the functor used to create PointCloud<T> objects
// on the subscriber side. This allows us to generate the mapping between message
// data and object fields only once and reuse it.
#if ROS_VERSION_MINIMUM(1, 3, 1)
template<typename T>
struct DefaultMessageCreator<pcl::PointCloud<T> >
{
boost::shared_ptr<pcl::MsgFieldMap> mapping_;
template<typename T>
struct DefaultMessageCreator<pcl::PointCloud<T>>
{
boost::shared_ptr<pcl::MsgFieldMap> mapping_;
DefaultMessageCreator()
: mapping_( boost::make_shared<pcl::MsgFieldMap>() )
{
}
boost::shared_ptr<pcl::PointCloud<T> > operator() ()
{
boost::shared_ptr<pcl::PointCloud<T> > msg (new pcl::PointCloud<T> ());
pcl::detail::getMapping(*msg) = mapping_;
return msg;
}
};
DefaultMessageCreator()
: mapping_(boost::make_shared<pcl::MsgFieldMap>() )
{
}
boost::shared_ptr<pcl::PointCloud<T>> operator()()
{
boost::shared_ptr<pcl::PointCloud<T>> msg(new pcl::PointCloud<T>());
pcl::detail::getMapping(*msg) = mapping_;
return msg;
}
};
#endif
namespace message_traits
namespace message_traits
{
template<typename T>
struct MD5Sum<pcl::PointCloud<T>>
{
static const char * value() {return MD5Sum<sensor_msgs::PointCloud2>::value();}
static const char * value(const pcl::PointCloud<T> &) {return value();}
static const uint64_t static_value1 = MD5Sum<sensor_msgs::PointCloud2>::static_value1;
static const uint64_t static_value2 = MD5Sum<sensor_msgs::PointCloud2>::static_value2;
// If the definition of sensor_msgs/PointCloud2 changes, we'll get a compile error here.
ROS_STATIC_ASSERT(static_value1 == 0x1158d486dd51d683ULL);
ROS_STATIC_ASSERT(static_value2 == 0xce2f1be655c3c181ULL);
};
template<typename T>
struct DataType<pcl::PointCloud<T>>
{
static const char * value() {return DataType<sensor_msgs::PointCloud2>::value();}
static const char * value(const pcl::PointCloud<T> &) {return value();}
};
template<typename T>
struct Definition<pcl::PointCloud<T>>
{
static const char * value() {return Definition<sensor_msgs::PointCloud2>::value();}
static const char * value(const pcl::PointCloud<T> &) {return value();}
};
// pcl point clouds message don't have a ROS compatible header
// the specialized meta functions below (TimeStamp and FrameId)
// can be used to get the header data.
template<typename T>
struct HasHeader<pcl::PointCloud<T>>: FalseType {};
template<typename T>
struct TimeStamp<pcl::PointCloud<T>>
{
// This specialization could be dangerous, but it's the best I can do.
// If this TimeStamp struct is destroyed before they are done with the
// pointer returned by the first functions may go out of scope, but there
// isn't a lot I can do about that. This is a good reason to refuse to
// returning pointers like this...
static ros::Time * pointer(typename pcl::PointCloud<T> & m)
{
template<typename T> struct MD5Sum<pcl::PointCloud<T> >
{
static const char* value() { return MD5Sum<sensor_msgs::PointCloud2>::value(); }
static const char* value(const pcl::PointCloud<T>&) { return value(); }
static const uint64_t static_value1 = MD5Sum<sensor_msgs::PointCloud2>::static_value1;
static const uint64_t static_value2 = MD5Sum<sensor_msgs::PointCloud2>::static_value2;
// If the definition of sensor_msgs/PointCloud2 changes, we'll get a compile error here.
ROS_STATIC_ASSERT(static_value1 == 0x1158d486dd51d683ULL);
ROS_STATIC_ASSERT(static_value2 == 0xce2f1be655c3c181ULL);
};
template<typename T> struct DataType<pcl::PointCloud<T> >
{
static const char* value() { return DataType<sensor_msgs::PointCloud2>::value(); }
static const char* value(const pcl::PointCloud<T>&) { return value(); }
};
template<typename T> struct Definition<pcl::PointCloud<T> >
{
static const char* value() { return Definition<sensor_msgs::PointCloud2>::value(); }
static const char* value(const pcl::PointCloud<T>&) { return value(); }
};
// pcl point clouds message don't have a ROS compatible header
// the specialized meta functions below (TimeStamp and FrameId)
// can be used to get the header data.
template<typename T> struct HasHeader<pcl::PointCloud<T> > : FalseType {};
template<typename T>
struct TimeStamp<pcl::PointCloud<T> >
{
// This specialization could be dangerous, but it's the best I can do.
// If this TimeStamp struct is destroyed before they are done with the
// pointer returned by the first functions may go out of scope, but there
// isn't a lot I can do about that. This is a good reason to refuse to
// returning pointers like this...
static ros::Time* pointer(typename pcl::PointCloud<T> &m) {
header_.reset(new std_msgs::Header());
pcl_conversions::fromPCL(m.header, *(header_));
return &(header_->stamp);
}
static ros::Time const* pointer(const typename pcl::PointCloud<T>& m) {
header_const_.reset(new std_msgs::Header());
pcl_conversions::fromPCL(m.header, *(header_const_));
return &(header_const_->stamp);
}
static ros::Time value(const typename pcl::PointCloud<T>& m) {
return pcl_conversions::fromPCL(m.header).stamp;
}
private:
static boost::shared_ptr<std_msgs::Header> header_;
static boost::shared_ptr<std_msgs::Header> header_const_;
};
template<typename T>
struct FrameId<pcl::PointCloud<T> >
{
static std::string* pointer(pcl::PointCloud<T>& m) { return &m.header.frame_id; }
static std::string const* pointer(const pcl::PointCloud<T>& m) { return &m.header.frame_id; }
static std::string value(const pcl::PointCloud<T>& m) { return m.header.frame_id; }
};
} // namespace ros::message_traits
namespace serialization
header_.reset(new std_msgs::Header());
pcl_conversions::fromPCL(m.header, *(header_));
return &(header_->stamp);
}
static ros::Time const * pointer(const typename pcl::PointCloud<T> & m)
{
template<typename T>
struct Serializer<pcl::PointCloud<T> >
header_const_.reset(new std_msgs::Header());
pcl_conversions::fromPCL(m.header, *(header_const_));
return &(header_const_->stamp);
}
static ros::Time value(const typename pcl::PointCloud<T> & m)
{
return pcl_conversions::fromPCL(m.header).stamp;
}
private:
static boost::shared_ptr<std_msgs::Header> header_;
static boost::shared_ptr<std_msgs::Header> header_const_;
};
template<typename T>
struct FrameId<pcl::PointCloud<T>>
{
static std::string * pointer(pcl::PointCloud<T> & m) {return &m.header.frame_id;}
static std::string const * pointer(const pcl::PointCloud<T> & m) {return &m.header.frame_id;}
static std::string value(const pcl::PointCloud<T> & m) {return m.header.frame_id;}
};
} // namespace ros::message_traits
namespace serialization
{
template<typename T>
struct Serializer<pcl::PointCloud<T>>
{
template<typename Stream>
inline static void write(Stream & stream, const pcl::PointCloud<T> & m)
{
stream.next(m.header);
// Ease the user's burden on specifying width/height for unorganized datasets
uint32_t height = m.height, width = m.width;
if (height == 0 && width == 0) {
width = m.points.size();
height = 1;
}
stream.next(height);
stream.next(width);
// Stream out point field metadata
typedef typename pcl::traits::fieldList<T>::type FieldList;
uint32_t fields_size = boost::mpl::size<FieldList>::value;
stream.next(fields_size);
pcl::for_each_type<FieldList>(pcl::detail::FieldStreamer<Stream, T>(stream));
// Assume little-endian...
uint8_t is_bigendian = false;
stream.next(is_bigendian);
// Write out point data as binary blob
uint32_t point_step = sizeof(T);
stream.next(point_step);
uint32_t row_step = point_step * width;
stream.next(row_step);
uint32_t data_size = row_step * height;
stream.next(data_size);
memcpy(stream.advance(data_size), &m.points[0], data_size);
uint8_t is_dense = m.is_dense;
stream.next(is_dense);
}
template<typename Stream>
inline static void read(Stream & stream, pcl::PointCloud<T> & m)
{
std_msgs::Header header;
stream.next(header);
pcl_conversions::toPCL(header, m.header);
stream.next(m.height);
stream.next(m.width);
/// @todo Check that fields haven't changed!
std::vector<sensor_msgs::PointField> fields;
stream.next(fields);
// Construct field mapping if deserializing for the first time
boost::shared_ptr<pcl::MsgFieldMap> & mapping_ptr = pcl::detail::getMapping(m);
if (!mapping_ptr) {
// This normally should get allocated by DefaultMessageCreator, but just in case
mapping_ptr = boost::make_shared<pcl::MsgFieldMap>();
}
pcl::MsgFieldMap & mapping = *mapping_ptr;
if (mapping.empty()) {
pcl::createMapping<T>(fields, mapping);
}
uint8_t is_bigendian;
stream.next(is_bigendian); // ignoring...
uint32_t point_step, row_step;
stream.next(point_step);
stream.next(row_step);
// Copy point data
uint32_t data_size;
stream.next(data_size);
assert(data_size == m.height * m.width * point_step);
m.points.resize(m.height * m.width);
uint8_t * m_data = reinterpret_cast<uint8_t *>(&m.points[0]);
// If the data layouts match, can copy a whole row in one memcpy
if (mapping.size() == 1 &&
mapping[0].serialized_offset == 0 &&
mapping[0].struct_offset == 0 &&
point_step == sizeof(T))
{
template<typename Stream>
inline static void write(Stream& stream, const pcl::PointCloud<T>& m)
{
stream.next(m.header);
// Ease the user's burden on specifying width/height for unorganized datasets
uint32_t height = m.height, width = m.width;
if (height == 0 && width == 0) {
width = m.points.size();
height = 1;
uint32_t m_row_step = sizeof(T) * m.width;
// And if the row steps match, can copy whole point cloud in one memcpy
if (m_row_step == row_step) {
memcpy(m_data, stream.advance(data_size), data_size);
} else {
for (uint32_t i = 0; i < m.height; ++i, m_data += m_row_step) {
memcpy(m_data, stream.advance(row_step), m_row_step);
}
stream.next(height);
stream.next(width);
// Stream out point field metadata
typedef typename pcl::traits::fieldList<T>::type FieldList;
uint32_t fields_size = boost::mpl::size<FieldList>::value;
stream.next(fields_size);
pcl::for_each_type<FieldList>(pcl::detail::FieldStreamer<Stream, T>(stream));
// Assume little-endian...
uint8_t is_bigendian = false;
stream.next(is_bigendian);
// Write out point data as binary blob
uint32_t point_step = sizeof(T);
stream.next(point_step);
uint32_t row_step = point_step * width;
stream.next(row_step);
uint32_t data_size = row_step * height;
stream.next(data_size);
memcpy(stream.advance(data_size), &m.points[0], data_size);
uint8_t is_dense = m.is_dense;
stream.next(is_dense);
}
template<typename Stream>
inline static void read(Stream& stream, pcl::PointCloud<T>& m)
{
std_msgs::Header header;
stream.next(header);
pcl_conversions::toPCL(header, m.header);
stream.next(m.height);
stream.next(m.width);
/// @todo Check that fields haven't changed!
std::vector<sensor_msgs::PointField> fields;
stream.next(fields);
// Construct field mapping if deserializing for the first time
boost::shared_ptr<pcl::MsgFieldMap>& mapping_ptr = pcl::detail::getMapping(m);
if (!mapping_ptr)
{
// This normally should get allocated by DefaultMessageCreator, but just in case
mapping_ptr = boost::make_shared<pcl::MsgFieldMap>();
}
pcl::MsgFieldMap& mapping = *mapping_ptr;
if (mapping.empty())
pcl::createMapping<T> (fields, mapping);
uint8_t is_bigendian;
stream.next(is_bigendian); // ignoring...
uint32_t point_step, row_step;
stream.next(point_step);
stream.next(row_step);
// Copy point data
uint32_t data_size;
stream.next(data_size);
assert(data_size == m.height * m.width * point_step);
m.points.resize(m.height * m.width);
uint8_t* m_data = reinterpret_cast<uint8_t*>(&m.points[0]);
// If the data layouts match, can copy a whole row in one memcpy
if (mapping.size() == 1 &&
mapping[0].serialized_offset == 0 &&
mapping[0].struct_offset == 0 &&
point_step == sizeof(T))
{
uint32_t m_row_step = sizeof(T) * m.width;
// And if the row steps match, can copy whole point cloud in one memcpy
if (m_row_step == row_step)
{
memcpy (m_data, stream.advance(data_size), data_size);
}
else
{
for (uint32_t i = 0; i < m.height; ++i, m_data += m_row_step)
memcpy (m_data, stream.advance(row_step), m_row_step);
} else {
// If not, do a lot of memcpys to copy over the fields
for (uint32_t row = 0; row < m.height; ++row) {
const uint8_t * stream_data = stream.advance(row_step);
for (uint32_t col = 0; col < m.width; ++col, stream_data += point_step) {
BOOST_FOREACH(const pcl::detail::FieldMapping & fm, mapping) {
memcpy(m_data + fm.struct_offset, stream_data + fm.serialized_offset, fm.size);
}
m_data += sizeof(T);
}
else
{
// If not, do a lot of memcpys to copy over the fields
for (uint32_t row = 0; row < m.height; ++row) {
const uint8_t* stream_data = stream.advance(row_step);
for (uint32_t col = 0; col < m.width; ++col, stream_data += point_step) {
BOOST_FOREACH(const pcl::detail::FieldMapping& fm, mapping) {
memcpy(m_data + fm.struct_offset, stream_data + fm.serialized_offset, fm.size);
}
m_data += sizeof(T);
}
}
}
uint8_t is_dense;
stream.next(is_dense);
m.is_dense = is_dense;
}
}
inline static uint32_t serializedLength(const pcl::PointCloud<T>& m)
{
uint32_t length = 0;
uint8_t is_dense;
stream.next(is_dense);
m.is_dense = is_dense;
}
length += serializationLength(m.header);
length += 8; // height/width
inline static uint32_t serializedLength(const pcl::PointCloud<T> & m)
{
uint32_t length = 0;
pcl::detail::FieldsLength<T> fl;
typedef typename pcl::traits::fieldList<T>::type FieldList;
pcl::for_each_type<FieldList>(boost::ref(fl));
length += 4; // size of 'fields'
length += fl.length;
length += serializationLength(m.header);
length += 8; // height/width
length += 1; // is_bigendian
length += 4; // point_step
length += 4; // row_step
length += 4; // size of 'data'
length += m.points.size() * sizeof(T); // data
length += 1; // is_dense
pcl::detail::FieldsLength<T> fl;
typedef typename pcl::traits::fieldList<T>::type FieldList;
pcl::for_each_type<FieldList>(boost::ref(fl));
length += 4; // size of 'fields'
length += fl.length;
return length;
}
};
} // namespace ros::serialization
length += 1; // is_bigendian
length += 4; // point_step
length += 4; // row_step
length += 4; // size of 'data'
length += m.points.size() * sizeof(T); // data
length += 1; // is_dense
/// @todo Printer specialization in message_operations
return length;
}
};
} // namespace ros::serialization
/// @todo Printer specialization in message_operations
} // namespace ros
@@ -315,103 +324,101 @@ namespace ros
namespace pcl
{
namespace detail
{
namespace detail
{
#if ROS_POINTER_COMPATIBILITY_IMPLEMENTED
#if PCL_VERSION_COMPARE(>=, 1, 10, 0)
template <class T>
constexpr static bool pcl_uses_boost = std::is_same<boost::shared_ptr<T>,
pcl::shared_ptr<T>>::value;
template<class T>
constexpr static bool pcl_uses_boost = std::is_same<boost::shared_ptr<T>,
pcl::shared_ptr<T>>::value;
#else
template <class T>
constexpr static bool pcl_uses_boost = true;
template<class T>
constexpr static bool pcl_uses_boost = true;
#endif
template<class SharedPointer> struct Holder
{
SharedPointer p;
template<class SharedPointer>
struct Holder
{
SharedPointer p;
Holder(const SharedPointer &p) : p(p) {}
Holder(const Holder &other) : p(other.p) {}
Holder(Holder &&other) : p(std::move(other.p)) {}
Holder(const SharedPointer & p)
: p(p) {}
Holder(const Holder & other)
: p(other.p) {}
Holder(Holder && other)
: p(std::move(other.p)) {}
void operator () (...) { p.reset(); }
};
void operator()(...) {p.reset();}
};
template<class T>
inline std::shared_ptr<T> to_std_ptr(const boost::shared_ptr<T> &p)
{
typedef Holder<std::shared_ptr<T>> H;
if(H *h = boost::get_deleter<H>(p))
{
return h->p;
}
else
{
return std::shared_ptr<T>(p.get(), Holder<boost::shared_ptr<T>>(p));
}
}
template<class T>
inline std::shared_ptr<T> to_std_ptr(const boost::shared_ptr<T> & p)
{
typedef Holder<std::shared_ptr<T>> H;
if (H * h = boost::get_deleter<H>(p)) {
return h->p;
} else {
return std::shared_ptr<T>(p.get(), Holder<boost::shared_ptr<T>>(p));
}
}
template<class T>
inline boost::shared_ptr<T> to_boost_ptr(const std::shared_ptr<T> &p)
{
typedef Holder<boost::shared_ptr<T>> H;
if(H * h = std::get_deleter<H>(p))
{
return h->p;
}
else
{
return boost::shared_ptr<T>(p.get(), Holder<std::shared_ptr<T>>(p));
}
}
template<class T>
inline boost::shared_ptr<T> to_boost_ptr(const std::shared_ptr<T> & p)
{
typedef Holder<boost::shared_ptr<T>> H;
if (H * h = std::get_deleter<H>(p)) {
return h->p;
} else {
return boost::shared_ptr<T>(p.get(), Holder<std::shared_ptr<T>>(p));
}
}
#endif
} // namespace pcl::detail
} // namespace pcl::detail
// add functions to convert to smart pointer used by ROS
template <class T>
inline boost::shared_ptr<T> ros_ptr(const boost::shared_ptr<T> &p)
{
return p;
}
template<class T>
inline boost::shared_ptr<T> ros_ptr(const boost::shared_ptr<T> & p)
{
return p;
}
#if ROS_POINTER_COMPATIBILITY_IMPLEMENTED
template <class T>
inline boost::shared_ptr<T> ros_ptr(const std::shared_ptr<T> &p)
{
return detail::to_boost_ptr(p);
}
template<class T>
inline boost::shared_ptr<T> ros_ptr(const std::shared_ptr<T> & p)
{
return detail::to_boost_ptr(p);
}
// add functions to convert to smart pointer used by PCL, based on PCL's own pointer
template <class T, class = typename std::enable_if<!detail::pcl_uses_boost<T>>::type>
inline std::shared_ptr<T> pcl_ptr(const std::shared_ptr<T> &p)
{
return p;
}
template<class T, class = typename std::enable_if<!detail::pcl_uses_boost<T>>::type>
inline std::shared_ptr<T> pcl_ptr(const std::shared_ptr<T> & p)
{
return p;
}
template <class T, class = typename std::enable_if<!detail::pcl_uses_boost<T>>::type>
inline std::shared_ptr<T> pcl_ptr(const boost::shared_ptr<T> &p)
{
return detail::to_std_ptr(p);
}
template<class T, class = typename std::enable_if<!detail::pcl_uses_boost<T>>::type>
inline std::shared_ptr<T> pcl_ptr(const boost::shared_ptr<T> & p)
{
return detail::to_std_ptr(p);
}
template <class T, class = typename std::enable_if<detail::pcl_uses_boost<T>>::type>
inline boost::shared_ptr<T> pcl_ptr(const std::shared_ptr<T> &p)
{
return detail::to_boost_ptr(p);
}
template<class T, class = typename std::enable_if<detail::pcl_uses_boost<T>>::type>
inline boost::shared_ptr<T> pcl_ptr(const std::shared_ptr<T> & p)
{
return detail::to_boost_ptr(p);
}
template <class T, class = typename std::enable_if<detail::pcl_uses_boost<T>>::type>
inline boost::shared_ptr<T> pcl_ptr(const boost::shared_ptr<T> &p)
{
return p;
}
template<class T, class = typename std::enable_if<detail::pcl_uses_boost<T>>::type>
inline boost::shared_ptr<T> pcl_ptr(const boost::shared_ptr<T> & p)
{
return p;
}
#else
template <class T>
inline boost::shared_ptr<T> pcl_ptr(const boost::shared_ptr<T> &p)
{
return p;
}
template<class T>
inline boost::shared_ptr<T> pcl_ptr(const boost::shared_ptr<T> & p)
{
return p;
}
#endif
} // namespace pcl
+85 -85
View File
@@ -38,7 +38,7 @@
\author Patrick Mihelich
@b Publisher represents a ROS publisher for the templated PointCloud implementation.
@b Publisher represents a ROS publisher for the templated PointCloud implementation.
**/
@@ -51,99 +51,99 @@
#include <pcl_conversions/pcl_conversions.h>
namespace pcl_ros
namespace pcl_ros
{
class BasePublisher
class BasePublisher
{
public:
void
advertise(ros::NodeHandle & nh, const std::string & topic, uint32_t queue_size)
{
public:
void
advertise (ros::NodeHandle& nh, const std::string& topic, uint32_t queue_size)
{
pub_ = nh.advertise<sensor_msgs::PointCloud2>(topic, queue_size);
}
pub_ = nh.advertise<sensor_msgs::PointCloud2>(topic, queue_size);
}
std::string
getTopic ()
{
return (pub_.getTopic ());
}
uint32_t
getNumSubscribers () const
{
return (pub_.getNumSubscribers ());
}
void
shutdown ()
{
pub_.shutdown ();
}
operator void*() const
{
return (pub_) ? (void*)1 : (void*)0;
}
protected:
ros::Publisher pub_;
};
template <typename PointT>
class Publisher : public BasePublisher
std::string
getTopic()
{
public:
Publisher () {}
return pub_.getTopic();
}
Publisher (ros::NodeHandle& nh, const std::string& topic, uint32_t queue_size)
{
advertise (nh, topic, queue_size);
}
~Publisher () {}
inline void
publish (const boost::shared_ptr<const pcl::PointCloud<PointT> > &point_cloud) const
{
publish (*point_cloud);
}
inline void
publish (const pcl::PointCloud<PointT>& point_cloud) const
{
// Fill point cloud binary data
sensor_msgs::PointCloud2 msg;
pcl::toROSMsg (point_cloud, msg);
pub_.publish (boost::make_shared<const sensor_msgs::PointCloud2> (msg));
}
};
template <>
class Publisher<sensor_msgs::PointCloud2> : public BasePublisher
uint32_t
getNumSubscribers() const
{
public:
Publisher () {}
return pub_.getNumSubscribers();
}
Publisher (ros::NodeHandle& nh, const std::string& topic, uint32_t queue_size)
{
advertise (nh, topic, queue_size);
}
void
shutdown()
{
pub_.shutdown();
}
~Publisher () {}
operator void *() const
{
return (pub_) ? (void *)1 : (void *)0;
}
void
publish (const sensor_msgs::PointCloud2Ptr& point_cloud) const
{
pub_.publish (point_cloud);
//pub_.publish (*point_cloud);
}
protected:
ros::Publisher pub_;
};
void
publish (const sensor_msgs::PointCloud2& point_cloud) const
{
pub_.publish (boost::make_shared<const sensor_msgs::PointCloud2> (point_cloud));
//pub_.publish (point_cloud);
}
};
template<typename PointT>
class Publisher : public BasePublisher
{
public:
Publisher() {}
Publisher(ros::NodeHandle & nh, const std::string & topic, uint32_t queue_size)
{
advertise(nh, topic, queue_size);
}
~Publisher() {}
inline void
publish(const boost::shared_ptr<const pcl::PointCloud<PointT>> & point_cloud) const
{
publish(*point_cloud);
}
inline void
publish(const pcl::PointCloud<PointT> & point_cloud) const
{
// Fill point cloud binary data
sensor_msgs::PointCloud2 msg;
pcl::toROSMsg(point_cloud, msg);
pub_.publish(boost::make_shared<const sensor_msgs::PointCloud2>(msg));
}
};
template<>
class Publisher<sensor_msgs::PointCloud2>: public BasePublisher
{
public:
Publisher() {}
Publisher(ros::NodeHandle & nh, const std::string & topic, uint32_t queue_size)
{
advertise(nh, topic, queue_size);
}
~Publisher() {}
void
publish(const sensor_msgs::PointCloud2Ptr & point_cloud) const
{
pub_.publish(point_cloud);
//pub_.publish (*point_cloud);
}
void
publish(const sensor_msgs::PointCloud2 & point_cloud) const
{
pub_.publish(boost::make_shared<const sensor_msgs::PointCloud2>(point_cloud));
//pub_.publish (point_cloud);
}
};
}
#endif //#ifndef PCL_ROS_PUBLISHER_H_
@@ -47,63 +47,68 @@
namespace pcl_ros
{
namespace sync_policies = message_filters::sync_policies;
namespace sync_policies = message_filters::sync_policies;
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b EuclideanClusterExtraction represents a segmentation class for cluster extraction in an Euclidean sense.
* \author Radu Bogdan Rusu
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b EuclideanClusterExtraction represents a segmentation class for cluster extraction in an Euclidean sense.
* \author Radu Bogdan Rusu
*/
class EuclideanClusterExtraction : public PCLNodelet
{
public:
/** \brief Empty constructor. */
EuclideanClusterExtraction()
: publish_indices_(false), max_clusters_(std::numeric_limits<int>::max()) {}
protected:
// ROS nodelet attributes
/** \brief Publish indices or convert to PointCloud clusters. Default: false */
bool publish_indices_;
/** \brief Maximum number of clusters to publish. */
int max_clusters_;
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<EuclideanClusterExtractionConfig>> srv_;
/** \brief Nodelet initialization routine. */
void onInit();
/** \brief LazyNodelet connection routine. */
void subscribe();
void unsubscribe();
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
class EuclideanClusterExtraction : public PCLNodelet
{
public:
/** \brief Empty constructor. */
EuclideanClusterExtraction () : publish_indices_ (false), max_clusters_ (std::numeric_limits<int>::max ()) {};
protected:
// ROS nodelet attributes
/** \brief Publish indices or convert to PointCloud clusters. Default: false */
bool publish_indices_;
void config_callback(EuclideanClusterExtractionConfig & config, uint32_t level);
/** \brief Maximum number of clusters to publish. */
int max_clusters_;
/** \brief Input point cloud callback.
* \param cloud the pointer to the input point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_indices_callback(
const PointCloudConstPtr & cloud,
const PointIndicesConstPtr & indices);
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<EuclideanClusterExtractionConfig> > srv_;
private:
/** \brief The PCL implementation used. */
pcl::EuclideanClusterExtraction<pcl::PointXYZ> impl_;
/** \brief Nodelet initialization routine. */
void onInit ();
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief LazyNodelet connection routine. */
void subscribe ();
void unsubscribe ();
/** \brief Synchronized input, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud,
PointIndices>>> sync_input_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud,
PointIndices>>> sync_input_indices_a_;
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback (EuclideanClusterExtractionConfig &config, uint32_t level);
/** \brief Input point cloud callback.
* \param cloud the pointer to the input point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_indices_callback (const PointCloudConstPtr &cloud, const PointIndicesConstPtr &indices);
private:
/** \brief The PCL implementation used. */
pcl::EuclideanClusterExtraction<pcl::PointXYZ> impl_;
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief Synchronized input, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud, PointIndices> > > sync_input_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud, PointIndices> > > sync_input_indices_a_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_EXTRACT_CLUSTERS_H_
@@ -52,79 +52,83 @@
namespace pcl_ros
{
namespace sync_policies = message_filters::sync_policies;
namespace sync_policies = message_filters::sync_policies;
/** \brief @b ExtractPolygonalPrismData uses a set of point indices that represent a planar model, and together with
* a given height, generates a 3D polygonal prism. The polygonal prism is then used to segment all points lying
* inside it.
*
* An example of its usage is to extract the data lying within a set of 3D boundaries (e.g., objects supported by a plane).
* \author Radu Bogdan Rusu
/** \brief @b ExtractPolygonalPrismData uses a set of point indices that represent a planar model, and together with
* a given height, generates a 3D polygonal prism. The polygonal prism is then used to segment all points lying
* inside it.
*
* An example of its usage is to extract the data lying within a set of 3D boundaries (e.g., objects supported by a plane).
* \author Radu Bogdan Rusu
*/
class ExtractPolygonalPrismData : public PCLNodelet
{
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
protected:
/** \brief The output PointIndices publisher. */
ros::Publisher pub_output_;
/** \brief The message filter subscriber for PointCloud2. */
message_filters::Subscriber<PointCloud> sub_hull_filter_;
/** \brief Synchronized input, planar hull, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud, PointCloud,
PointIndices>>> sync_input_hull_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud,
PointCloud, PointIndices>>> sync_input_hull_indices_a_;
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<ExtractPolygonalPrismDataConfig>> srv_;
/** \brief Null passthrough filter, used for pushing empty elements in the
* synchronizer */
message_filters::PassThrough<PointIndices> nf_;
/** \brief Input point cloud callback.
* Because we want to use the same synchronizer object, we push back
* empty elements with the same timestamp.
*/
class ExtractPolygonalPrismData : public PCLNodelet
inline void
input_callback(const PointCloudConstPtr & input)
{
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
PointIndices cloud;
cloud.header.stamp = pcl_conversions::fromPCL(input->header).stamp;
nf_.add(boost::make_shared<PointIndices>(cloud));
}
protected:
/** \brief The output PointIndices publisher. */
ros::Publisher pub_output_;
/** \brief Nodelet initialization routine. */
void onInit();
/** \brief The message filter subscriber for PointCloud2. */
message_filters::Subscriber<PointCloud> sub_hull_filter_;
/** \brief LazyNodelet connection routine. */
void subscribe();
void unsubscribe();
/** \brief Synchronized input, planar hull, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud, PointCloud, PointIndices> > > sync_input_hull_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud, PointCloud, PointIndices> > > sync_input_hull_indices_a_;
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback(ExtractPolygonalPrismDataConfig & config, uint32_t level);
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<ExtractPolygonalPrismDataConfig> > srv_;
/** \brief Input point cloud callback. Used when \a use_indices is set.
* \param cloud the pointer to the input point cloud
* \param hull the pointer to the planar hull point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_hull_indices_callback(
const PointCloudConstPtr & cloud,
const PointCloudConstPtr & hull,
const PointIndicesConstPtr & indices);
/** \brief Null passthrough filter, used for pushing empty elements in the
* synchronizer */
message_filters::PassThrough<PointIndices> nf_;
private:
/** \brief The PCL implementation used. */
pcl::ExtractPolygonalPrismData<pcl::PointXYZ> impl_;
/** \brief Input point cloud callback.
* Because we want to use the same synchronizer object, we push back
* empty elements with the same timestamp.
*/
inline void
input_callback (const PointCloudConstPtr &input)
{
PointIndices cloud;
cloud.header.stamp = pcl_conversions::fromPCL(input->header).stamp;
nf_.add (boost::make_shared<PointIndices> (cloud));
}
/** \brief Nodelet initialization routine. */
void onInit ();
/** \brief LazyNodelet connection routine. */
void subscribe ();
void unsubscribe ();
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback (ExtractPolygonalPrismDataConfig &config, uint32_t level);
/** \brief Input point cloud callback. Used when \a use_indices is set.
* \param cloud the pointer to the input point cloud
* \param hull the pointer to the planar hull point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_hull_indices_callback (const PointCloudConstPtr &cloud,
const PointCloudConstPtr &hull,
const PointIndicesConstPtr &indices);
private:
/** \brief The PCL implementation used. */
pcl::ExtractPolygonalPrismData<pcl::PointXYZ> impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_EXTRACT_POLYGONAL_PRISM_DATA_H_
@@ -51,235 +51,243 @@
namespace pcl_ros
{
namespace sync_policies = message_filters::sync_policies;
namespace sync_policies = message_filters::sync_policies;
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b SACSegmentation represents the Nodelet segmentation class for Sample Consensus methods and models, in
* the sense that it just creates a Nodelet wrapper for generic-purpose SAC-based segmentation.
* \author Radu Bogdan Rusu
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b SACSegmentation represents the Nodelet segmentation class for Sample Consensus methods and models, in
* the sense that it just creates a Nodelet wrapper for generic-purpose SAC-based segmentation.
* \author Radu Bogdan Rusu
*/
class SACSegmentation : public PCLNodelet
{
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
public:
/** \brief Constructor. */
SACSegmentation()
: min_inliers_(0) {}
/** \brief Set the input TF frame the data should be transformed into before processing, if input.header.frame_id is different.
* \param tf_frame the TF frame the input PointCloud should be transformed into before processing
*/
class SACSegmentation : public PCLNodelet
{
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
inline void setInputTFframe(std::string tf_frame) {tf_input_frame_ = tf_frame;}
public:
/** \brief Constructor. */
SACSegmentation () : min_inliers_(0) {}
/** \brief Get the TF frame the input PointCloud should be transformed into before processing. */
inline std::string getInputTFframe() {return tf_input_frame_;}
/** \brief Set the input TF frame the data should be transformed into before processing, if input.header.frame_id is different.
* \param tf_frame the TF frame the input PointCloud should be transformed into before processing
*/
inline void setInputTFframe (std::string tf_frame) { tf_input_frame_ = tf_frame; }
/** \brief Get the TF frame the input PointCloud should be transformed into before processing. */
inline std::string getInputTFframe () { return (tf_input_frame_); }
/** \brief Set the output TF frame the data should be transformed into after processing.
* \param tf_frame the TF frame the PointCloud should be transformed into after processing
*/
inline void setOutputTFframe (std::string tf_frame) { tf_output_frame_ = tf_frame; }
/** \brief Get the TF frame the PointCloud should be transformed into after processing. */
inline std::string getOutputTFframe () { return (tf_output_frame_); }
protected:
// The minimum number of inliers a model must have in order to be considered valid.
int min_inliers_;
// ROS nodelet attributes
/** \brief The output PointIndices publisher. */
ros::Publisher pub_indices_;
/** \brief The output ModelCoefficients publisher. */
ros::Publisher pub_model_;
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<SACSegmentationConfig> > srv_;
/** \brief The input TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_input_frame_;
/** \brief The original data input TF frame. */
std::string tf_input_orig_frame_;
/** \brief The output TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_output_frame_;
/** \brief Null passthrough filter, used for pushing empty elements in the
* synchronizer */
message_filters::PassThrough<pcl_msgs::PointIndices> nf_pi_;
/** \brief Nodelet initialization routine. */
virtual void onInit ();
/** \brief LazyNodelet connection routine. */
virtual void subscribe ();
virtual void unsubscribe ();
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback (SACSegmentationConfig &config, uint32_t level);
/** \brief Input point cloud callback. Used when \a use_indices is set.
* \param cloud the pointer to the input point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_indices_callback (const PointCloudConstPtr &cloud, const PointIndicesConstPtr &indices);
/** \brief Pointer to a set of indices stored internally.
* (used when \a latched_indices_ is set).
*/
PointIndices indices_;
/** \brief Indices callback. Used when \a latched_indices_ is set.
* \param indices the pointer to the input point cloud indices
*/
inline void
indices_callback (const PointIndicesConstPtr &indices)
{
indices_ = *indices;
}
/** \brief Input callback. Used when \a latched_indices_ is set.
* \param input the pointer to the input point cloud
*/
inline void
input_callback (const PointCloudConstPtr &input)
{
indices_.header = fromPCL(input->header);
PointIndicesConstPtr indices;
indices.reset (new PointIndices (indices_));
nf_pi_.add (indices);
}
private:
/** \brief Internal mutex. */
boost::mutex mutex_;
/** \brief The PCL implementation used. */
pcl::SACSegmentation<pcl::PointXYZ> impl_;
/** \brief Synchronized input, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud, PointIndices> > > sync_input_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud, PointIndices> > > sync_input_indices_a_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b SACSegmentationFromNormals represents the PCL nodelet segmentation class for Sample Consensus methods and
* models that require the use of surface normals for estimation.
/** \brief Set the output TF frame the data should be transformed into after processing.
* \param tf_frame the TF frame the PointCloud should be transformed into after processing
*/
class SACSegmentationFromNormals: public SACSegmentation
inline void setOutputTFframe(std::string tf_frame) {tf_output_frame_ = tf_frame;}
/** \brief Get the TF frame the PointCloud should be transformed into after processing. */
inline std::string getOutputTFframe() {return tf_output_frame_;}
protected:
// The minimum number of inliers a model must have in order to be considered valid.
int min_inliers_;
// ROS nodelet attributes
/** \brief The output PointIndices publisher. */
ros::Publisher pub_indices_;
/** \brief The output ModelCoefficients publisher. */
ros::Publisher pub_model_;
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<SACSegmentationConfig>> srv_;
/** \brief The input TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_input_frame_;
/** \brief The original data input TF frame. */
std::string tf_input_orig_frame_;
/** \brief The output TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_output_frame_;
/** \brief Null passthrough filter, used for pushing empty elements in the
* synchronizer */
message_filters::PassThrough<pcl_msgs::PointIndices> nf_pi_;
/** \brief Nodelet initialization routine. */
virtual void onInit();
/** \brief LazyNodelet connection routine. */
virtual void subscribe();
virtual void unsubscribe();
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback(SACSegmentationConfig & config, uint32_t level);
/** \brief Input point cloud callback. Used when \a use_indices is set.
* \param cloud the pointer to the input point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_indices_callback(
const PointCloudConstPtr & cloud,
const PointIndicesConstPtr & indices);
/** \brief Pointer to a set of indices stored internally.
* (used when \a latched_indices_ is set).
*/
PointIndices indices_;
/** \brief Indices callback. Used when \a latched_indices_ is set.
* \param indices the pointer to the input point cloud indices
*/
inline void
indices_callback(const PointIndicesConstPtr & indices)
{
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
indices_ = *indices;
}
typedef pcl::PointCloud<pcl::Normal> PointCloudN;
typedef boost::shared_ptr<PointCloudN> PointCloudNPtr;
typedef boost::shared_ptr<const PointCloudN> PointCloudNConstPtr;
/** \brief Input callback. Used when \a latched_indices_ is set.
* \param input the pointer to the input point cloud
*/
inline void
input_callback(const PointCloudConstPtr & input)
{
indices_.header = fromPCL(input->header);
PointIndicesConstPtr indices;
indices.reset(new PointIndices(indices_));
nf_pi_.add(indices);
}
public:
/** \brief Set the input TF frame the data should be transformed into before processing, if input.header.frame_id is different.
* \param tf_frame the TF frame the input PointCloud should be transformed into before processing
*/
inline void setInputTFframe (std::string tf_frame) { tf_input_frame_ = tf_frame; }
/** \brief Get the TF frame the input PointCloud should be transformed into before processing. */
inline std::string getInputTFframe () { return (tf_input_frame_); }
private:
/** \brief Internal mutex. */
boost::mutex mutex_;
/** \brief Set the output TF frame the data should be transformed into after processing.
* \param tf_frame the TF frame the PointCloud should be transformed into after processing
*/
inline void setOutputTFframe (std::string tf_frame) { tf_output_frame_ = tf_frame; }
/** \brief Get the TF frame the PointCloud should be transformed into after processing. */
inline std::string getOutputTFframe () { return (tf_output_frame_); }
/** \brief The PCL implementation used. */
pcl::SACSegmentation<pcl::PointXYZ> impl_;
protected:
// ROS nodelet attributes
/** \brief The normals PointCloud subscriber filter. */
message_filters::Subscriber<PointCloudN> sub_normals_filter_;
/** \brief Synchronized input, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud,
PointIndices>>> sync_input_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud,
PointIndices>>> sync_input_indices_a_;
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_axis_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<SACSegmentationFromNormalsConfig> > srv_;
/** \brief Input point cloud callback.
* Because we want to use the same synchronizer object, we push back
* empty elements with the same timestamp.
*/
inline void
input_callback (const PointCloudConstPtr &cloud)
{
PointIndices indices;
indices.header.stamp = fromPCL(cloud->header).stamp;
nf_.add (boost::make_shared<PointIndices> (indices));
}
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b SACSegmentationFromNormals represents the PCL nodelet segmentation class for Sample Consensus methods and
* models that require the use of surface normals for estimation.
*/
class SACSegmentationFromNormals : public SACSegmentation
{
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
/** \brief Null passthrough filter, used for pushing empty elements in the
* synchronizer */
message_filters::PassThrough<PointIndices> nf_;
typedef pcl::PointCloud<pcl::Normal> PointCloudN;
typedef boost::shared_ptr<PointCloudN> PointCloudNPtr;
typedef boost::shared_ptr<const PointCloudN> PointCloudNConstPtr;
/** \brief The input TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_input_frame_;
/** \brief The original data input TF frame. */
std::string tf_input_orig_frame_;
/** \brief The output TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_output_frame_;
public:
/** \brief Set the input TF frame the data should be transformed into before processing, if input.header.frame_id is different.
* \param tf_frame the TF frame the input PointCloud should be transformed into before processing
*/
inline void setInputTFframe(std::string tf_frame) {tf_input_frame_ = tf_frame;}
/** \brief Nodelet initialization routine. */
virtual void onInit ();
/** \brief Get the TF frame the input PointCloud should be transformed into before processing. */
inline std::string getInputTFframe() {return tf_input_frame_;}
/** \brief LazyNodelet connection routine. */
virtual void subscribe ();
virtual void unsubscribe ();
/** \brief Set the output TF frame the data should be transformed into after processing.
* \param tf_frame the TF frame the PointCloud should be transformed into after processing
*/
inline void setOutputTFframe(std::string tf_frame) {tf_output_frame_ = tf_frame;}
/** \brief Model callback
* \param model the sample consensus model found
*/
void axis_callback (const pcl_msgs::ModelCoefficientsConstPtr &model);
/** \brief Get the TF frame the PointCloud should be transformed into after processing. */
inline std::string getOutputTFframe() {return tf_output_frame_;}
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback (SACSegmentationFromNormalsConfig &config, uint32_t level);
protected:
// ROS nodelet attributes
/** \brief The normals PointCloud subscriber filter. */
message_filters::Subscriber<PointCloudN> sub_normals_filter_;
/** \brief Input point cloud callback.
* \param cloud the pointer to the input point cloud
* \param cloud_normals the pointer to the input point cloud normals
* \param indices the pointer to the input point cloud indices
*/
void input_normals_indices_callback (const PointCloudConstPtr &cloud,
const PointCloudNConstPtr &cloud_normals,
const PointIndicesConstPtr &indices);
private:
/** \brief Internal mutex. */
boost::mutex mutex_;
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_axis_;
/** \brief The PCL implementation used. */
pcl::SACSegmentationFromNormals<pcl::PointXYZ, pcl::Normal> impl_;
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<SACSegmentationFromNormalsConfig>> srv_;
/** \brief Synchronized input, normals, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud, PointCloudN, PointIndices> > > sync_input_normals_indices_a_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud, PointCloudN, PointIndices> > > sync_input_normals_indices_e_;
/** \brief Input point cloud callback.
* Because we want to use the same synchronizer object, we push back
* empty elements with the same timestamp.
*/
inline void
input_callback(const PointCloudConstPtr & cloud)
{
PointIndices indices;
indices.header.stamp = fromPCL(cloud->header).stamp;
nf_.add(boost::make_shared<PointIndices>(indices));
}
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
/** \brief Null passthrough filter, used for pushing empty elements in the
* synchronizer */
message_filters::PassThrough<PointIndices> nf_;
/** \brief The input TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_input_frame_;
/** \brief The original data input TF frame. */
std::string tf_input_orig_frame_;
/** \brief The output TF frame the data should be transformed into, if input.header.frame_id is different. */
std::string tf_output_frame_;
/** \brief Nodelet initialization routine. */
virtual void onInit();
/** \brief LazyNodelet connection routine. */
virtual void subscribe();
virtual void unsubscribe();
/** \brief Model callback
* \param model the sample consensus model found
*/
void axis_callback(const pcl_msgs::ModelCoefficientsConstPtr & model);
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback(SACSegmentationFromNormalsConfig & config, uint32_t level);
/** \brief Input point cloud callback.
* \param cloud the pointer to the input point cloud
* \param cloud_normals the pointer to the input point cloud normals
* \param indices the pointer to the input point cloud indices
*/
void input_normals_indices_callback(
const PointCloudConstPtr & cloud,
const PointCloudNConstPtr & cloud_normals,
const PointIndicesConstPtr & indices);
private:
/** \brief Internal mutex. */
boost::mutex mutex_;
/** \brief The PCL implementation used. */
pcl::SACSegmentationFromNormals<pcl::PointXYZ, pcl::Normal> impl_;
/** \brief Synchronized input, normals, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud,
PointCloudN, PointIndices>>> sync_input_normals_indices_a_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud, PointCloudN,
PointIndices>>> sync_input_normals_indices_e_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_SAC_SEGMENTATION_H_
@@ -48,63 +48,66 @@
namespace pcl_ros
{
namespace sync_policies = message_filters::sync_policies;
namespace sync_policies = message_filters::sync_policies;
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b SegmentDifferences obtains the difference between two spatially aligned point clouds and returns the
* difference between them for a maximum given distance threshold.
* \author Radu Bogdan Rusu
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b SegmentDifferences obtains the difference between two spatially aligned point clouds and returns the
* difference between them for a maximum given distance threshold.
* \author Radu Bogdan Rusu
*/
class SegmentDifferences : public PCLNodelet
{
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
public:
/** \brief Empty constructor. */
SegmentDifferences() {}
protected:
/** \brief The message filter subscriber for PointCloud2. */
message_filters::Subscriber<PointCloud> sub_target_filter_;
/** \brief Synchronized input, and planar hull.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud,
PointCloud>>> sync_input_target_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud,
PointCloud>>> sync_input_target_a_;
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<SegmentDifferencesConfig>> srv_;
/** \brief Nodelet initialization routine. */
void onInit();
/** \brief LazyNodelet connection routine. */
void subscribe();
void unsubscribe();
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
class SegmentDifferences : public PCLNodelet
{
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
void config_callback(SegmentDifferencesConfig & config, uint32_t level);
public:
/** \brief Empty constructor. */
SegmentDifferences () {};
protected:
/** \brief The message filter subscriber for PointCloud2. */
message_filters::Subscriber<PointCloud> sub_target_filter_;
/** \brief Input point cloud callback.
* \param cloud the pointer to the input point cloud
* \param cloud_target the pointcloud that we want to segment \a cloud from
*/
void input_target_callback(
const PointCloudConstPtr & cloud,
const PointCloudConstPtr & cloud_target);
/** \brief Synchronized input, and planar hull.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud, PointCloud> > > sync_input_target_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud, PointCloud> > > sync_input_target_a_;
private:
/** \brief The PCL implementation used. */
pcl::SegmentDifferences<pcl::PointXYZ> impl_;
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<SegmentDifferencesConfig> > srv_;
/** \brief Nodelet initialization routine. */
void onInit ();
/** \brief LazyNodelet connection routine. */
void subscribe ();
void unsubscribe ();
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback (SegmentDifferencesConfig &config, uint32_t level);
/** \brief Input point cloud callback.
* \param cloud the pointer to the input point cloud
* \param cloud_target the pointcloud that we want to segment \a cloud from
*/
void input_target_callback (const PointCloudConstPtr &cloud,
const PointCloudConstPtr &cloud_target);
private:
/** \brief The PCL implementation used. */
pcl::SegmentDifferences<pcl::PointXYZ> impl_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_SEGMENT_DIFFERENCES_H_
+39 -36
View File
@@ -48,49 +48,52 @@
namespace pcl_ros
{
namespace sync_policies = message_filters::sync_policies;
namespace sync_policies = message_filters::sync_policies;
/** \brief @b ConvexHull2D represents a 2D ConvexHull implementation.
* \author Radu Bogdan Rusu
/** \brief @b ConvexHull2D represents a 2D ConvexHull implementation.
* \author Radu Bogdan Rusu
*/
class ConvexHull2D : public PCLNodelet
{
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
private:
/** \brief Nodelet initialization routine. */
virtual void onInit();
/** \brief LazyNodelet connection routine. */
virtual void subscribe();
virtual void unsubscribe();
/** \brief Input point cloud callback.
* \param cloud the pointer to the input point cloud
* \param indices the pointer to the input point cloud indices
*/
class ConvexHull2D : public PCLNodelet
{
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
typedef boost::shared_ptr<PointCloud> PointCloudPtr;
typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr;
void input_indices_callback(
const PointCloudConstPtr & cloud,
const PointIndicesConstPtr & indices);
private:
/** \brief Nodelet initialization routine. */
virtual void onInit ();
private:
/** \brief The PCL implementation used. */
pcl::ConvexHull<pcl::PointXYZ> impl_;
/** \brief LazyNodelet connection routine. */
virtual void subscribe ();
virtual void unsubscribe ();
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief Input point cloud callback.
* \param cloud the pointer to the input point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_indices_callback (const PointCloudConstPtr &cloud,
const PointIndicesConstPtr &indices);
/** \brief Publisher for PolygonStamped. */
ros::Publisher pub_plane_;
private:
/** \brief The PCL implementation used. */
pcl::ConvexHull<pcl::PointXYZ> impl_;
/** \brief Synchronized input, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud,
PointIndices>>> sync_input_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud,
PointIndices>>> sync_input_indices_a_;
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief Publisher for PolygonStamped. */
ros::Publisher pub_plane_;
/** \brief Synchronized input, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloud, PointIndices> > > sync_input_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud, PointIndices> > > sync_input_indices_a_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_CONVEX_HULL_2D_H_
@@ -46,105 +46,107 @@
// Dynamic reconfigure
#include <dynamic_reconfigure/server.h>
#include "pcl_ros/MLSConfig.h"
#include "pcl_ros/MLSConfig.h"
namespace pcl_ros
{
namespace sync_policies = message_filters::sync_policies;
namespace sync_policies = message_filters::sync_policies;
/** \brief @b MovingLeastSquares represents a nodelet using the MovingLeastSquares implementation.
* The type of the output is the same as the input, it only smooths the XYZ coordinates according to the parameters.
* Normals are estimated at each point as well and published on a separate topic.
* \author Radu Bogdan Rusu, Zoltan-Csaba Marton
/** \brief @b MovingLeastSquares represents a nodelet using the MovingLeastSquares implementation.
* The type of the output is the same as the input, it only smooths the XYZ coordinates according to the parameters.
* Normals are estimated at each point as well and published on a separate topic.
* \author Radu Bogdan Rusu, Zoltan-Csaba Marton
*/
class MovingLeastSquares : public PCLNodelet
{
typedef pcl::PointXYZ PointIn;
typedef pcl::PointNormal NormalOut;
typedef pcl::PointCloud<PointIn> PointCloudIn;
typedef boost::shared_ptr<PointCloudIn> PointCloudInPtr;
typedef boost::shared_ptr<const PointCloudIn> PointCloudInConstPtr;
typedef pcl::PointCloud<NormalOut> NormalCloudOut;
typedef pcl::KdTree<PointIn> KdTree;
typedef pcl::KdTree<PointIn>::Ptr KdTreePtr;
protected:
/** \brief An input point cloud describing the surface that is to be used for nearest neighbors estimation. */
PointCloudInConstPtr surface_;
/** \brief A pointer to the spatial search object. */
KdTreePtr tree_;
/** \brief The nearest neighbors search radius for each point. */
double search_radius_;
/** \brief The number of K nearest neighbors to use for each point. */
//int k_;
/** \brief Whether to use a polynomial fit. */
bool use_polynomial_fit_;
/** \brief The order of the polynomial to be fit. */
int polynomial_order_;
/** \brief How 'flat' should the neighbor weighting gaussian be (the smaller, the more local the fit). */
double gaussian_parameter_;
// ROS nodelet attributes
/** \brief The surface PointCloud subscriber filter. */
message_filters::Subscriber<PointCloudIn> sub_surface_filter_;
/** \brief Parameter for the spatial locator tree. By convention, the values represent:
* 0: ANN (Approximate Nearest Neigbor library) kd-tree
* 1: FLANN (Fast Library for Approximate Nearest Neighbors) kd-tree
* 2: Organized spatial dataset index
*/
class MovingLeastSquares : public PCLNodelet
{
typedef pcl::PointXYZ PointIn;
typedef pcl::PointNormal NormalOut;
int spatial_locator_type_;
typedef pcl::PointCloud<PointIn> PointCloudIn;
typedef boost::shared_ptr<PointCloudIn> PointCloudInPtr;
typedef boost::shared_ptr<const PointCloudIn> PointCloudInConstPtr;
typedef pcl::PointCloud<NormalOut> NormalCloudOut;
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr<dynamic_reconfigure::Server<MLSConfig>> srv_;
typedef pcl::KdTree<PointIn> KdTree;
typedef pcl::KdTree<PointIn>::Ptr KdTreePtr;
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback(MLSConfig & config, uint32_t level);
protected:
/** \brief An input point cloud describing the surface that is to be used for nearest neighbors estimation. */
PointCloudInConstPtr surface_;
/** \brief Nodelet initialization routine. */
virtual void onInit();
/** \brief A pointer to the spatial search object. */
KdTreePtr tree_;
/** \brief LazyNodelet connection routine. */
virtual void subscribe();
virtual void unsubscribe();
/** \brief The nearest neighbors search radius for each point. */
double search_radius_;
private:
/** \brief Input point cloud callback.
* \param cloud the pointer to the input point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_indices_callback(
const PointCloudInConstPtr & cloud,
const PointIndicesConstPtr & indices);
/** \brief The number of K nearest neighbors to use for each point. */
//int k_;
private:
/** \brief The PCL implementation used. */
pcl::MovingLeastSquares<PointIn, NormalOut> impl_;
/** \brief Whether to use a polynomial fit. */
bool use_polynomial_fit_;
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief The order of the polynomial to be fit. */
int polynomial_order_;
/** \brief The output PointCloud (containing the normals) publisher. */
ros::Publisher pub_normals_;
/** \brief How 'flat' should the neighbor weighting gaussian be (the smaller, the more local the fit). */
double gaussian_parameter_;
/** \brief Synchronized input, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloudIn,
PointIndices>>> sync_input_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloudIn,
PointIndices>>> sync_input_indices_a_;
// ROS nodelet attributes
/** \brief The surface PointCloud subscriber filter. */
message_filters::Subscriber<PointCloudIn> sub_surface_filter_;
/** \brief Parameter for the spatial locator tree. By convention, the values represent:
* 0: ANN (Approximate Nearest Neigbor library) kd-tree
* 1: FLANN (Fast Library for Approximate Nearest Neighbors) kd-tree
* 2: Organized spatial dataset index
*/
int spatial_locator_type_;
/** \brief Pointer to a dynamic reconfigure service. */
boost::shared_ptr <dynamic_reconfigure::Server<MLSConfig> > srv_;
/** \brief Dynamic reconfigure callback
* \param config the config object
* \param level the dynamic reconfigure level
*/
void config_callback (MLSConfig &config, uint32_t level);
/** \brief Nodelet initialization routine. */
virtual void onInit ();
/** \brief LazyNodelet connection routine. */
virtual void subscribe ();
virtual void unsubscribe ();
private:
/** \brief Input point cloud callback.
* \param cloud the pointer to the input point cloud
* \param indices the pointer to the input point cloud indices
*/
void input_indices_callback (const PointCloudInConstPtr &cloud,
const PointIndicesConstPtr &indices);
private:
/** \brief The PCL implementation used. */
pcl::MovingLeastSquares<PointIn, NormalOut> impl_;
/** \brief The input PointCloud subscriber. */
ros::Subscriber sub_input_;
/** \brief The output PointCloud (containing the normals) publisher. */
ros::Publisher pub_normals_;
/** \brief Synchronized input, and indices.*/
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ExactTime<PointCloudIn, PointIndices> > > sync_input_indices_e_;
boost::shared_ptr<message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloudIn, PointIndices> > > sync_input_indices_a_;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
#endif //#ifndef PCL_ROS_MOVING_LEAST_SQUARES_H_
+123 -109
View File
@@ -44,124 +44,138 @@
namespace pcl_ros
{
/** \brief Transform a point cloud and rotate its normals using an Eigen transform.
* \param cloud_in the input point cloud
* \param cloud_out the input point cloud
* \param transform a rigid transformation from tf
* \note calls the Eigen version
*/
template <typename PointT> void
transformPointCloudWithNormals (const pcl::PointCloud <PointT> &cloud_in,
pcl::PointCloud <PointT> &cloud_out,
const tf::Transform &transform);
/** \brief Transform a point cloud and rotate its normals using an Eigen transform.
* \param cloud_in the input point cloud
* \param cloud_out the input point cloud
* \param transform a rigid transformation from tf
* \note calls the Eigen version
*/
template<typename PointT>
void
transformPointCloudWithNormals(
const pcl::PointCloud<PointT> & cloud_in,
pcl::PointCloud<PointT> & cloud_out,
const tf::Transform & transform);
/** \brief Transforms a point cloud in a given target TF frame using a TransformListener
* \param target_frame the target TF frame the point cloud should be transformed to
* \param cloud_in the input point cloud
* \param cloud_out the input point cloud
* \param tf_listener a TF listener object
*/
template <typename PointT> bool
transformPointCloudWithNormals (const std::string &target_frame,
const pcl::PointCloud <PointT> &cloud_in,
pcl::PointCloud <PointT> &cloud_out,
const tf::TransformListener &tf_listener);
/** \brief Transforms a point cloud in a given target TF frame using a TransformListener
* \param target_frame the target TF frame the point cloud should be transformed to
* \param cloud_in the input point cloud
* \param cloud_out the input point cloud
* \param tf_listener a TF listener object
*/
template<typename PointT>
bool
transformPointCloudWithNormals(
const std::string & target_frame,
const pcl::PointCloud<PointT> & cloud_in,
pcl::PointCloud<PointT> & cloud_out,
const tf::TransformListener & tf_listener);
/** \brief Transforms a point cloud in a given target TF frame using a TransformListener
* \param target_frame the target TF frame the point cloud should be transformed to
* \param target_time the target timestamp
* \param cloud_in the input point cloud
* \param fixed_frame fixed TF frame
* \param cloud_out the input point cloud
* \param tf_listener a TF listener object
*/
template <typename PointT> bool
transformPointCloudWithNormals (const std::string &target_frame,
const ros::Time & target_time,
const pcl::PointCloud <PointT> &cloud_in,
const std::string &fixed_frame,
pcl::PointCloud <PointT> &cloud_out,
const tf::TransformListener &tf_listener);
/** \brief Transforms a point cloud in a given target TF frame using a TransformListener
* \param target_frame the target TF frame the point cloud should be transformed to
* \param target_time the target timestamp
* \param cloud_in the input point cloud
* \param fixed_frame fixed TF frame
* \param cloud_out the input point cloud
* \param tf_listener a TF listener object
*/
template<typename PointT>
bool
transformPointCloudWithNormals(
const std::string & target_frame,
const ros::Time & target_time,
const pcl::PointCloud<PointT> & cloud_in,
const std::string & fixed_frame,
pcl::PointCloud<PointT> & cloud_out,
const tf::TransformListener & tf_listener);
/** \brief Apply a rigid transform defined by a 3D offset and a quaternion
* \param cloud_in the input point cloud
* \param cloud_out the input point cloud
* \param transform a rigid transformation from tf
* \note calls the Eigen version
*/
template <typename PointT> void
transformPointCloud (const pcl::PointCloud <PointT> &cloud_in,
pcl::PointCloud <PointT> &cloud_out,
const tf::Transform &transform);
/** \brief Apply a rigid transform defined by a 3D offset and a quaternion
* \param cloud_in the input point cloud
* \param cloud_out the input point cloud
* \param transform a rigid transformation from tf
* \note calls the Eigen version
*/
template<typename PointT>
void
transformPointCloud(
const pcl::PointCloud<PointT> & cloud_in,
pcl::PointCloud<PointT> & cloud_out,
const tf::Transform & transform);
/** \brief Transforms a point cloud in a given target TF frame using a TransformListener
* \param target_frame the target TF frame the point cloud should be transformed to
* \param cloud_in the input point cloud
* \param cloud_out the input point cloud
* \param tf_listener a TF listener object
*/
template <typename PointT> bool
transformPointCloud (const std::string &target_frame,
const pcl::PointCloud <PointT> &cloud_in,
pcl::PointCloud <PointT> &cloud_out,
const tf::TransformListener &tf_listener);
/** \brief Transforms a point cloud in a given target TF frame using a TransformListener
* \param target_frame the target TF frame the point cloud should be transformed to
* \param cloud_in the input point cloud
* \param cloud_out the input point cloud
* \param tf_listener a TF listener object
*/
template<typename PointT>
bool
transformPointCloud(
const std::string & target_frame,
const pcl::PointCloud<PointT> & cloud_in,
pcl::PointCloud<PointT> & cloud_out,
const tf::TransformListener & tf_listener);
/** \brief Transforms a point cloud in a given target TF frame using a TransformListener
* \param target_frame the target TF frame the point cloud should be transformed to
* \param target_time the target timestamp
* \param cloud_in the input point cloud
* \param fixed_frame fixed TF frame
* \param cloud_out the input point cloud
* \param tf_listener a TF listener object
*/
template <typename PointT> bool
transformPointCloud (const std::string &target_frame, const ros::Time & target_time,
const pcl::PointCloud <PointT> &cloud_in,
const std::string &fixed_frame,
pcl::PointCloud <PointT> &cloud_out,
const tf::TransformListener &tf_listener);
/** \brief Transforms a point cloud in a given target TF frame using a TransformListener
* \param target_frame the target TF frame the point cloud should be transformed to
* \param target_time the target timestamp
* \param cloud_in the input point cloud
* \param fixed_frame fixed TF frame
* \param cloud_out the input point cloud
* \param tf_listener a TF listener object
*/
template<typename PointT>
bool
transformPointCloud(
const std::string & target_frame, const ros::Time & target_time,
const pcl::PointCloud<PointT> & cloud_in,
const std::string & fixed_frame,
pcl::PointCloud<PointT> & cloud_out,
const tf::TransformListener & tf_listener);
/** \brief Transform a sensor_msgs::PointCloud2 dataset from its frame to a given TF target frame.
* \param target_frame the target TF frame
* \param in the input PointCloud2 dataset
* \param out the resultant transformed PointCloud2 dataset
* \param tf_listener a TF listener object
*/
bool
transformPointCloud (const std::string &target_frame,
const sensor_msgs::PointCloud2 &in,
sensor_msgs::PointCloud2 &out,
const tf::TransformListener &tf_listener);
/** \brief Transform a sensor_msgs::PointCloud2 dataset from its frame to a given TF target frame.
* \param target_frame the target TF frame
* \param in the input PointCloud2 dataset
* \param out the resultant transformed PointCloud2 dataset
* \param tf_listener a TF listener object
*/
bool
transformPointCloud(
const std::string & target_frame,
const sensor_msgs::PointCloud2 & in,
sensor_msgs::PointCloud2 & out,
const tf::TransformListener & tf_listener);
/** \brief Transform a sensor_msgs::PointCloud2 dataset from its frame to a given TF target frame.
* \param target_frame the target TF frame
* \param net_transform the TF transformer object
* \param in the input PointCloud2 dataset
* \param out the resultant transformed PointCloud2 dataset
*/
void
transformPointCloud (const std::string &target_frame,
const tf::Transform &net_transform,
const sensor_msgs::PointCloud2 &in,
sensor_msgs::PointCloud2 &out);
/** \brief Transform a sensor_msgs::PointCloud2 dataset from its frame to a given TF target frame.
* \param target_frame the target TF frame
* \param net_transform the TF transformer object
* \param in the input PointCloud2 dataset
* \param out the resultant transformed PointCloud2 dataset
*/
void
transformPointCloud(
const std::string & target_frame,
const tf::Transform & net_transform,
const sensor_msgs::PointCloud2 & in,
sensor_msgs::PointCloud2 & out);
/** \brief Transform a sensor_msgs::PointCloud2 dataset using an Eigen 4x4 matrix.
* \param transform the transformation to use on the points
* \param in the input PointCloud2 dataset
* \param out the resultant transformed PointCloud2 dataset
*/
void
transformPointCloud (const Eigen::Matrix4f &transform,
const sensor_msgs::PointCloud2 &in,
sensor_msgs::PointCloud2 &out);
/** \brief Transform a sensor_msgs::PointCloud2 dataset using an Eigen 4x4 matrix.
* \param transform the transformation to use on the points
* \param in the input PointCloud2 dataset
* \param out the resultant transformed PointCloud2 dataset
*/
void
transformPointCloud(
const Eigen::Matrix4f & transform,
const sensor_msgs::PointCloud2 & in,
sensor_msgs::PointCloud2 & out);
/** \brief Obtain the transformation matrix from TF into an Eigen form
* \param bt the TF transformation
* \param out_mat the Eigen transformation
*/
void
transformAsMatrix (const tf::Transform& bt, Eigen::Matrix4f &out_mat);
/** \brief Obtain the transformation matrix from TF into an Eigen form
* \param bt the TF transformation
* \param out_mat the Eigen transformation
*/
void
transformAsMatrix(const tf::Transform & bt, Eigen::Matrix4f & out_mat);
}
#endif // PCL_ROS_TRANSFORMS_H_