test_rosmpi.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * $Id: test_rosmpi.cpp 48321 2011-01-26 07:05:47Z hsu $
00035  *
00036  */
00037 
00038 #include <rosmpi/rosmpi.h>
00039 #include <rosmpi/node_handle.h>
00040 #include <rosmpi/publisher.h>
00041 #include <rosmpi/subscriber.h>
00042 
00043 #include <pcl/point_types.h>
00044 #include <pcl/io/pcd_io.h>
00045 #include <pcl/ros/conversions.h>
00046 #include <pcl/features/normal_3d.h>
00047 #include <pcl/kdtree/kdtree_flann.h>
00048 
00049 typedef sensor_msgs::PointCloud2 Msg;
00050 typedef sensor_msgs::PointCloud2::ConstPtr MsgConstPtr;
00051 
00052 std::string processor_name;
00053 int rank;
00054 
00055 void 
00056   computeIndices (const int rank, const int max_rank, const int nr_points, pcl::PointIndices &indices)
00057 {
00058   int pts_per_worker = lrint (round (nr_points / max_rank));
00059   int s_idx = rank * pts_per_worker;
00060   //int e_idx = (rank + 1) * pts_per_worker;
00061   indices.indices.resize (pts_per_worker);
00062   for (size_t i = 0; i < indices.indices.size (); i++)
00063     indices.indices[i] = i + s_idx;
00064 }
00065 
00066 class Worker
00067 {
00068   public:
00069     Worker (int rank, int max_rank) : rank_ (rank), max_rank_ (max_rank)
00070     {
00071       sub_ = nh_.subscribe (&Worker::cloud_cb, this);
00072     }
00073 
00074 
00075     void 
00076       cloud_cb (const MsgConstPtr &msg)
00077     {
00078       ROS_INFO_STREAM ("[" << processor_name << "/" << rank << "] received message with " << msg->data.size () << " size, with " << msg->width << "x" << msg->height);
00079 
00080       pcl::PointCloud<pcl::PointXYZ> cloud;
00081       pcl::fromROSMsg (*msg, cloud);
00082       cloud_.reset (new pcl::PointCloud<pcl::PointXYZ> (cloud));
00083      
00084       pcl::PointIndices indices;
00085       computeIndices (rank_, max_rank_, cloud.points.size (), indices);
00086 
00087       tree_ = boost::make_shared<pcl::KdTreeFLANN<pcl::PointXYZ> > ();
00088       tree_->setInputCloud (cloud_);
00089       
00090       ROS_INFO ("Estimating features for indices: %d -> %d", indices.indices[0], indices.indices[indices.indices.size () - 1]);
00091       ne_.setInputCloud (cloud_);
00092       ne_.setIndices (boost::make_shared<pcl::PointIndices> (indices));
00093       ne_.setSearchMethod (tree_);
00094       ne_.setRadiusSearch (0.03);
00095       ne_.compute (normals_);
00096     }
00097 
00098   private:
00099     rosmpi::NodeHandle nh_;
00100     rosmpi::Subscriber sub_;
00101     pcl::KdTreeFLANN<pcl::PointXYZ>::Ptr tree_;
00102     int rank_, max_rank_;
00103 
00104     pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne_;
00105     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_;
00106     pcl::PointCloud<pcl::Normal> normals_;
00107 };
00108 
00109 /* ---[ */
00110 int
00111   main (int argc, char** argv)
00112 {
00113   if (argc < 2)
00114   {
00115     ROS_ERROR ("Need a valid PCD file as input. Example: $ %s `rospack find pcl`/test/bun0.pcd", argv[0]);
00116     return (-1);
00117   }
00118   rosmpi::init (argc, argv, rosmpi::init_options::ThreadSingle);      // Init ros-mpi
00119 
00120   // Get the process name and rank
00121   int nr_procs = rosmpi::communicator::getSize ();
00122   rank     = rosmpi::communicator::getRank ();
00123 
00124   processor_name = rosmpi::this_processor::getName ();
00125  
00126   // Master?
00127   if (rank == 0)
00128   {
00129     // Load the data
00130     Msg msg;
00131     pcl::io::loadPCDFile (argv[1], msg);
00132     ROS_INFO_STREAM ("[" << processor_name << "] Loaded a file with " << msg.width * msg.height << " points (" << msg.data.size () << " data bytes).");
00133 
00134     // Create the publisher
00135     rosmpi::Publisher pub; 
00136     ROS_INFO_STREAM ("[" << processor_name << "] Sending data to " << nr_procs << " nodes.") ;
00137     pub.publish<Msg> (msg);
00138 
00139       pcl::PointCloud<pcl::PointXYZ> cloud;
00140       pcl::fromROSMsg (msg, cloud);
00141      
00142       pcl::PointIndices indices;
00143       computeIndices (rank, nr_procs, cloud.points.size (), indices);
00144 
00145       pcl::KdTreeFLANN<pcl::PointXYZ>::Ptr tree_ = boost::make_shared<pcl::KdTreeFLANN<pcl::PointXYZ> > ();
00146       tree_->setInputCloud (boost::make_shared<pcl::PointCloud<pcl::PointXYZ> >(cloud));
00147       
00148       ROS_INFO ("Estimating features for indices: %d -> %d", indices.indices[0], indices.indices[indices.indices.size () - 1]);
00149       pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne_;
00150       ne_.setInputCloud (boost::make_shared<pcl::PointCloud<pcl::PointXYZ> >(cloud));
00151       ne_.setIndices (boost::make_shared<pcl::PointIndices> (indices));
00152       ne_.setSearchMethod (tree_);
00153       ne_.setRadiusSearch (0.03);
00154       pcl::PointCloud<pcl::Normal> normals_;
00155       ne_.compute (normals_);
00156   }
00157   else
00158   {
00159     Worker w (rank, nr_procs);
00160   }
00161 
00162   rosmpi::shutdown ();
00163 
00164   return (0);
00165 }
00166 /* ]--- */


rosmpi
Author(s): Radu Bogdan Rusu, John Hsu
autogenerated on Mon Jan 6 2014 11:27:20