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);