Go to the documentation of this file.00001 #include <numeric>
00002 #include <ros/ros.h>
00003 #include <algorithm>
00004
00005 #include <geometry_msgs/PointStamped.h>
00006 #include <geometry_msgs/PoseStamped.h>
00007 #include <pcl/point_types.h>
00008 #include <pcl_ros/point_cloud.h>
00009 #include <pcl/point_cloud.h>
00010 #include <pcl/surface/concave_hull.h>
00011 #include <tf/transform_listener.h>
00012 #include <opencv/cv.h>
00013 #include <image_transport/image_transport.h>
00014 #include <image_geometry/pinhole_camera_model.h>
00015 #include <pcl_ros/transforms.h>
00016 #include <tabletop_object_detector/TabletopSegmentation.h>
00017 #include <hrl_table_detect/ObjectButtonDetect.h>
00018
00019 namespace hrl_table_detect {
00020
00021 class ObjectButtonDetector {
00022 public:
00023 ros::NodeHandle nh;
00024 tf::TransformListener tf_listener;
00025 ros::ServiceServer table_obj_srv;
00026 ros::ServiceClient table_seg_srv;
00027 ros::Publisher hull_pub;
00028 std::string camera_frame;
00029
00030 ObjectButtonDetector();
00031 void onInit();
00032 bool detectCallback(ObjectButtonDetect::Request& req, ObjectButtonDetect::Response& resp);
00033
00034 };
00035
00036 ObjectButtonDetector::ObjectButtonDetector() {
00037 }
00038
00039 void ObjectButtonDetector::onInit() {
00040 nh.param<std::string>("camera_frame", camera_frame, "/openni_rgb_optical_frame");
00041
00042 table_obj_srv = nh.advertiseService("object_button_detect",
00043 &ObjectButtonDetector::detectCallback, this);
00044 table_seg_srv = nh.serviceClient<tabletop_object_detector::TabletopSegmentation>(
00045 "table_segmentation", false);
00046 hull_pub = nh.advertise<visualization_msgs::Marker>("object_hull", 1);
00047 ROS_INFO("[object_button_detector] ObjectButtonDetector loaded.");
00048 ros::Duration(1).sleep();
00049 }
00050
00051 bool ObjectButtonDetector::detectCallback(ObjectButtonDetect::Request& req,
00052 ObjectButtonDetect::Response& resp) {
00053
00054 tabletop_object_detector::TabletopSegmentation::Request table_seg_req;
00055 tabletop_object_detector::TabletopSegmentation::Response table_seg_resp;
00056 table_seg_srv.call(table_seg_req, table_seg_resp);
00057
00058
00059
00060 geometry_msgs::PointStamped table_pt, table_base_frame, cam_pt, cam_base_frame;
00061 table_pt.header.frame_id = "/torso_lift_link";
00062 table_pt.header.stamp = table_seg_resp.table.pose.header.stamp;
00063 table_pt.point.x = table_seg_resp.table.pose.pose.position.x;
00064 table_pt.point.y = table_seg_resp.table.pose.pose.position.y;
00065 table_pt.point.z = table_seg_resp.table.pose.pose.position.z;
00066 cam_pt.header.frame_id = camera_frame;
00067 cam_pt.header.stamp = ros::Time(0);
00068 cam_pt.point.x = 0; cam_pt.point.y = 0; cam_pt.point.z = 0;
00069
00070 tf_listener.transformPoint("/base_footprint", table_pt, table_base_frame);
00071 tf_listener.transformPoint("/base_footprint", cam_pt, cam_base_frame);
00072 float table_height = table_base_frame.point.z;
00073 for(uint32_t i=0;i<table_seg_resp.clusters.size();i++) {
00074
00075 sensor_msgs::PointCloud obj_img_frame;
00076 table_seg_resp.clusters[i].header.frame_id = "/torso_lift_link";
00077 tf_listener.transformPointCloud("/base_footprint", table_seg_resp.clusters[i],
00078 obj_img_frame);
00079
00080 pcl::PointCloud<pcl::PointXYZ>::Ptr table_proj_obj
00081 (new pcl::PointCloud<pcl::PointXYZ>);
00082 BOOST_FOREACH(const geometry_msgs::Point32& pt, obj_img_frame.points) {
00083 if(pt.x != pt.x || pt.y != pt.y || pt.z != pt.z)
00084 continue;
00085 geometry_msgs::Vector3Stamped ray, ray_trans;
00086 ray.header.frame_id = camera_frame;
00087 ray.vector.x = pt.x - cam_base_frame.point.x;
00088 ray.vector.y = pt.y - cam_base_frame.point.y;
00089 ray.vector.z = pt.z - cam_base_frame.point.z;
00090 tf_listener.transformVector("/base_footprint", ray, ray_trans);
00091 float t = (table_height - cam_base_frame.point.z) / ray.vector.z;
00092 pcl::PointXYZ proj_pt;
00093 proj_pt.x = cam_base_frame.point.x + ray.vector.x * t;
00094 proj_pt.y = cam_base_frame.point.y + ray.vector.y * t;
00095 proj_pt.z = table_height;
00096 table_proj_obj->points.push_back(proj_pt);
00097 }
00098
00099
00100 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_hull
00101 (new pcl::PointCloud<pcl::PointXYZ>);
00102 pcl::PointCloud<pcl::PointXYZ>::Ptr voronoi_centers
00103 (new pcl::PointCloud<pcl::PointXYZ>);
00104 std::vector<pcl::Vertices> hull_verts;
00105 pcl::ConcaveHull<pcl::PointXYZ> concave_hull;
00106 concave_hull.setInputCloud(table_proj_obj);
00107 concave_hull.setAlpha(0.1);
00108 concave_hull.setVoronoiCenters(voronoi_centers);
00109 concave_hull.reconstruct(*cloud_hull, hull_verts);
00110
00111
00112 visualization_msgs::Marker hull_poly;
00113 hull_poly.type = visualization_msgs::Marker::LINE_STRIP;
00114 hull_poly.action = visualization_msgs::Marker::ADD;
00115 hull_poly.ns = "object_hull";
00116 hull_poly.header.frame_id = "/base_footprint";
00117 hull_poly.header.stamp = ros::Time::now();
00118 hull_poly.id = i;
00119 hull_poly.pose.orientation.w = 1;
00120 hull_poly.scale.x = 0.01; hull_poly.scale.y = 0.01; hull_poly.scale.z = 0.01;
00121 hull_poly.color.r = 1; hull_poly.color.b = 1; hull_poly.color.a = 1;
00122 BOOST_FOREACH(const pcl::PointXYZ& pt, cloud_hull->points) {
00123 geometry_msgs::Point n_pt;
00124 n_pt.x = pt.x; n_pt.y = pt.y; n_pt.z = pt.z;
00125 hull_poly.points.push_back(n_pt);
00126 }
00127 hull_poly.points.push_back(hull_poly.points[0]);
00128 resp.objects.push_back(hull_poly);
00129 hull_pub.publish(hull_poly);
00130 }
00131 return true;
00132 }
00133
00134 };
00135
00136
00137 using namespace hrl_table_detect;
00138
00139 int main(int argc, char **argv)
00140 {
00141 ros::init(argc, argv, "object_button_detector");
00142 ObjectButtonDetector obd;
00143 obd.onInit();
00144 ros::spin();
00145 return 0;
00146 }