35 #define BOOST_PARAMETER_MAX_ARITY 7
37 #include <pcl/kdtree/kdtree_flann.h>
38 #include <pcl/sample_consensus/method_types.h>
39 #include <pcl/sample_consensus/model_types.h>
40 #include <pcl/segmentation/sac_segmentation.h>
48 DiagnosticNodelet::onInit();
49 pcl::console::setVerbosityLevel(pcl::console::L_ALWAYS);
50 srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
51 dynamic_reconfigure::Server<Config>::CallbackType
f =
54 srv_->setCallback (
f);
56 pub_indices_ = advertise<jsk_recognition_msgs::ClusterPointIndices>(
57 *pnh_,
"output/indices", 1);
58 pub_polygon_ = advertise<jsk_recognition_msgs::PolygonArray>(
59 *pnh_,
"output/polygons", 1);
61 *pnh_,
"output/coefficients", 1);
83 sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> > (100);
99 const sensor_msgs::PointCloud2::ConstPtr& cloud_msg,
100 const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& indices_msg,
101 const jsk_recognition_msgs::PolygonArray::ConstPtr& polygon_array_msg,
102 const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& coefficients_array_msg)
105 vital_checker_->poke();
107 size_t nr_cluster = polygon_array_msg->polygons.size();
108 pcl::PointCloud<PointT>::Ptr
cloud (
new pcl::PointCloud<PointT>);
111 std::vector<pcl::ModelCoefficients::Ptr> all_coefficients
113 coefficients_array_msg->coefficients);
114 std::vector<pcl::PointIndices::Ptr> all_indices
116 std::vector<pcl::PointCloud<PointT>::Ptr> all_clouds
117 = jsk_recognition_utils::convertToPointCloudArray<PointT>(
cloud, all_indices);
118 std::vector<jsk_recognition_utils::Plane::Ptr> planes
122 for (
size_t i = 0;
i < nr_cluster;
i++) {
123 connection_map[
i] = std::vector<int>();
124 connection_map[
i].push_back(
i);
126 pcl::KdTreeFLANN<PointT> kdtree;
127 pcl::PointCloud<PointT>::Ptr focused_cloud = all_clouds[
i];
128 kdtree.setInputCloud(focused_cloud);
131 for (
size_t j =
i + 1; j < nr_cluster; j++) {
135 bool is_near_enough =
isNearPointCloud(kdtree, all_clouds[j], target_plane);
136 if (is_near_enough) {
137 connection_map[
i].push_back(j);
142 std::vector<std::set<int> > cloud_sets;
145 std::vector<pcl::PointIndices::Ptr> new_indices;
146 std::vector<pcl::ModelCoefficients::Ptr> new_coefficients;
147 for (
size_t i = 0;
i < cloud_sets.size();
i++) {
148 pcl::PointIndices::Ptr new_one_indices (
new pcl::PointIndices);
149 new_coefficients.push_back(all_coefficients[*cloud_sets[
i].begin()]);
150 for (std::set<int>::iterator it = cloud_sets[
i].begin();
151 it != cloud_sets[
i].end();
155 if (new_one_indices->indices.size() >
min_size_) {
156 new_indices.push_back(new_one_indices);
161 std::vector<pcl::ModelCoefficients::Ptr> new_refined_coefficients;
162 for (
size_t i = 0;
i < new_indices.size();
i++) {
163 pcl::ModelCoefficients::Ptr refined_coefficients
165 new_refined_coefficients.push_back(refined_coefficients);
169 jsk_recognition_msgs::ClusterPointIndices new_ros_indices;
170 jsk_recognition_msgs::ModelCoefficientsArray new_ros_coefficients;
171 jsk_recognition_msgs::PolygonArray new_ros_polygons;
172 new_ros_indices.header = cloud_msg->header;
173 new_ros_coefficients.header = cloud_msg->header;
174 new_ros_polygons.header = cloud_msg->header;
175 for (
size_t i = 0;
i < new_indices.size();
i++) {
177 = jsk_recognition_utils::convexFromCoefficientsAndInliers<PointT>(
178 cloud, new_indices[
i], new_refined_coefficients[
i]);
180 geometry_msgs::PolygonStamped polygon;
181 polygon.polygon = convex->toROSMsg();
182 polygon.header = cloud_msg->header;
183 new_ros_polygons.polygons.push_back(polygon);
184 pcl_msgs::PointIndices ros_indices;
185 ros_indices.header = cloud_msg->header;
186 ros_indices.indices = new_indices[
i]->indices;
187 new_ros_indices.cluster_indices.push_back(ros_indices);
188 pcl_msgs::ModelCoefficients ros_coefficients;
189 ros_coefficients.header = cloud_msg->header;
190 ros_coefficients.values = new_refined_coefficients[
i]->values;
191 new_ros_coefficients.coefficients.push_back(ros_coefficients);
207 pcl::PointCloud<PointT>::Ptr
cloud,
208 pcl::PointIndices::Ptr indices,
209 pcl::ModelCoefficients::Ptr original_coefficients)
211 pcl::SACSegmentation<PointT> seg;
212 seg.setOptimizeCoefficients (
true);
213 seg.setModelType (pcl::SACMODEL_PERPENDICULAR_PLANE);
214 seg.setMethodType (pcl::SAC_RANSAC);
217 seg.setInputCloud(
cloud);
219 seg.setIndices(indices);
221 Eigen::Vector3f normal (original_coefficients->values[0],
222 original_coefficients->values[1],
223 original_coefficients->values[2]);
229 pcl::PointIndices::Ptr refined_inliers (
new pcl::PointIndices);
230 pcl::ModelCoefficients::Ptr refined_coefficients(
new pcl::ModelCoefficients);
231 seg.segment(*refined_inliers, *refined_coefficients);
232 if (refined_inliers->indices.size() > 0) {
233 pcl::ModelCoefficients::Ptr fixed_refined_coefficients(
new pcl::ModelCoefficients);
235 return fixed_refined_coefficients;
238 return original_coefficients;
243 pcl::KdTreeFLANN<PointT>& kdtree,
244 pcl::PointCloud<PointT>::Ptr
cloud,
247 pcl::PointCloud<PointT>::ConstPtr input_cloud = kdtree.getInputCloud();
248 for (
size_t i = 0;
i <
cloud->points.size();
i++) {
250 std::vector<int> k_indices;
251 std::vector<float> k_sqr_distances;
253 k_indices, k_sqr_distances, 1) > 0) {
255 const PointT near_p = input_cloud->points[k_indices[0]];
256 Eigen::Affine3f plane_coordinates = target_plane->coordinates();
257 Eigen::Vector3f plane_local_p = plane_coordinates.inverse() *
p.getVector3fMap();
258 Eigen::Vector3f plane_local_near_p = plane_coordinates.inverse() * near_p.getVector3fMap();
259 Eigen::Vector3f plane_local_diff = plane_local_near_p - plane_local_p;
260 double perpendicular_distance = std::abs(plane_local_diff[2]);
270 Config &config, uint32_t level)
278 =
config.ransac_refinement_outlier_threshold;
286 const pcl::ModelCoefficients::Ptr& coefficients,
287 pcl::ModelCoefficients::Ptr& output_coefficients)