find_objects.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # Copyright (c) 2013, Oregon State University
00003 # All rights reserved.
00004 #
00005 # Redistribution and use in source and binary forms, with or without
00006 # modification, are permitted provided that the following conditions are met:
00007 #     * Redistributions of source code must retain the above copyright
00008 #       notice, this list of conditions and the following disclaimer.
00009 #     * Redistributions in binary form must reproduce the above copyright
00010 #       notice, this list of conditions and the following disclaimer in the
00011 #       documentation and/or other materials provided with the distribution.
00012 #     * Neither the name of the Oregon State University nor the
00013 #       names of its contributors may be used to endorse or promote products
00014 #       derived from this software without specific prior written permission.
00015 #
00016 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 # DISCLAIMED. IN NO EVENT SHALL OREGON STATE UNIVERSITY BE LIABLE FOR ANY
00020 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 #
00027 # Author Dan Lazewatsky/lazewatd@engr.orst.edu
00028 
00029 import roslib; roslib.load_manifest('projector_interface')
00030 from tabletop_object_detector.srv import TabletopSegmentation, TabletopSegmentationRequest
00031 from tabletop_object_detector.msg import Table
00032 from tabletop_object_detector.msg import Table
00033 from pr2_python.pointclouds import xyz_array_to_pointcloud2
00034 from pr2_python.transform_listener import transform_point_stamped, transform_pose_stamped
00035 from tf import TransformBroadcaster
00036 import tf_conversions.posemath as pm
00037 import dynamic_reconfigure.client
00038 from threading import Thread, RLock
00039 
00040 import rospy
00041 import tf
00042 import numpy as np
00043 from sensor_msgs.msg import PointCloud2
00044 from geometry_msgs.msg import PointStamped
00045 
00046 import rospy.service
00047 
00048 table_pose = None
00049 br = None
00050 tf_lock = RLock()
00051 
00052 def pt2np(pt):
00053     return np.array([pt.x,pt.y,pt.z])
00054 
00055 def cloud2np(cloud):
00056         return np.asarray([pt2np(pt) for pt in cloud.points])           
00057 
00058 def location_from_cluster(cluster):
00059     pt = cloud2np(cluster).mean(axis=0)
00060     pt_stamped = PointStamped()
00061     pt_stamped.header = cluster.header
00062     pt_stamped.point.x, pt_stamped.point.y, pt_stamped.point.z = pt
00063     
00064     try:
00065         ptt = transform_point_stamped('/table', pt_stamped)
00066         return np.array([ptt.point.x,ptt.point.y,0])
00067     except tf.Exception as e:
00068         print 'exception...'
00069         return np.array([np.nan]*3)
00070 
00071 def detect(detect_srv):
00072     detection = detect_srv.call()
00073     objects = detection.clusters
00074     header = rospy.Header()
00075     header.stamp = rospy.Time.now()
00076     cloud = None
00077     table = None
00078     if objects:
00079         frame_id = objects[0].header.frame_id
00080         cloud = xyz_array_to_pointcloud2(np.asarray([location_from_cluster(obj) for obj in objects]), stamp=rospy.Time.now(), frame_id='/table')
00081     if detection.table.pose.header.frame_id:
00082         table = detection.table
00083     return cloud, table
00084 
00085 def broadcast_table_frame(args):
00086     if table_pose is None: return
00087     with tf_lock:
00088         trans, rot = pm.toTf(pm.fromMsg(table_pose.pose))
00089         br.sendTransform(trans, rot, rospy.Time.now(), '/table', table_pose.header.frame_id)
00090         br.sendTransform(trans, rot, rospy.Time.now() + rospy.Duration(0.005), '/table', table_pose.header.frame_id)
00091         br.sendTransform(trans, rot, rospy.Time.now() - rospy.Duration(0.005), '/table', table_pose.header.frame_id)
00092 
00093 def set_table_filter_limits(table, clients):
00094     for field, client in clients.iteritems():
00095         params = dict(
00096             filter_field_name = field
00097         )
00098         if field in ('x','y'):
00099             # params['input_frame'] = table.pose.header.frame_id
00100             params['input_frame']  = '/table'
00101             params['output_frame'] = '/table'
00102             
00103             params['filter_limit_min'] = table.__getattribute__('%s_min' % field)
00104             params['filter_limit_max'] = table.__getattribute__('%s_max' % field)
00105         else:
00106             params['input_frame']  = '/table'
00107             params['output_frame'] = '/table'
00108             params['filter_limit_min'] = -0.01
00109             params['filter_limit_max'] =  0.01
00110             # params['filter_limit_min'] = -5
00111             # params['filter_limit_max'] =  5
00112         client.update_configuration(params)
00113     
00114 
00115 if __name__ == '__main__':
00116     rospy.init_node('find_objects')
00117     object_pub = rospy.Publisher('object_cloud', PointCloud2)
00118     table_pub  = rospy.Publisher('table', Table)
00119     rate = rospy.get_param('~detect_rate', default=0.5)
00120     br = TransformBroadcaster() 
00121     detect_srv = rospy.ServiceProxy('/tabletop_segmentation', TabletopSegmentation)
00122     detect_srv.wait_for_service()
00123     Thread(target=rospy.Timer(rospy.Duration(0.05), broadcast_table_frame).run)
00124     #clients = dict(
00125     #    x = dynamic_reconfigure.client.Client('xfilter', timeout=float('inf')),
00126     #    y = dynamic_reconfigure.client.Client('yfilter', timeout=float('inf')),
00127     #    z = dynamic_reconfigure.client.Client('zfilter', timeout=float('inf'))
00128     #)
00129     r = rospy.Rate(rate)
00130     while not rospy.is_shutdown():
00131         try:
00132             object_cloud, table = detect(detect_srv)
00133             if table is not None:
00134                 with tf_lock:
00135                     if not table_pose or np.linalg.norm(pt2np(table_pose.pose.position) - pt2np(table.pose.pose.position)) > 0.1:
00136                         table_pose = table.pose
00137                 table_pub.publish(table)
00138 
00139             if object_cloud is not None:
00140                 #set_table_filter_limits(table, clients)
00141                 object_pub.publish(object_cloud)
00142             r.sleep()
00143         except rospy.service.ServiceException, e:
00144             pass


projector_interface
Author(s): Daniel Lazewatsky
autogenerated on Mon Oct 6 2014 10:12:36