00001
00059
00060
00061
00062
00063
00064
00065
00066 #if !defined(SICK) //&& !defined(ONLY_PLANES_DEPTH)
00067 #define USE_COLOR
00068 #endif
00069
00070
00071 #include <ros/ros.h>
00072 #include <pluginlib/class_list_macros.h>
00073 #include <nodelet/nodelet.h>
00074 #include <pcl/point_types.h>
00075 #include <pcl_ros/point_cloud.h>
00076 #include <pcl/point_cloud.h>
00077 #include <pcl_conversions/pcl_conversions.h>
00078
00079 #include <cob_3d_segmentation/quad_regression/quad_regression.h>
00080 #include <cob_3d_mapping_msgs/CurvedPolygonArray.h>
00081
00082
00083 #include <actionlib/server/simple_action_server.h>
00084 #include <cob_3d_segmentation/ObjectWatchGoal.h>
00085 #include <cob_3d_segmentation/ObjectWatchFeedback.h>
00086 #include <cob_3d_segmentation/ObjectWatchAction.h>
00087 #include <geometry_msgs/PoseStamped.h>
00088 #include <cob_3d_segmentation/point_types.h>
00089
00090 class As_Node
00091 {
00092 protected:
00093 ros::NodeHandle n_;
00094 public:
00095 As_Node(): n_("~") {
00096 }
00097
00098 virtual ~As_Node() {}
00099
00100 virtual void onInit()=0;
00101
00102 void start() {
00103
00104 }
00105 };
00106
00107 class As_Nodelet : public nodelet::Nodelet
00108 {
00109 protected:
00110 ros::NodeHandle n_;
00111 public:
00112 As_Nodelet() {
00113 }
00114
00115 virtual ~As_Nodelet() {}
00116
00117 void start() {
00118
00119 n_ = getNodeHandle();
00120 }
00121 };
00122
00123 template <typename Point, typename PointLabel, typename Parent>
00124 class QPPF_Node : public Parent
00125 {
00126 typedef pcl::PointCloud<Point> PointCloud;
00127
00128 ros::Subscriber point_cloud_sub_;
00129 ros::Publisher curved_pub_, shapes_pub_, outline_pub_, image_pub_, label_pub_, rec_pub_;
00130
00131 #ifdef SICK
00132 Segmentation::Segmentation_QuadRegression<Point, PointLabel, Segmentation::QPPF::QuadRegression<1, Point, Segmentation::QPPF::CameraModel_SR4500<Point> > > seg_;
00133 #else
00134 #ifdef ONLY_PLANES_DEPTH
00135 Segmentation::Segmentation_QuadRegression<Point, PointLabel, Segmentation::QPPF::QuadRegression<1, Point, Segmentation::QPPF::CameraModel_Kinect<Point> > > seg_;
00136 #else
00137 Segmentation::Segmentation_QuadRegression<Point, PointLabel, Segmentation::QPPF::QuadRegression<2, Point, Segmentation::QPPF::CameraModel_Kinect<Point> > > seg_;
00138 #endif
00139 #endif
00140
00141
00142
00143 actionlib::SimpleActionServer<cob_3d_segmentation::ObjectWatchAction> as_;
00144 cob_3d_segmentation::ObjectWatchGoalConstPtr goal_;
00145
00146 public:
00147
00148 QPPF_Node(const std::string &name):
00149 as_(this->n_, name, boost::bind(&QPPF_Node::setGoal, this, _1), false)
00150 {
00151 }
00152
00153 virtual ~QPPF_Node()
00154 {}
00155
00156 void onInit() {
00157 this->start();
00158
00159 ros::NodeHandle *n=&(this->n_);
00160 #ifdef USE_COLOR
00161 point_cloud_sub_ = this->n_.subscribe("/camera/rgb/points", 1, &QPPF_Node<Point, PointLabel, Parent>::pointCloudSubCallback, this);
00162 #else
00163 point_cloud_sub_ = this->n_.subscribe("/camera/depth/points", 1, &QPPF_Node<Point, PointLabel, Parent>::pointCloudSubCallback, this);
00164 #endif
00165 curved_pub_ = n->advertise<cob_3d_mapping_msgs::CurvedPolygonArray>("/curved_polygons", 1);
00166 shapes_pub_ = n->advertise<cob_3d_mapping_msgs::ShapeArray>("/shapes_array", 1);
00167 outline_pub_= n->advertise<visualization_msgs::Marker>("/outline", 1);
00168 image_pub_ = n->advertise<sensor_msgs::Image>("/image1", 1);
00169 label_pub_ = n->advertise< pcl::PointCloud<PointLabel> >("/labeled_pc", 1);
00170 rec_pub_ = n->advertise< pcl::PointCloud<PointLabel> >("/reconstructed_pc", 1);
00171
00172 as_.start();
00173
00174 double filter;
00175 if(this->n_.getParam("filter",filter))
00176 seg_.setFilter((float)filter);
00177
00178 bool only_planes;
00179 if(this->n_.getParam("only_planes",only_planes))
00180 seg_.setOnlyPlanes(only_planes);
00181 }
00182
00183 void setGoal(const cob_3d_segmentation::ObjectWatchGoalConstPtr &goal)
00184 {
00185 as_.setPreempted();
00186
00187 if(!goal) {
00188 goal_.reset();
00189 return;
00190 }
00191
00192 if(goal->widths.size()!=goal->heights.size())
00193 {
00194 ROS_ERROR("malformed goal message (|widths|!=|heights|): aborting...");
00195 goal_.reset();
00196 }
00197 else if(goal->widths.size()==0)
00198 {
00199 ROS_DEBUG("stopping segment filtering");
00200 goal_.reset();
00201 }
00202 else
00203 goal_ = goal;
00204 }
00205
00206 void
00207 pointCloudSubCallback(const boost::shared_ptr<const PointCloud>& pc_in)
00208 {
00209 ROS_DEBUG("segmentation: point cloud callback");
00210
00211 const bool subscribers =
00212 (image_pub_.getNumSubscribers()>0) ||
00213 (outline_pub_.getNumSubscribers()>0) ||
00214 (shapes_pub_.getNumSubscribers()>0) ||
00215 (curved_pub_.getNumSubscribers()>0) ||
00216 (rec_pub_.getNumSubscribers()>0) ||
00217 (label_pub_.getNumSubscribers()>0);
00218
00219 if(!subscribers) {
00220 ROS_DEBUG("segmentation: no subscribers --> do nothing");
00221 return;
00222 }
00223
00224 seg_.setInputCloud(pc_in);
00225 seg_.compute();
00226 seg_.extractImages();
00227
00228 if(goal_)
00229 {
00230 cob_3d_segmentation::ObjectWatchFeedback feedback;
00231 for(size_t i=0; i<seg_.getPolygons().size(); i++)
00232 {
00233 Eigen::Matrix3f P;
00234 Eigen::Vector3f origin;
00235 float h, w;
00236 if(seg_.getPolygons()[i].getPose(P,origin,h,w))
00237 {
00238 std::cerr<<"z: "<<origin(2)<<" ";
00239 std::cerr<<"w: "<<w<<" ";
00240 std::cerr<<"h: "<<h<<"\n";
00241 for(size_t j=0; j<goal_->heights.size(); j++)
00242 if( std::abs(h-goal_->heights[j])<0.2f*goal_->heights[j] && std::abs(w-goal_->widths[j])<0.2f*goal_->widths[j]) {
00243 ROS_INFO("found");
00244 std::cout<<"P\n"<<P<<"\n";
00245 std::cout<<"origin\n"<<origin<<"\n";
00246
00247 geometry_msgs::PoseStamped p;
00248 pcl_conversions::fromPCL(pc_in->header, p.header);
00249
00250 Eigen::Quaternionf Q(P);
00251 p.pose.orientation.x = Q.x();
00252 p.pose.orientation.y = Q.y();
00253 p.pose.orientation.z = Q.z();
00254 p.pose.orientation.w = Q.w();
00255 p.pose.position.x = origin(0);
00256 p.pose.position.y = origin(1);
00257 p.pose.position.z = origin(2);
00258 feedback.objs.push_back(p);
00259 }
00260 }
00261 }
00262 as_.publishFeedback(feedback);
00263 }
00264
00265 if(image_pub_.getNumSubscribers()>0)
00266 {
00267 if(seg_.getPolygons().size()>0 && seg_.getPolygons()[0].img_) {
00268 sensor_msgs::Image img = *seg_.getPolygons()[0].img_;
00269 pcl_conversions::fromPCL(pc_in->header, img.header);
00270
00271 image_pub_.publish(img);
00272 }
00273 }
00274 if(outline_pub_.getNumSubscribers()>0)
00275 {
00276 visualization_msgs::Marker m = seg_;
00277 pcl_conversions::fromPCL(pc_in->header, m.header);
00278
00279 outline_pub_.publish(m);
00280 }
00281 if(shapes_pub_.getNumSubscribers()>0)
00282 {
00283 cob_3d_mapping_msgs::ShapeArray sa = seg_;
00284 pcl_conversions::fromPCL(pc_in->header, sa.header);
00285
00286 for(size_t i=0; i<sa.shapes.size(); i++)
00287 pcl_conversions::fromPCL(pc_in->header, sa.shapes[i].header);
00288
00289 shapes_pub_.publish(sa);
00290 }
00291 if(curved_pub_.getNumSubscribers()>0)
00292 {
00293 cob_3d_mapping_msgs::CurvedPolygonArray cpa;
00294 for(size_t i=0; i<seg_.getPolygons().size(); i++)
00295 {
00296 cob_3d_mapping_msgs::CurvedPolygon cp;
00297 std_msgs::Header header;
00298 pcl_conversions::fromPCL(pc_in->header, header);
00299 seg_.getPolygons()[i].toRosMsg(&cp,header.stamp);
00300 cpa.polygons.push_back(cp);
00301 }
00302 pcl_conversions::fromPCL(pc_in->header, cpa.header);
00303
00304 curved_pub_.publish(cpa);
00305 }
00306 if(rec_pub_.getNumSubscribers()>0) {
00307 pcl::PointCloud<PointLabel> pc = *seg_.getReconstructedOutputCloud();
00308 pc.header = pc_in->header;
00309 rec_pub_.publish(pc);
00310 }
00311 if(label_pub_.getNumSubscribers()>0) {
00312 pcl::PointCloud<PointLabel> pc = *seg_.getOutputCloud();
00313 pc.header = pc_in->header;
00314 label_pub_.publish(pc);
00315 }
00316 }
00317 };
00318
00319 #ifdef COMPILE_NODELET
00320
00321 typedef QPPF_Node<pcl::PointXYZ,pcl::PointXYZRGB,As_Nodelet> QPPF_XYZ;
00322 typedef QPPF_Node<pcl::PointXYZRGB,pcl::PointXYZRGB,As_Nodelet> QPPF_XYZRGB;
00323
00324 PLUGINLIB_DECLARE_CLASS(cob_3d_segmentation, QPPF_XYZRGB, QPPF_Node_XYZ, nodelet::Nodelet)
00325
00326 #else
00327
00328 int main(int argc, char **argv) {
00329 ros::init(argc, argv, "qppf");
00330
00331 #ifdef USE_COLOR
00332 QPPF_Node<pcl::PointXYZRGB,pcl::PointXYZRGB,As_Node> sn("qppf");
00333 #else
00334 #ifdef SICK
00335 QPPF_Node<pcl::PointXYZI,PointXYZILabel,As_Node> sn("qppf");
00336 #else
00337 QPPF_Node<pcl::PointXYZ,pcl::PointXYZRGB,As_Node> sn("qppf");
00338 #endif
00339 #endif
00340 sn.onInit();
00341
00342 ros::spin();
00343
00344 return 0;
00345 }
00346
00347 #endif