36 #define BOOST_PARAMETER_MAX_ARITY 7
39 #include <pcl/filters/extract_indices.h>
40 #include <pcl/common/distances.h>
42 #include <pcl/filters/project_inliers.h>
43 #include <pcl/surface/convex_hull.h>
44 #include <pcl/filters/project_inliers.h>
45 #include <jsk_recognition_msgs/SparseOccupancyGridArray.h>
48 #include <geometry_msgs/PoseArray.h>
51 #include <jsk_topic_tools/rosparam_utils.h>
56 DiagnosticNodelet::onInit();
58 srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
59 typename dynamic_reconfigure::Server<Config>::CallbackType
f =
61 srv_->setCallback (
f);
65 = pnh_->advertise<jsk_recognition_msgs::PolygonArray>(
66 "debug/magnified_polygons", 1);
68 = pnh_->advertise<sensor_msgs::PointCloud2>(
69 "debug/convex_cloud", 1);
71 = pnh_->advertise<jsk_recognition_msgs::SimpleOccupancyGridArray>(
72 "debug/raw_grid_map", 1);
74 = pnh_->advertise<jsk_recognition_msgs::SimpleOccupancyGridArray>(
75 "debug/noeroded_grid_map", 1);
77 = pnh_->advertise<geometry_msgs::PoseArray>(
78 "debug/plane_poses", 1);
80 = pnh_->advertise<geometry_msgs::PoseArray>(
81 "debug/magnified_plane_poses", 1);
83 = pnh_->advertise<jsk_recognition_msgs::SimpleOccupancyGridArray>(
86 "/footstep_simple/goal", 1);
88 "output/non_plane_indices", 1);
93 "input/leg_bounding_box", 1,
96 jsk_topic_tools::readVectorParameter(
101 "/move_base_simple/goal", 1,
108 sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(100);
111 sync_->registerCallback(
143 const sensor_msgs::PointCloud2::ConstPtr& cloud_msg,
144 const sensor_msgs::PointCloud2::ConstPtr& full_cloud_msg,
145 const jsk_recognition_msgs::PolygonArray::ConstPtr& polygon_msg,
146 const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& coefficients_msg,
147 const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& indices_msg)
150 NODELET_INFO(
" Number of points -- %d", cloud_msg->width * cloud_msg->height);
151 NODELET_INFO(
" Number of full points -- %d", full_cloud_msg->width * full_cloud_msg->height);
152 NODELET_INFO(
" Number of clusters: -- %lu", indices_msg->cluster_indices.size());
153 NODELET_INFO(
" Frame Id: %s", cloud_msg->header.frame_id.c_str());
158 const sensor_msgs::PointCloud2::ConstPtr& cloud_msg,
159 const sensor_msgs::PointCloud2::ConstPtr& full_cloud_msg,
160 const jsk_recognition_msgs::PolygonArray::ConstPtr& polygon_msg,
161 const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& coefficients_msg,
162 const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& indices_msg)
164 std::string
frame_id = cloud_msg->header.frame_id;
165 if (full_cloud_msg->header.frame_id !=
frame_id) {
176 if (coefficients_msg->header.frame_id !=
frame_id) {
179 for (
size_t i = 0;
i < coefficients_msg->coefficients.size();
i++) {
180 if (coefficients_msg->coefficients[
i].header.frame_id !=
frame_id) {
184 if (indices_msg->header.frame_id !=
frame_id) {
187 for (
size_t i = 0;
i < indices_msg->cluster_indices.size();
i++) {
188 if (indices_msg->cluster_indices[
i].header.frame_id !=
frame_id) {
196 const geometry_msgs::PoseStamped::ConstPtr&
msg)
207 msg->header.frame_id,
214 Eigen::Affine3f global_coords =
transform * local_coords;
217 double max_height = - DBL_MAX;
219 Eigen::Affine3f max_projected_coords = Eigen::Affine3f::Identity();
222 Eigen::Affine3f projected_coords;
223 target_grid->getPolygon()->projectOnPlane(global_coords, projected_coords);
224 Eigen::Vector3f projected_point(projected_coords.translation());
225 if (target_grid->isOccupiedGlobal(projected_point)) {
226 double height = projected_point[2];
227 if (max_height <
height) {
229 max_grid = target_grid;
230 max_projected_coords = projected_coords;
236 geometry_msgs::PoseStamped ros_coords;
238 ros_coords.header.stamp =
msg->header.stamp;
248 const jsk_recognition_msgs::BoundingBox::ConstPtr&
box)
255 const sensor_msgs::PointCloud2::ConstPtr& cloud_msg,
256 const sensor_msgs::PointCloud2::ConstPtr& full_cloud_msg,
257 const jsk_recognition_msgs::PolygonArray::ConstPtr& polygon_msg,
258 const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& coefficients_msg,
259 const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& indices_msg)
269 NODELET_ERROR(
"Bounding Box for Footprint is not yet ready");
276 pcl::PointCloud<pcl::PointNormal>::Ptr
cloud (
new pcl::PointCloud<pcl::PointNormal>);
279 pcl::PointCloud<pcl::PointNormal>::Ptr full_cloud (
new pcl::PointCloud<pcl::PointNormal>);
285 std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> magnified_convexes =
magnifyConvexes(convexes);
291 geometry_msgs::PoseArray pose_array;
292 pose_array.header = cloud_msg->header;
293 for (
size_t i = 0;
i < convexes.size();
i++) {
294 Eigen::Affine3f
pose = convexes[
i]->coordinates();
295 geometry_msgs::Pose ros_pose;
297 pose_array.poses.push_back(ros_pose);
302 geometry_msgs::PoseArray pose_array;
303 pose_array.header = cloud_msg->header;
304 for (
size_t i = 0;
i < magnified_convexes.size();
i++) {
305 Eigen::Affine3f
pose = magnified_convexes[
i]->coordinates();
306 geometry_msgs::Pose ros_pose;
308 pose_array.poses.push_back(ros_pose);
314 std::set<int> non_plane_indices;
315 std::vector<GridPlane::Ptr> raw_grid_planes =
buildGridPlanes(full_cloud, magnified_convexes, non_plane_indices);
319 ros_non_plane_indices.indices = std::vector<int>(non_plane_indices.begin(),
320 non_plane_indices.end());
321 ros_non_plane_indices.header = cloud_msg->header;
323 std::vector<GridPlane::Ptr> morphological_filtered_grid_planes
327 morphological_filtered_grid_planes);
329 std::vector<GridPlane::Ptr> eroded_grid_planes
331 std::vector<GridPlane::Ptr> result_grid_planes;
339 result_grid_planes = eroded_grid_planes;
349 NODELET_ERROR(
"Failed to lookup transformation: %s", e.what());
354 std::vector<GridPlane::Ptr>& grid_maps)
356 std::vector<GridPlane::Ptr> ret;
357 for (
size_t i = 0;
i < grid_maps.size();
i++) {
359 ret.push_back(eroded_grid_map);
365 const Eigen::Affine3f& pose,
const std::vector<GridPlane::Ptr>& grid_maps)
367 Eigen::Vector3f foot_z = (
pose.rotation() * Eigen::Vector3f::UnitZ()).normalized();
368 Eigen::Vector3f foot_p(
pose.translation());
369 double min_distance = DBL_MAX;
371 for (
size_t i = 0;
i < grid_maps.size();
i++) {
373 Eigen::Vector3f normal =
grid->getPolygon()->getNormal();
377 Eigen::Vector3f foot_center(
pose.translation());
378 if (!
grid->isOccupiedGlobal(foot_center)) {
380 double d =
grid->getPolygon()->distanceFromVertices(foot_center);
381 if (
d < min_distance) {
398 const std::string& footprint_frame,
const std_msgs::Header&
header,
399 const std::vector<GridPlane::Ptr>& grid_maps)
404 header.frame_id, footprint_frame,
407 Eigen::Affine3f eigen_transform;
414 const jsk_recognition_msgs::BoundingBox::ConstPtr&
box,
415 const std_msgs::Header&
header,
422 box->header.frame_id,
427 Eigen::Affine3f local_pose;
429 Eigen::Affine3f global_pose =
transform * local_pose;
430 std::vector<double> dimensions;
431 dimensions.push_back(
box->dimensions.x);
432 dimensions.push_back(
box->dimensions.y);
433 dimensions.push_back(
box->dimensions.z);
435 Eigen::Quaternionf(global_pose.rotation()),
438 completed_grid_map->fillCellsFromCube(*
cube);
439 return completed_grid_map;
443 const std_msgs::Header&
header, std::vector<GridPlane::Ptr>& grid_maps)
446 std::vector<GridPlane::Ptr> completed_grid_maps(grid_maps.size());
447 std::set<int> ground_plane_indices;
451 footprint_frame,
header, grid_maps);
452 if (grid_index != -1) {
453 NODELET_INFO(
"Found ground plane for %s: %d", footprint_frame.c_str(), grid_index);
454 ground_plane_indices.insert(grid_index);
457 NODELET_WARN(
"Cannnot find ground plane for %s: %d", footprint_frame.c_str(), grid_index);
460 for (
size_t i = 0;
i < grid_maps.size();
i++) {
461 if (ground_plane_indices.find(
i) == ground_plane_indices.end()) {
463 completed_grid_maps[
i] = grid_maps[
i];
470 return completed_grid_maps;
473 NODELET_FATAL(
"Failed to lookup transformation: %s", e.what());
474 return std::vector<GridPlane::Ptr>();
479 std::vector<GridPlane::Ptr>& raw_grid_maps)
481 std::vector<GridPlane::Ptr> ret;
482 for (
size_t i = 0;
i < raw_grid_maps.size();
i++) {
485 ret.push_back(eroded_grid_map);
493 const std_msgs::Header&
header,
494 std::vector<jsk_recognition_utils::ConvexPolygon::Ptr>& convexes)
496 pcl::PointCloud<pcl::PointXYZ>::Ptr
497 boundary_cloud (
new pcl::PointCloud<pcl::PointXYZ>);
498 for (
size_t i = 0;
i < convexes.size();
i++) {
499 pcl::PointCloud<pcl::PointXYZ>::Ptr
500 one_boundary_cloud (
new pcl::PointCloud<pcl::PointXYZ>);
501 convexes[
i]->boundariesToPointCloud<pcl::PointXYZ>(
502 *one_boundary_cloud);
503 *boundary_cloud = *boundary_cloud + *one_boundary_cloud;
505 sensor_msgs::PointCloud2 ros_cloud;
507 ros_cloud.header =
header;
508 pub.publish(ros_cloud);
513 const std_msgs::Header&
header,
514 std::vector<GridPlane::Ptr>& grids)
516 jsk_recognition_msgs::SimpleOccupancyGridArray grid_array;
517 grid_array.header =
header;
518 for (
size_t i = 0;
i < grids.size();
i++) {
519 jsk_recognition_msgs::SimpleOccupancyGrid
grid = grids[
i]->toROSMsg();
521 grid_array.grids.push_back(
grid);
523 pub.publish(grid_array);
528 pcl::PointCloud<pcl::PointNormal>::Ptr& cloud,
529 std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> convexes,
530 std::set<int>& non_plane_indices)
532 std::vector<GridPlane::Ptr> ret(convexes.size());
534 for (
size_t i = 0;
i < convexes.size();
i++) {
550 const std_msgs::Header&
header,
551 std::vector<jsk_recognition_utils::ConvexPolygon::Ptr>& convexes)
553 jsk_recognition_msgs::PolygonArray polygon_array;
554 polygon_array.header =
header;
555 for (
size_t i = 0;
i < convexes.size();
i++) {
556 geometry_msgs::PolygonStamped
polygon;
557 polygon.polygon = convexes[
i]->toROSMsg();
559 polygon_array.polygons.push_back(
polygon);
561 pub.publish(polygon_array);
565 std::vector<jsk_recognition_utils::ConvexPolygon::Ptr>& convexes)
567 std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> ret(0);
568 for (
size_t i = 0;
i < convexes.size();
i++) {
572 if (new_convex->getNormalFromVertices().dot(Eigen::Vector3f::UnitZ()) < 0) {
573 new_convex = boost::make_shared<jsk_recognition_utils::ConvexPolygon>(new_convex->flipConvex());
575 ret.push_back(new_convex);
581 const pcl::PointCloud<pcl::PointNormal>::Ptr& cloud,
582 const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& indices_msg,
583 const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& coefficients_msg)
585 std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> convexes(0);
586 for (
size_t i = 0;
i < indices_msg->cluster_indices.size();
i++) {
587 pcl::PointIndices::Ptr inliers (
new pcl::PointIndices);
588 inliers->indices = indices_msg->cluster_indices[
i].indices;
589 pcl::ModelCoefficients::Ptr
coefficients (
new pcl::ModelCoefficients);
590 coefficients->values = coefficients_msg->coefficients[
i].values;
592 = jsk_recognition_utils::convexFromCoefficientsAndInliers<pcl::PointNormal>(
594 convexes.push_back(convex);