Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 #include "jsk_pcl_ros/parallel_edge_finder.h"
00037 #include "jsk_recognition_utils/pcl_util.h"
00038 #include <jsk_recognition_msgs/ParallelEdgeArray.h>
00039 
00040 namespace jsk_pcl_ros
00041 {
00042   void ParallelEdgeFinder::onInit()
00043   {
00044     ConnectionBasedNodelet::onInit();
00045     
00047     
00049     pub_ = advertise<jsk_recognition_msgs::ParallelEdgeArray>(*pnh_, "output_edges_groups", 1);
00050     pub_clusters_ = advertise<jsk_recognition_msgs::ClusterPointIndices>(*pnh_, "output_clusters", 1);
00051 
00053     
00055     srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
00056     dynamic_reconfigure::Server<Config>::CallbackType f =
00057       boost::bind (&ParallelEdgeFinder::configCallback, this, _1, _2);
00058     srv_->setCallback (f);
00059     onInitPostProcess();
00060   }
00061 
00062   void ParallelEdgeFinder::subscribe()
00063   {
00065     
00067     sub_indices_.subscribe(*pnh_, "input_indices", 1);
00068     sub_coefficients_.subscribe(*pnh_, "input_coefficients", 1);
00069     sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(100);
00070     sync_->connectInput(sub_indices_, sub_coefficients_);
00071     sync_->registerCallback(boost::bind(&ParallelEdgeFinder::estimate,
00072                                         this, _1, _2));
00073   }
00074 
00075   void ParallelEdgeFinder::unsubscribe()
00076   {
00077     sub_indices_.unsubscribe();
00078     sub_coefficients_.unsubscribe();
00079   }
00080 
00081   void ParallelEdgeFinder::configCallback(
00082     Config &config, uint32_t level)
00083   {
00084     boost::mutex::scoped_lock lock(mutex_);
00085     angle_threshold_ = config.angular_threshold;
00086   }
00087   
00088   void ParallelEdgeFinder::estimate(
00089     const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& input_indices,
00090     const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& input_coefficients)
00091   {
00092     boost::mutex::scoped_lock lock(mutex_);
00094     
00096     std::vector<jsk_recognition_utils::Line::Ptr> lines;
00097     if (input_coefficients->coefficients.size() == 0) {
00098       return;
00099     }
00100     for (size_t i = 0; i < input_coefficients->coefficients.size(); i++) {
00101       std::vector<float> the_coefficients
00102         = input_coefficients->coefficients[i].values;
00103       lines.push_back(jsk_recognition_utils::Line::fromCoefficients(the_coefficients));
00104     }
00105 
00106     std::map<int, std::vector<int> > parallel_map;
00107     for (size_t i = 0; i < lines.size() - 1; i++) {
00108       parallel_map[i] = std::vector<int>();
00109       jsk_recognition_utils::Line::Ptr the_line = lines[i];
00110       for (size_t j = i + 1; j < lines.size(); j++) {
00111         jsk_recognition_utils::Line::Ptr candidate_line = lines[j];
00112         if (the_line->isParallel(*candidate_line, angle_threshold_)) {
00113           parallel_map[i].push_back(j);
00114         }
00115       }
00116     }
00117     
00118     
00119     
00120     std::vector<std::set<int> > parallel_groups_list;
00121     
00122     
00123     
00124     std::set<int> listed_indices;
00125 
00126     for (size_t i = 0; i < lines.size() - 1; i++) {
00127       std::vector<int> parallel_indices = parallel_map[i];
00128       if (listed_indices.find(i) == listed_indices.end()) {
00129         if (parallel_indices.size() == 0) {
00130           
00131         }
00132         else {
00133           std::set<int> new_parallel_set;
00134           jsk_recognition_utils::buildGroupFromGraphMap(parallel_map,
00135                                  i,
00136                                  parallel_indices,
00137                                  new_parallel_set);
00138           parallel_groups_list.push_back(new_parallel_set);
00139           jsk_recognition_utils::addSet(listed_indices, new_parallel_set);
00140         }
00141       }
00142     }
00143     
00144     publishResult(parallel_groups_list, input_indices, input_coefficients);
00145     publishResultAsCluser(parallel_groups_list, input_indices,
00146                           input_coefficients);
00147   }
00148 
00149   void ParallelEdgeFinder::publishResult(
00150     const std::vector<std::set<int> >& parallel_groups_list,
00151     const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& input_indices,
00152     const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& input_coefficients)
00153   {
00154     jsk_recognition_msgs::ParallelEdgeArray ros_output_msg;
00155     ros_output_msg.header = input_indices->header;
00156     for (size_t i = 0; i < parallel_groups_list.size(); i++) {
00157       std::set<int> parallel_groups = parallel_groups_list[i];
00158       jsk_recognition_msgs::ParallelEdge edge_group;
00159       edge_group.header = input_indices->header;
00160       for (std::set<int>::iterator it = parallel_groups.begin();
00161            it != parallel_groups.end();
00162            ++it) {
00163         int the_index = *it;
00164         std::vector<int> indices
00165           = input_indices->cluster_indices[the_index].indices;
00166         std::vector<float> coefficients
00167           = input_coefficients->coefficients[the_index].values;
00168         PCLIndicesMsg indices_msg;
00169         indices_msg.header = input_indices->header;
00170         indices_msg.indices = indices;
00171         PCLModelCoefficientMsg coefficients_msg;
00172         coefficients_msg.header = input_coefficients->header;
00173         coefficients_msg.values = coefficients;
00174         edge_group.cluster_indices.push_back(indices_msg);
00175         edge_group.coefficients.push_back(coefficients_msg);
00176       }
00177       ros_output_msg.edge_groups.push_back(edge_group);
00178     }
00179     pub_.publish(ros_output_msg);
00180   }
00181 
00182   void ParallelEdgeFinder::publishResultAsCluser(
00183       const std::vector<std::set<int> >& parallel_groups_list,
00184       const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& input_indices,
00185       const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& input_coefficients)
00186   {
00187     jsk_recognition_msgs::ClusterPointIndices ros_output_msg;
00188     ros_output_msg.header = input_indices->header;
00189 
00190     for (size_t i = 0; i < parallel_groups_list.size(); i++) {
00191       std::set<int> parallel_groups = parallel_groups_list[i];
00192       PCLIndicesMsg indices_msg;
00193       indices_msg.header = input_indices->header;
00194       for (std::set<int>::iterator it = parallel_groups.begin();
00195            it != parallel_groups.end();
00196            ++it) {
00197         indices_msg.indices = jsk_recognition_utils::addIndices(
00198           indices_msg.indices,
00199           input_indices->cluster_indices[*it].indices);
00200       }
00201       ros_output_msg.cluster_indices.push_back(indices_msg);
00202     }
00203     pub_clusters_.publish(ros_output_msg);
00204   }
00205   
00206 }
00207 
00208 #include <pluginlib/class_list_macros.h>
00209 PLUGINLIB_EXPORT_CLASS (jsk_pcl_ros::ParallelEdgeFinder, nodelet::Nodelet);
00210