Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
00111
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
00125
00126
00127
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
00141 object_pub.publish(object_cloud)
00142 r.sleep()
00143 except rospy.service.ServiceException, e:
00144 pass