Go to the documentation of this file.00001
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 #include <ros/ros.h>
00074 #include <nodelet/nodelet.h>
00075 #include <pluginlib/class_list_macros.h>
00076 #include <tf/transform_listener.h>
00077 #include <tf_conversions/tf_eigen.h>
00078 #include <pcl_ros/point_cloud.h>
00079 #include <pcl/point_types.h>
00080 #include <pcl/segmentation/extract_polygonal_prism_data.h>
00081 #include <pcl/filters/extract_indices.h>
00082
00083 #include <cob_3d_mapping_common/stop_watch.h>
00084
00085 namespace cob_table_object_cluster
00086 {
00087
00088
00089 class TableRegionCropNodelet : public nodelet::Nodelet
00090 {
00091 public:
00092 typedef pcl::PointXYZRGB Point;
00093 typedef pcl::PointCloud<Point> PointCloud;
00094
00095
00096 TableRegionCropNodelet()
00097 : target_frame_id_("/map"),
00098 table_frame_id_("/bookshelf_bottom_link"),
00099 height_min_(0.01),
00100 height_max_(0.5),
00101 hull_(new PointCloud)
00102 {
00103 hull_points_.resize(4);
00104 hull_->resize(4);
00105 }
00106
00107
00108 ~TableRegionCropNodelet()
00109 {
00111 }
00112
00113 void
00114 onInit()
00115 {
00116 n_ = getNodeHandle();
00117
00118 ros::NodeHandle pn = getPrivateNodeHandle();
00119 pn.getParam("target_frame_id", target_frame_id_);
00120 pn.getParam("table_frame_id", table_frame_id_);
00121 pn.getParam("height_min", height_min_);
00122 pn.getParam("height_max", height_max_);
00123 XmlRpc::XmlRpcValue v;
00124 pn.getParam("table_dimensions", v);
00125 if( v.size() < 3)
00126 {
00127 ROS_ERROR("Hull points not set correctly, nodelet will not work");
00128 return;
00129 }
00130 double x ,y, z;
00131 x = (double)v[0];
00132 y = (double)v[1];
00133 z = (double)v[2];
00134 Eigen::Vector3d p;
00135 p << -x/2, -y/2, z;
00136 hull_points_[0] = p;
00137 p << -x/2, y/2, z;
00138 hull_points_[1] = p;
00139 p << x/2, y/2, z;
00140 hull_points_[2] = p;
00141 p << x/2, -y/2, z;
00142 hull_points_[3] = p;
00143
00144 tf::StampedTransform trf_table;
00145 try
00146 {
00147 tf_listener_.waitForTransform(target_frame_id_, table_frame_id_, ros::Time(), ros::Duration(2));
00148 tf_listener_.lookupTransform(target_frame_id_, table_frame_id_, ros::Time(), trf_table);
00149 }
00150 catch (tf::TransformException& ex) { ROS_ERROR("[transform region crop] : %s",ex.what()); return; }
00151 Eigen::Affine3d ad;
00152 tf::transformTFToEigen(trf_table, ad);
00153
00154 for(int i = 0; i < hull_points_.size(); i++)
00155 {
00156 Point p;
00157 p.getVector3fMap() = (ad*hull_points_[i]).cast<float>();
00158 hull_->points[i] = p;
00159 }
00160
00161 pc_sub_ = n_.subscribe<PointCloud>("point_cloud_in", 1, boost::bind(&TableRegionCropNodelet::topicCallback, this, _1));
00162 pc_pub_ = n_.advertise<PointCloud>("point_cloud_out", 1);
00163
00164 eppd_.setInputPlanarHull(hull_);
00165 eppd_.setHeightLimits(height_min_, height_max_);
00166 eppd_.setViewPoint(0,0,5);
00167 }
00168
00169 void
00170 topicCallback(const PointCloud::ConstPtr& pc_in)
00171 {
00172 if(pc_in->header.frame_id != target_frame_id_)
00173 {
00174 ROS_ERROR("Frame ID (%s) of incoming point cloud does not match target frame ID (%s), aborting...", pc_in->header.frame_id.c_str(), target_frame_id_.c_str());
00175 return;
00176 }
00177
00178 PointCloud::Ptr pc_out(new PointCloud);
00179 pcl::PointIndices::Ptr ind_out(new pcl::PointIndices);
00180 eppd_.setInputCloud(pc_in);
00181 eppd_.segment(*ind_out);
00182 ei_.setInputCloud(pc_in);
00183 ei_.setIndices(ind_out);
00184 ei_.filter(*pc_out);
00185 pc_pub_.publish(pc_out);
00186 }
00187
00188
00189 protected:
00190 ros::NodeHandle n_;
00191 ros::Subscriber pc_sub_;
00192 ros::Publisher pc_pub_;
00193 tf::TransformListener tf_listener_;
00194 std::string target_frame_id_;
00195 std::string table_frame_id_;
00196 double height_min_, height_max_;
00197
00198 std::vector<Eigen::Vector3d> hull_points_;
00199 PointCloud::Ptr hull_;
00200 pcl::ExtractPolygonalPrismData<Point> eppd_;
00201 pcl::ExtractIndices<Point> ei_;
00202 };
00203 }
00204
00205 PLUGINLIB_DECLARE_CLASS(cob_table_object_cluster, TableRegionCropNodelet, cob_table_object_cluster::TableRegionCropNodelet, nodelet::Nodelet);
00206
00207