qppf_node.cpp
Go to the documentation of this file.
00001 
00059 /*
00060  * qppf_node.cpp
00061  *
00062  *  Created on: 21.07.2012
00063  *      Author: josh
00064  */
00065 
00066 #if !defined(SICK) //&& !defined(ONLY_PLANES_DEPTH)
00067 #define USE_COLOR
00068 #endif
00069 
00070 // ROS includes
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 //#include <cob_3d_mapping_msgs/FilterObject.h>
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     //PCLNodelet::onInit();
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   //std::vector<cob_3d_mapping_msgs::FilterObject> filter_;
00142 
00143   actionlib::SimpleActionServer<cob_3d_segmentation::ObjectWatchAction> as_;
00144   cob_3d_segmentation::ObjectWatchGoalConstPtr  goal_;
00145 
00146 public:
00147   // Constructor
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               //p.header = pc_in->header;
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         //img.header = pc_in->header;
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       //m.header = pc_in->header;
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       //sa.header = pc_in->header;
00286       for(size_t i=0; i<sa.shapes.size(); i++)
00287         pcl_conversions::fromPCL(pc_in->header, sa.shapes[i].header);
00288         //sa.shapes[i].header = pc_in->header;
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       //cpa.header = pc_in->header;
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


cob_3d_segmentation
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:03:03