00001 import roslib
00002 roslib.load_manifest('srs_states')
00003 import rospy
00004 import smach
00005 import smach_ros
00006
00007 from math import *
00008 import copy
00009 from struct import *
00010
00011 from simple_script_server import *
00012 sss = simple_script_server()
00013
00014 from cob_object_detection_msgs.msg import *
00015 from cob_object_detection_msgs.srv import *
00016 from shared_state_information import *
00017 from eval_objects import *
00018 from cob_3d_mapping_msgs.msg import *
00019
00020 from srs_knowledge.srv import *
00021
00022
00023
00024
00025
00026
00027 class detect_object(smach.State):
00028 def __init__(self,object_name = "",max_retries = 1):
00029 smach.State.__init__(
00030 self,
00031 outcomes=['succeeded','retry','no_more_retries','failed','preempted'],
00032 input_keys=['object_name'],
00033 output_keys=['object','object_pose'])
00034
00035 self.object_list = DetectionArray()
00036 self.max_retries = max_retries
00037 self.retries = 0
00038 self.object_name = object_name
00039 self.srv_name_object_detection = '/object_detection/detect_object'
00040 self.torso_poses = []
00041 self.torso_poses.append("back_right")
00042 self.torso_poses.append("back_right")
00043
00044 self.torso_poses.append("back")
00045 self.torso_poses.append("back")
00046
00047 self.torso_poses.append("back_left")
00048 self.torso_poses.append("back_left")
00049
00050 self.the_object = ''
00051 self.the_object_pose = ''
00052
00053
00054 def execute(self, userdata):
00055
00056 global current_task_info
00057
00058
00059 if current_task_info.get_object_identification_state() == True:
00060 userdata.object_pose = self.the_object_pose
00061 userdata.object = self.the_object
00062 return 'succeeded'
00063
00064 if self.preempt_requested():
00065 self.service_preempt()
00066 return 'preempted'
00067
00068 """
00069 # checking extra information
00070 if userdata.key_region == '':
00071 pass #normal detection
00072 else:
00073 pass #detection in bounding box specified by key_region
00074 """
00075
00076 userdata.object = ""
00077 userdata.object_pose=""
00078
00079 rospy.loginfo("object_name: %s", userdata.object_name)
00080
00081
00082 if self.object_name != "":
00083 object_name = self.object_name
00084 elif type(userdata.object_name) is str:
00085 object_name = userdata.object_name
00086 else:
00087 rospy.logerr("Invalid userdata 'object_name'")
00088 self.retries = 0
00089 return 'failed'
00090
00091
00092 if self.retries > self.max_retries:
00093 self.retries = 0
00094 handle_torso = sss.move("torso","home",False)
00095 handle_torso.wait()
00096 return 'no_more_retries'
00097
00098
00099 sss.move("sdh","cylclosed",False)
00100
00101
00102 if self.retries == 0:
00103 rospy.loginfo ("object_name: %s", object_name)
00104 sss.say([current_task_info.speaking_language['Search'] + object_name + "."],False)
00105 handle_arm = sss.move("arm","folded-to-look_at_table",False)
00106 handle_torso = sss.move("torso","shake",False)
00107 handle_head = sss.move("head","back",False)
00108
00109 if self.preempt_requested():
00110 self.service_preempt()
00111
00112 handle_arm.client.cancel_goal()
00113 handle_torso.client.cancel_goal()
00114 handle_head.client.cancel_goal()
00115 return 'preempted'
00116 else:
00117 handle_arm.wait()
00118 handle_head.wait()
00119 handle_torso.wait()
00120
00121 handle_torso = sss.move("torso",self.torso_poses[self.retries % len(self.torso_poses)])
00122
00123
00124 sss.move("sdh","home",False)
00125
00126
00127 sss.sleep(2)
00128
00129
00130
00131 try:
00132 rospy.wait_for_service(self.srv_name_object_detection,10)
00133 except rospy.ROSException, e:
00134 print "Service not available: %s"%e
00135 self.retries = 0
00136 return 'failed'
00137
00138
00139 try:
00140 detector_service = rospy.ServiceProxy(self.srv_name_object_detection, DetectObjects)
00141 req = DetectObjectsRequest()
00142 req.object_name.data = object_name
00143 res = detector_service(req)
00144 except rospy.ServiceException, e:
00145 print "Service call failed: %s"%e
00146 self.retries = 0
00147 return 'failed'
00148
00149
00150 if len(res.object_list.detections) <= 0:
00151 rospy.logerr("No objects found")
00152 self.retries += 1
00153 return 'retry'
00154
00155
00156 min_dist = 2
00157 obj = Detection()
00158 for item in res.object_list.detections:
00159 dist = sqrt(item.pose.pose.position.x*item.pose.pose.position.x+item.pose.pose.position.y*item.pose.pose.position.y)
00160 if dist < min_dist:
00161 min_dist = dist
00162 obj = copy.deepcopy(item)
00163
00164
00165 if obj.label == "":
00166 rospy.logerr("Object not within target range")
00167 self.retries += 1
00168 return 'retry'
00169
00170
00171 if obj.label != object_name:
00172 rospy.logerr("The object name doesn't fit.")
00173 self.retries += 1
00174 return 'retry'
00175
00176
00177 userdata.object = obj
00178 self.the_object = obj
00179 object_pose_map = PoseStamped()
00180 self.retries = 0
00181
00182 global listener
00183
00184 try:
00185
00186 object_pose_in = copy.deepcopy(obj.pose)
00187 print "###obj", obj
00188 print "###obj.pose", obj.pose
00189 object_pose_in.header.stamp = listener.getLatestCommonTime("/map",object_pose_in.header.frame_id)
00190 object_pose_map = listener.transformPose("/map", object_pose_in)
00191 obj.pose = copy.deepcopy(object_pose_map)
00192 userdata.object = obj
00193 except rospy.ROSException, e:
00194 print "Transformation not possible: %s"%e
00195 return 'failed'
00196
00197
00198
00199 userdata.object_pose=object_pose_map
00200 self.the_object_pose=object_pose_map
00201
00202 if self.preempt_requested():
00203 self.service_preempt()
00204 return 'preempted'
00205
00206
00207 current_task_info.set_object_identification_state(True)
00208 return 'succeeded'
00209
00210
00211 """Verifies whether the object expected at target_object_pose is actually there.
00212 If yes, verfified_target_object_pose is returned."""
00213 class VerifyObject(smach.State):
00214
00215 def __init__(self):
00216
00217 smach.State.__init__(
00218 self,
00219 outcomes=['succeeded', 'failed', 'not_completed', 'preempted'],
00220 input_keys=['object_id','target_object_pose'],
00221 output_keys=['verfified_target_object_pose'])
00222 self.eo = EvalObjects()
00223
00224
00225 def execute(self, userdata):
00226
00227
00228 """TODO: get classID for object_id or have class_id as input"""
00229 object_list_map = self.eo.map_list_objects(1)
00230
00231 verified_table = self.eo.verify_table(userdata.target_object_pose, object_list_map)
00232 if verified_table:
00233 userdata.verfified_target_object_pose = verified_table.pose.pose
00234 print "table " + str(userdata.target_object_pose.position.x) + "," + str(userdata.target_object_pose.position.y) + " found at " + str(verified_table.pose.pose.position.x) + "," + str(verified_table.pose.pose.position.y)
00235 return 'succeeded'
00236 else:
00237 print "table " + str(userdata.target_object_pose.position.x) + "," + str(userdata.target_object_pose.position.y) + " not found"
00238 return 'not_completed'
00239
00240
00241
00242
00243 """Verifies whether the object expected at target_object_pose is actually there.
00244 If yes, verfified_target_object_pose is returned."""
00245 class VerifyObjectByName(smach.State):
00246
00247 def __init__(self):
00248
00249 smach.State.__init__(
00250 self,
00251 outcomes=['succeeded', 'failed', 'not_completed', 'preempted'],
00252 input_keys=['object_name'],
00253 output_keys=['verfified_target_object_pose'])
00254 self.eo = EvalObjects()
00255
00256
00257 def execute(self, userdata):
00258
00259 target_object_pose =''
00260 object_id = -1000
00261 all_workspaces_on_map = ''
00262 index_of_the_target_workspace = ''
00263
00264 try:
00265 getWorkspace = rospy.ServiceProxy('get_workspace_on_map', GetWorkspaceOnMap)
00266 all_workspaces_on_map = getWorkspace(os.environ['ROBOT_ENV'], True)
00267
00268
00269 index_of_the_target_workspace = all_workspaces_on_map.objects.index(userdata.object_name)
00270
00271 target_object_pose = all_workspaces_on_map.objectsInfo[index_of_the_target_workspace].pose
00272
00273 object_id = all_workspaces_on_map.houseHoldId[index_of_the_target_workspace]
00274
00275 rospy.loginfo ("target name: %s", userdata.object_name)
00276 rospy.loginfo ("target pose: %s", target_object_pose)
00277 rospy.loginfo ("target id: %s", object_id)
00278
00279
00280 except rospy.ServiceException, e:
00281 print "Service call failed: %s"%e
00282 return 'failed'
00283
00284 """
00285 #checking object id in HHDB, maybe required for more complicated verification
00286 if object_id == -1000:
00287 #the object is not available in the HH database
00288 #verification not possible
00289 return 'not_completed'
00290 """
00291
00292
00293
00294 """TODO: get classID for object_id or have class_id as input"""
00295 object_list_map = self.eo.map_list_objects(1)
00296 print "object list map",object_list_map
00297
00298 verified_table = self.eo.verify_table(target_object_pose, object_list_map)
00299 if verified_table:
00300 userdata.verfified_target_object_pose = verified_table.pose.pose
00301 print "table " + str(userdata.target_object_pose.position.x) + "," + str(userdata.target_object_pose.position.y) + " found at " + str(verified_table.pose.pose.position.x) + "," + str(verified_table.pose.pose.position.y)
00302 return 'succeeded'
00303 else:
00304 print "table " + str(target_object_pose.position.x) + "," + str(target_object_pose.position.y) + " not found"
00305 return 'not_completed'
00306
00307
00308
00309
00310 """Observes the space over a table and returns objects as bounding boxes"""
00311 class GetTableObjectCluster(smach.State):
00312
00313 def __init__(self):
00314
00315 smach.State.__init__(
00316 self,
00317 outcomes=['succeeded', 'failed', 'not_completed', 'preempted'],
00318 input_keys=['target_table_pose'],
00319 output_keys=['object_cluster'])
00320 self.eo = EvalObjects()
00321 self.client = actionlib.SimpleActionClient('table_object_cluster', TableObjectClusterAction)
00322
00323 def execute(self, userdata):
00324
00325
00326 object_list_map = self.eo.map_list_objects(1)
00327
00328 verified_table = self.eo.verify_table(userdata.target_table_pose, object_list_map)
00329
00330 if verified_table:
00331 hull = verified_table.points[0]
00332
00333
00334 else:
00335 print "table " + str(userdata.target_table_pose.position.x) + "," + str(userdata.target_table_pose.position.y) + " not found"
00336 return 'not_completed'
00337 goal = TableObjectClusterGoal(hull)
00338 if not self.client.wait_for_server():
00339 rospy.logerr('server not available')
00340 return 'not_completed'
00341 self.client.send_goal(goal)
00342 if not self.client.wait_for_result():
00343 return 'not_completed'
00344 userdata.object_cluster = self.client.get_result().bounding_boxes
00345 return 'succeeded'
00346
00347
00348 """Checks, whether target_object_pose_on_table is occupied by at least one object of object_cluster.
00349 Returns succeded if the position is free and failed if the position is occupied"""
00350 class CheckPoseOnTableFree(smach.State):
00351
00352 def __init__(self):
00353
00354 smach.State.__init__(
00355 self,
00356 outcomes=['succeeded', 'failed', 'not_completed', 'preempted'],
00357 input_keys=['target_object_pose_on_table','object_cluster'],
00358 output_keys=[])
00359
00360 def execute(self, userdata):
00361 for bb in userdata.object_cluster:
00362 pt1 = []
00363 for i in range(0,3):
00364 pt1.append(unpack("f",bb.data[4*i:4*i+4])[0])
00365 pt2 = []
00366 for i in range(4,7):
00367 pt2.append(unpack("f",bb.data[4*i:4*i+4])[0])
00368 x = userdata.target_object_pose_on_table.position.x
00369 y = userdata.target_object_pose_on_table.position.y
00370 if x>pt1[0] and x<pt2[0] and y>pt1[1] and y<pt2[1]:
00371 print "target position occupied"
00372 return 'failed'
00373 else:
00374 print "target position free"
00375 return 'succeeded'
00376