detection_states.py
Go to the documentation of this file.
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 #import service form semantic KB
00020 from srs_knowledge.srv import *
00021 
00022 ## Detect state
00023 #
00024 # This state will try to detect an object.
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         #self.torso_poses.append("back_right_extreme")
00044         self.torso_poses.append("back")
00045         self.torso_poses.append("back")
00046         #self.torso_poses.append("back_extreme")
00047         self.torso_poses.append("back_left")
00048         self.torso_poses.append("back_left")
00049         #self.torso_poses.append("back_left_extreme")
00050         self.the_object = ''
00051         self.the_object_pose = ''
00052 
00053 
00054     def execute(self, userdata):
00055 
00056         global current_task_info
00057             #userdata.object_name = "milk"
00058         # if the object has been identified, and there was no base movement of grasp, then no need to detect again
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         #add initial value to output keys
00076         userdata.object = ""
00077         userdata.object_pose=""
00078         
00079         rospy.loginfo("object_name: %s", userdata.object_name)
00080         
00081         # determine object name
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: # this should never happen
00087             rospy.logerr("Invalid userdata 'object_name'")
00088             self.retries = 0
00089             return 'failed'
00090 
00091         # check if maximum retries reached
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         # move sdh as feedback
00099         sss.move("sdh","cylclosed",False)
00100 
00101         # make the robot ready to inspect the scene
00102         if self.retries == 0: # only move arm, sdh and head for the first try
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                 #handle_base.set_failed(4)
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)]) # have an other viewing point for each retry
00122 
00123         # move sdh as feedback
00124         sss.move("sdh","home",False)
00125 
00126         # wait for image to become stable
00127         sss.sleep(2)
00128 
00129 
00130         # check if object detection service is available
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 # no object found within min_dist start value
00136             return 'failed'
00137 
00138         # call object detection service
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         # check for no objects
00150         if len(res.object_list.detections) <= 0:
00151             rospy.logerr("No objects found")
00152             self.retries += 1
00153             return 'retry'
00154 
00155         # select nearest object in x-y-plane in head_camera_left_link
00156         min_dist = 2 # start value in m
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         # check if an object could be found within the min_dist start value
00165         if obj.label == "":
00166             rospy.logerr("Object not within target range")
00167             self.retries += 1
00168             return 'retry'
00169 
00170         #check if label of object fits to requested object_name
00171         if obj.label != object_name:
00172             rospy.logerr("The object name doesn't fit.")
00173             self.retries += 1
00174             return 'retry'
00175 
00176         # we succeeded to detect an object
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             #transform object_pose into base_link
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         #print object_pose_map
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         # remember the object has been identified, if there is no base movement of grasp, no need to detect again
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     #self.client = actionlib.SimpleActionClient('trigger_mapping', TriggerMappingAction)
00224 
00225   def execute(self, userdata):
00226     #object_to_search =self.eo.semantics_db_get_object_info(userdata.object_id)
00227     #print "Searching for object at " + str(object_to_search.objectPose.position.x) + ", " + str(object_to_search.objectPose.position.y)
00228     """TODO: get classID for object_id or have class_id as input"""
00229     object_list_map = self.eo.map_list_objects(1)#object_to_search.classID)
00230     #if object_to_search.classID == 1: #table
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     #else:
00240     #  print 'Object class not supported'
00241     #  return 'failed'
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     #self.client = actionlib.SimpleActionClient('trigger_mapping', TriggerMappingAction)
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         #get the index of the target workspace e.g. table0    
00269         index_of_the_target_workspace = all_workspaces_on_map.objects.index(userdata.object_name)
00270         #get the pose of the workspace from knowledge service
00271         target_object_pose = all_workspaces_on_map.objectsInfo[index_of_the_target_workspace].pose
00272         #get the houseHoldID of the workspace 
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     #object_to_search =self.eo.semantics_db_get_object_info(userdata.object_id)
00293     #print "Searching for object at " + str(object_to_search.objectPose.position.x) + ", " + str(object_to_search.objectPose.position.y)
00294     """TODO: get classID for object_id or have class_id as input"""
00295     object_list_map = self.eo.map_list_objects(1)#object_to_search.classID)
00296     print "object list map",object_list_map
00297     #if object_to_search.classID == 1: #table
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     #else:
00307     #  print 'Object class not supported'
00308     #  return 'failed'
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     #object_to_search =self.eo.semantics_db_get_object_info(userdata.object_id)
00325     #print "Searching for object at " + str(object_to_search.objectPose.position.x) + ", " + str(object_to_search.objectPose.position.y)
00326     object_list_map = self.eo.map_list_objects(1)#object_to_search.classID)
00327     #if object_to_search.classID == 1: #table
00328     verified_table = self.eo.verify_table(userdata.target_table_pose, object_list_map)
00329     #verified_table = object_list_map.objects.shapes[2]
00330     if verified_table:
00331         hull = verified_table.points[0]
00332         #print verified_table.params
00333         #print "table " + str(userdata.target_object_pose.position.x) + "," + str(userdata.target_object_pose.position.y) + " found at " + str(verified_table.params[4]) + "," + str(verified_table.params[5])
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():#rospy.Duration.from_sec(5.0)):
00339       rospy.logerr('server not available')
00340       return 'not_completed'
00341     self.client.send_goal(goal)
00342     if not self.client.wait_for_result():#rospy.Duration.from_sec(5.0)):
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 


srs_states
Author(s): Georg Arbeiter
autogenerated on Mon Oct 6 2014 08:34:06