challenge_hand_me_that
identify_object.py
Go to the documentation of this file.
1 # ROS
2 import PyKDL as kdl
3 from pykdl_ros import FrameStamped, VectorStamped
4 import rospy
5 import smach
6 import tf2_ros
7 
8 # TU/e Robotics
9 from ed.entity import Entity
10 
11 import robot_smach_states.util.designators as ds
12 from robot_smach_states.designator_iterator import IterateDesignator
13 from robot_smach_states.human_interaction import AskYesNo, Say
14 from robot_smach_states.manipulation import PrepareEdGrasp, ResetOnFailure
15 from robot_smach_states.navigation import NavigateToGrasp
16 from robot_smach_states.utility import WaitTime
17 from robot_skills.arm.arms import PublicArm
18 from robot_smach_states.utility import ResolveArm, check_arm_requirements
19 
20 
21 class PointAt(smach.State):
22  REQUIRED_ARM_PROPERTIES = {"required_goals": ["carrying_pose"], }
23 
24  def __init__(self, robot, arm, point_entity_designator):
25  """
26  Points at an item, similar to picking it up.
27 
28  :param robot: robot to execute this state with
29  :param arm: Designator that resolves to the arm to point at the entity with. E.g. UnoccupiedArmDesignator
30  :param point_entity_designator: Designator that resolves to the entity to point at. e.g EntityByIdDesignator
31  """
32  smach.State.__init__(self, outcomes=['succeeded', 'failed'])
33 
34  # Assign member variables
35  self.robot = robot
36  self.arm_des = arm
37 
38  ds.check_type(point_entity_designator, Entity)
39  self.point_entity_designator = point_entity_designator
40 
41  def execute(self, userdata=None):
42 
43  point_entity = self.point_entity_designator.resolve()
44  if not point_entity:
45  rospy.logerr("Could not resolve grab_entity")
46  return "failed"
47 
48  arm = self.arm_des.resolve()
49 
50  if not arm:
51  rospy.logerr("Could not resolve arm")
52  return "failed"
53 
54  goal_map = VectorStamped.from_xyz(0, 0, 0, rospy.Time(), point_entity.uuid)
55 
56  try:
57  # Transform to base link frame
58  goal_bl = self.robot.tf_buffer.transform(goal_map, self.robot.base_link_frame)
59  if goal_bl is None:
60  rospy.logerr('Transformation of goal to base failed')
61  return 'failed'
62  except tf2_ros.TransformException as tfe:
63  rospy.logerr('Transformation of goal to base failed: {0}'.format(tfe))
64  return 'failed'
65 
66  # Make sure the torso and the arm are done
67  self.robot.torso.wait_for_motion_done(cancel=True)
68  arm.wait_for_motion_done(cancel=True)
69 
70  # This is needed because the head is not entirely still when the
71  # look_at_point function finishes
72  rospy.sleep(0.5)
73 
74  # Resolve the entity again because we want the latest pose
75  updated_point_entity = self.point_entity_designator.resolve() # type: Entity
76 
77  rospy.loginfo("ID to update: {0}".format(point_entity.uuid))
78  if not updated_point_entity:
79  rospy.logerr("Could not resolve the updated grab_entity, "
80  "this should not happen [CHECK WHY THIS IS HAPPENING]")
81  point_entity = self.associate(original_entity=point_entity)
82  else:
83  rospy.loginfo("Updated pose of entity (dx, dy, dz) : (%f, %f, %f)" %
84  (updated_point_entity.pose.frame.p.x() - point_entity.pose.frame.p.x(),
85  updated_point_entity.pose.frame.p.y() - point_entity.pose.frame.p.y(),
86  updated_point_entity.pose.frame.p.z() - point_entity.pose.frame.p.z()))
87  point_entity = updated_point_entity
88  point_entity._last_update_time = rospy.Time() # Just the most recent time ToDo: Hack
89 
90  # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
91  # Grasp point determination
92  goal_bl = self._get_pointing_pose(point_entity)
93 
94  # Pointing with gripper closed is better
95  arm.gripper.send_goal('close')
96 
97  # Grasp
98  rospy.loginfo('Start pointing')
99  one_pointing_succeeded = False
100  z_offset = 0.02 # 2cm
101  for x_offset in [-0.15, 0.0]: # Hack because Hero does not pre-grasp reliably
102  _goal_bl = FrameStamped(goal_bl.frame * kdl.Frame(kdl.Vector(x_offset, 0.0, z_offset)), rospy.Time(),
103  goal_bl.header.frame_id)
104  if not arm.send_goal(_goal_bl, timeout=20, pre_grasp=False, allowed_touch_objects=[point_entity.uuid]):
105  self.robot.speech.speak('I am sorry but I cannot move my arm to the object position', block=False)
106  rospy.logerr('Pointing failed')
107  arm.reset()
108  else:
109  one_pointing_succeeded = True
110 
111  if not one_pointing_succeeded:
112  rospy.logerr("Both Pointing at failed")
113  return 'failed'
114 
115  # Retract
116  rospy.loginfo('Start retracting')
117  roll = 0.0
118 
119  goal_bl.frame.p.x(goal_bl.frame.p.x() - 0.1) # Retract 10 cm
120  goal_bl.frame.p.z(goal_bl.frame.p.z() + 0.05) # Go 5 cm higher
121  goal_bl.frame.M = kdl.Rotation.RPY(roll, 0.0, 0.0) # Update the roll
122  rospy.loginfo("Start retract")
123  if not arm.send_goal(goal_bl, timeout=0.0, allowed_touch_objects=[point_entity.uuid]):
124  rospy.logerr('Failed retract')
125  arm.wait_for_motion_done()
126  self.robot.base.force_drive(-0.125, 0, 0, 2.0)
127 
128  # Close gripper
129  arm.wait_for_motion_done(cancel=True)
130 
131  # Carrying pose
132  arm.send_joint_goal('carrying_pose', timeout=0.0)
133 
134  # Reset head
135  self.robot.head.cancel_goal()
136 
137  return "succeeded"
138 
139  def _get_pointing_pose(self, point_entity):
140  # type: (Entity, Arm) -> FrameStamped
141  """
142  Computes the pointing pose, i.e., where the grippoint should go to. The position is equal to the position of
143  the entity. The orientation is determined such that it easily aligns with the robot.
144 
145  :param point_entity: (Entity)
146  :return: (FrameStamped)
147  """
148  # Compute the frame w.r.t. base link
149  fs_robot = self.robot.tf_buffer.transform(point_entity.pose, self.robot.base_link_frame)
150 
151  # Set the orientation to unity
152  fs_robot.frame.M = kdl.Rotation()
153 
154  return fs_robot
155 
156 
157 class IdentifyObject(smach.StateMachine):
158  def __init__(self, robot, items, arm):
159  """
160  Has the robot points to the object that was pointed to by the operator.
161 
162  This is based on the 'Grab' state, with difference that pickup is changed, i.e., without closing gripper.
163 
164  :param robot: Robot to use
165  :param items: Designator that resolves to the list of items to point.
166  :param arm: Designator that resolves to the arm to use for grabbing. Eg. UnoccupiedArmDesignator
167  :return:
168  """
169  smach.StateMachine.__init__(self, outcomes=['done', 'failed'])
170 
171  # Check types or designator resolve types
172  ds.check_type(items, [Entity])
173  ds.check_type(arm, PublicArm)
174 
175  item = ds.VariableDesignator(resolve_type=Entity)
176 
177  with self:
178  smach.StateMachine.add('RESOLVE_ARM', ResolveArm(arm, self),
179  transitions={'succeeded': 'ITERATE_ITEM',
180  'failed': 'failed'})
181 
182  smach.StateMachine.add("ITERATE_ITEM", IterateDesignator(items, item.writeable),
183  transitions={'next': 'NAVIGATE_TO_POINT',
184  'stop_iteration': 'failed'})
185 
186  smach.StateMachine.add('NAVIGATE_TO_POINT', NavigateToGrasp(robot, arm, item),
187  transitions={'unreachable': 'WAIT_BEFORE_NAVIGATE_BACKUP',
188  'goal_not_defined': 'WAIT_BEFORE_NAVIGATE_BACKUP',
189  'arrived': 'PREPARE_POINT'})
190 
191  smach.StateMachine.add("ASK_OPERATOR_MOVE", Say(robot, "Operator, please move, so I can drive"),
192  transitions={'spoken': "WAIT_BEFORE_NAVIGATE_BACKUP"})
193 
194  smach.StateMachine.add('WAIT_BEFORE_NAVIGATE_BACKUP', WaitTime(robot, 5),
195  transitions={'waited': 'NAVIGATE_TO_POINT_BACKUP',
196  'preempted': 'failed'})
197 
198  smach.StateMachine.add('NAVIGATE_TO_POINT_BACKUP', NavigateToGrasp(robot, arm, item),
199  transitions={'unreachable': 'RESET_FAILURE',
200  'goal_not_defined': 'RESET_FAILURE',
201  'arrived': 'PREPARE_POINT'})
202 
203  smach.StateMachine.add('PREPARE_POINT', PrepareEdGrasp(robot, arm, item),
204  transitions={'succeeded': 'POINT',
205  'failed': 'RESET_FAILURE'})
206 
207  smach.StateMachine.add('POINT', PointAt(robot, arm, item),
208  transitions={'succeeded': 'ASK_CORRECT',
209  'failed': 'RESET_FAILURE'})
210 
211  smach.StateMachine.add("ASK_CORRECT", Say(robot, ["Is this the object you pointed at?",
212  "Did I got the correct object?"
213  ],
214  block=True,
215  look_at_standing_person=True),
216  transitions={'spoken': 'LISTEN_ANSWER'})
217 
218  smach.StateMachine.add("LISTEN_ANSWER", AskYesNo(robot),
219  transitions={'yes': 'done',
220  'no': 'SAY_ANOTHER_GUESS',
221  'no_result': 'done'})
222 
223  smach.StateMachine.add("SAY_ANOTHER_GUESS", Say(robot, ["Let me maybe try another guess"]),
224  transitions={'spoken': 'ITERATE_ITEM'})
225 
226  smach.StateMachine.add("RESET_FAILURE", ResetOnFailure(robot, arm),
227  transitions={'done': 'failed'})
228 
229  check_arm_requirements(self, robot)
230 
231 
232 if __name__ == "__main__":
233  from robot_skills import get_robot_from_argv
234 
235  rospy.init_node("test_grasping")
236 
237  robot = get_robot_from_argv(index=1)
238 
239  entity_id = "test_item"
240  pose = FrameStamped(kdl.Frame(kdl.Rotation.RPY(0, 0, -1.57), kdl.Vector(2.6, -0.95, 0.8)), rospy.Time.now(), "map")
241 
242  robot.ed.update_entity(uuid=entity_id, frame_stamped=pose)
243 
244  item = ds.EdEntityDesignator(robot, uuid=entity_id)
245 
246  arm = ds.UnoccupiedArmDesignator(robot, {})
247 
248  grab_state = IdentifyObject(robot, item, arm)
249  grab_state.execute()
challenge_hand_me_that.identify_object.PointAt.arm_des
arm_des
Definition: identify_object.py:36
challenge_hand_me_that.identify_object.PointAt.execute
def execute(self, userdata=None)
Definition: identify_object.py:41
challenge_hand_me_that.identify_object.IdentifyObject
Definition: identify_object.py:157
challenge_hand_me_that.identify_object.PointAt.point_entity_designator
point_entity_designator
Definition: identify_object.py:39
challenge_hand_me_that.identify_object.PointAt.__init__
def __init__(self, robot, arm, point_entity_designator)
Definition: identify_object.py:24
challenge_hand_me_that.identify_object.PointAt._get_pointing_pose
def _get_pointing_pose(self, point_entity)
Definition: identify_object.py:139
challenge_hand_me_that.identify_object.PointAt
Definition: identify_object.py:21
challenge_hand_me_that.identify_object.PointAt.robot
robot
Definition: identify_object.py:35
challenge_hand_me_that.identify_object.IdentifyObject.__init__
def __init__(self, robot, items, arm)
Definition: identify_object.py:158