Go to the documentation of this file.00001
00064
00065
00066
00067
00068
00069 #include <sstream>
00070 #include <fstream>
00071
00072
00073 #include <ros/ros.h>
00074 #include <pluginlib/class_list_macros.h>
00075 #include <nodelet/nodelet.h>
00076 #include <pcl/io/io.h>
00077 #include <pcl/io/pcd_io.h>
00078 #include <pcl/point_types.h>
00079 #include <tf/transform_listener.h>
00080 #include <pcl_ros/point_cloud.h>
00081 #include <actionlib/server/simple_action_server.h>
00082 #include <pcl/point_types.h>
00083
00084 #include <dynamic_reconfigure/server.h>
00085 #include <cob_table_object_cluster/table_object_cluster_nodeletConfig.h>
00086
00087
00088
00089
00090
00091 #include <cob_3d_mapping_msgs/GetPlane.h>
00092 #include <cob_3d_mapping_msgs/GetBoundingBoxes.h>
00093
00094
00095 #include <boost/timer.hpp>
00096 #include <Eigen/StdVector>
00097
00098 #include "cob_table_object_cluster/table_object_cluster.h"
00099 #include "cob_3d_mapping_msgs/TableObjectClusterAction.h"
00100
00101 using namespace cob_table_object_cluster;
00102
00103
00104
00105
00106 class TableObjectClusterNodelet : public nodelet::Nodelet
00107 {
00108 public:
00109 typedef pcl::PointXYZRGB Point;
00110
00111 TableObjectClusterNodelet()
00112 : as_(0)
00113 {
00114 save_to_file_ = table_object_cluster_nodeletConfig::__getDefault__().save;
00115 file_path_ = table_object_cluster_nodeletConfig::__getDefault__().file_path;
00116 }
00117
00118
00119 ~TableObjectClusterNodelet()
00120 {
00122 if(as_) delete as_;
00123 }
00124
00132 void
00133 dynReconfCallback(table_object_cluster_nodeletConfig &config, uint32_t level)
00134 {
00135 save_to_file_ = config.save;
00136 file_path_ = config.file_path;
00137
00138
00139
00140
00141 toc.setPrismHeight(config.height_min, config.height_max);
00142 toc.setClusterParams(config.min_cluster_size, config.cluster_tolerance);
00143 }
00144
00152 void onInit()
00153 {
00154
00155 n_ = getNodeHandle();
00156
00157 config_server_.setCallback(boost::bind(&TableObjectClusterNodelet::dynReconfCallback, this, _1, _2));
00158
00159 get_plane_client_ = n_.serviceClient<cob_3d_mapping_msgs::GetPlane>("get_plane");
00160 get_bb_client_ = n_.serviceClient<cob_3d_mapping_msgs::GetBoundingBoxes>("get_known_objects");
00161 as_= new actionlib::SimpleActionServer<cob_3d_mapping_msgs::TableObjectClusterAction>(n_, "table_object_cluster", boost::bind(&TableObjectClusterNodelet::actionCallback, this, _1), false);
00162 as_->start();
00163 }
00164
00165
00175 void
00176 actionCallback(const cob_3d_mapping_msgs::TableObjectClusterGoalConstPtr &goal)
00177 {
00178 ROS_INFO("action callback");
00179 cob_3d_mapping_msgs::TableObjectClusterFeedback feedback;
00180 cob_3d_mapping_msgs::TableObjectClusterResult result;
00181 cob_3d_mapping_msgs::GetPlane srv;
00182 if(!get_plane_client_.call(srv))
00183 {
00184 ROS_ERROR("Failed to call service get_plane");
00185 as_->setAborted();
00186 return;
00187 }
00188 pcl::PointCloud<Point>::Ptr pc(new pcl::PointCloud<Point>);
00189 pcl::PointCloud<Point>::Ptr hull(new pcl::PointCloud<Point>);
00190 pcl::fromROSMsg(srv.response.pc, *pc);
00191 pcl::fromROSMsg(srv.response.hull, *hull);
00192 Eigen::Vector4f plane_coeffs(srv.response.plane_coeffs[0].data,
00193 srv.response.plane_coeffs[1].data,
00194 srv.response.plane_coeffs[2].data,
00195 srv.response.plane_coeffs[3].data);
00196 ROS_INFO("Hull size: %d", hull->size());
00197
00198 pcl::PointCloud<Point>::Ptr pc_roi(new pcl::PointCloud<Point>);
00199 toc.extractTableRoi(pc, hull, *pc_roi);
00200
00201 ROS_INFO("ROI size: %d", pc_roi->size());
00202
00203 pcl::PointCloud<Point>::Ptr pc_roi_red(new pcl::PointCloud<Point>);
00204 cob_3d_mapping_msgs::GetBoundingBoxes srv2;
00205 if(get_bb_client_.call(srv2))
00206 {
00207 std::vector<pcl::PointCloud<pcl::PointXYZ>, Eigen::aligned_allocator<pcl::PointCloud<pcl::PointXYZ> > > known_objs;
00208 for(unsigned int i=0; i<srv2.response.bounding_boxes.size(); i++)
00209 {
00210 pcl::PointCloud<pcl::PointXYZ> obj;
00211 pcl::fromROSMsg(srv2.response.bounding_boxes[i], obj);
00212 known_objs.push_back(obj);
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 toc.removeKnownObjects(pc_roi, known_objs, *pc_roi_red);
00226 }
00227 else
00228 {
00229 ROS_WARN("Failed to call service get_bounding_boxes");
00230 pc_roi_red = pc_roi;
00231 }
00232
00233 std::vector<pcl::PointCloud<pcl::PointXYZ>, Eigen::aligned_allocator<pcl::PointCloud<pcl::PointXYZ> > > bounding_boxes;
00234 toc.calculateBoundingBoxes(pc_roi_red,bounding_boxes);
00235 for(unsigned int i=0; i< bounding_boxes.size(); i++)
00236 {
00237 sensor_msgs::PointCloud2 bb;
00238 pcl::toROSMsg(bounding_boxes[i], bb);
00239 result.bounding_boxes.push_back(bb);
00240 }
00241
00242 if(save_to_file_)
00243 {
00244 std::stringstream ss;
00245 ss << file_path_ << "/pc.pcd";
00246 pcl::io::savePCDFileASCII (ss.str(), *pc);
00247 ss.str("");
00248 ss.clear();
00249 ss << file_path_ << "/hull.pcd";
00250 pcl::io::savePCDFileASCII (ss.str(), *hull);
00251 ss.str("");
00252 ss.clear();
00253 ss << file_path_ << "/table_roi.pcd";
00254 pcl::io::savePCDFileASCII (ss.str(), *pc_roi);
00255 ss.str("");
00256 ss.clear();
00257 ss << file_path_ << "/table_roi_red.pcd";
00258 pcl::io::savePCDFileASCII (ss.str(), *pc_roi_red);
00259 ss.str("");
00260 ss.clear();
00261 for(unsigned int i=0; i< bounding_boxes.size(); i++)
00262 {
00263 ss << file_path_ << "/bb_" << i << ".pcd";
00264 pcl::io::savePCDFileASCII (ss.str(), bounding_boxes[i]);
00265 ss.str("");
00266 ss.clear();
00267 }
00268 }
00269 as_->setSucceeded(result);
00270 }
00271
00272
00273 ros::NodeHandle n_;
00274
00275
00276 protected:
00277 actionlib::SimpleActionServer<cob_3d_mapping_msgs::TableObjectClusterAction>* as_;
00278 ros::ServiceClient get_plane_client_;
00279 ros::ServiceClient get_bb_client_;
00280 dynamic_reconfigure::Server<table_object_cluster_nodeletConfig> config_server_;
00281 boost::mutex mutex_;
00282
00283 TableObjectCluster toc;
00284
00285 bool save_to_file_;
00286 std::string file_path_;
00287
00288
00289
00290
00291
00292 };
00293
00294 PLUGINLIB_DECLARE_CLASS(cob_env_model, TableObjectClusterNodelet, TableObjectClusterNodelet, nodelet::Nodelet)