arm_target.py
Go to the documentation of this file.
00001 '''Defines behaviour for ArmTarget primitive. This is for primitives
00002 where the arm moves to a single pose.
00003 '''
00004 
00005 # ######################################################################
00006 # Imports
00007 # ######################################################################
00008 # System builtins
00009 import math
00010 
00011 # Core ROS imports come first.
00012 import rospy
00013 
00014 # ROS builtins
00015 import tf
00016 from std_msgs.msg import ColorRGBA, String
00017 from geometry_msgs.msg import Vector3, Point, Pose, Quaternion, PoseStamped
00018 from visualization_msgs.msg import Marker, InteractiveMarker
00019 from visualization_msgs.msg import InteractiveMarkerControl
00020 from visualization_msgs.msg import InteractiveMarkerFeedback
00021 from interactive_markers.menu_handler import MenuHandler
00022 
00023 # Local
00024 from fetch_pbd_interaction.primitive import Primitive
00025 from fetch_arm_control.msg import GripperState
00026 from fetch_pbd_interaction.msg import ArmState, Landmark
00027 from fetch_pbd_interaction.srv import GetObjectList, \
00028                                       GetObjectFromName, GetMostSimilarObject
00029 
00030 # ######################################################################
00031 # Module level constants
00032 # ######################################################################
00033 
00034 # Marker options
00035 # --------------
00036 # Colors
00037 # COLOR_OBJ_REF_ARROW = ColorRGBA(1.0, 0.8, 0.2, 0.5)
00038 COLOR_MESH_REACHABLE = ColorRGBA(1.0, 0.5, 0.0, 0.6)
00039 COLOR_MESH_REACHABLE_SELECTED = ColorRGBA(0.0, 1.0, 0.0, 1.0)
00040 
00041 COLOR_MESH_UNREACHABLE = ColorRGBA(0.5, 0.5, 0.5, 0.6)
00042 COLOR_MESH_UNREACHABLE_SELECTED = ColorRGBA(0.5, 0.9, 0.5, 0.4)
00043 
00044 # Scales
00045 SCALE_TRAJ_STEP_SPHERES = Vector3(0.02, 0.02, 0.02)
00046 SCALE_OBJ_REF_ARROW = Vector3(0.02, 0.03, 0.04)
00047 
00048 # Gripper mesh related
00049 STR_MESH_GRIPPER_FOLDER = 'package://fetch_description/meshes/'
00050 STR_GRIPPER_PALM_FILE = STR_MESH_GRIPPER_FOLDER + 'gripper_link.STL'
00051 STR_L_GRIPPER_FINGER_FILE = STR_MESH_GRIPPER_FOLDER + \
00052                                 'l_gripper_finger_link.STL'
00053 STR_R_GRIPPER_FINGER_FILE = STR_MESH_GRIPPER_FOLDER + \
00054                                 'r_gripper_finger_link.STL'
00055 DEFAULT_OFFSET = 0.085
00056 
00057 # Right-click menu.
00058 MENU_OPTIONS = {
00059     'ref': 'Change target:',
00060     'move_here': 'Move arm here',
00061     'move_current': 'Move to current arm pose',
00062     'del': 'Delete'
00063     # 'target': 'Change target object:'
00064 }
00065 
00066 # Offets to maintain globally-unique IDs but with new sets of objects.
00067 # Each action step marker has a unique ID, and this allows each to
00068 # have a matching unique id for trajectories, text, etc. Assumes we'll
00069 # have < 1k steps.
00070 ID_OFFSET_REF_ARROW = 1000
00071 ID_OFFSET_TRAJ_FIRST = 2000
00072 ID_OFFSET_TRAJ_LAST = 3000
00073 
00074 # Other
00075 TRAJ_MARKER_LIFETIME = rospy.Duration()
00076 TEXT_Z_OFFSET = 0.1
00077 INT_MARKER_SCALE = 0.2
00078 TRAJ_ENDPOINT_SCALE = 0.05
00079 
00080 # ROS topics, etc.
00081 # ----------------
00082 # Namespace for interactive marker server.
00083 TOPIC_IM_SERVER = 'programmed_actions'
00084 
00085 # We might want to refactor this even further, as it's used throughout
00086 # the code.
00087 BASE_LINK = 'base_link'
00088 PREVIOUS_PRIMITIVE = "previous primitive"
00089 
00090 # ######################################################################
00091 # Classes
00092 # ######################################################################
00093 
00094 class ArmTarget(Primitive):
00095     '''Defines behaviour for ArmTarget primitive. This is for primitives
00096     where the arm moves to a single pose.
00097     '''
00098 
00099     _offset = DEFAULT_OFFSET
00100 
00101     def __init__(self, robot, tf_listener, im_server, arm_state=ArmState(),
00102                  gripper_state=None, number=None):
00103         '''
00104         Args:
00105             robot (Robot) : interface to lower level robot functionality
00106             tf_listener (TransformListener)
00107             im_server (InteractiveMarkerSerever)
00108             arm_state (ArmState, optional)
00109             gripper_state (GripperState.OPEN|GripperState.CLOSED, optional)
00110             number (int, optional): The number of this primitive in the
00111             action sequence
00112         '''
00113         self._name = "" #Unused currently
00114         self._im_server = im_server
00115         self._robot = robot
00116         self._arm_state = arm_state
00117         self._gripper_state = gripper_state
00118         self._number = number
00119         self._is_control_visible = False
00120         self._selected = False
00121         self._tf_listener = tf_listener
00122         self._marker_visible = False
00123         self._color_mesh_reachable = COLOR_MESH_REACHABLE
00124         self._color_mesh_unreachable = COLOR_MESH_UNREACHABLE
00125         self._reachable = True
00126         self._landmark_found = False
00127 
00128         self._menu_handler = MenuHandler()
00129 
00130         self._sub_ref_entries = None
00131         self._marker_click_cb = None
00132         self._marker_delete_cb = None
00133         self._pose_change_cb = None
00134         self._action_change_cb = None
00135 
00136         self._get_object_from_name_srv = rospy.ServiceProxy(
00137                                          '/fetch_pbd/get_object_from_name',
00138                                          GetObjectFromName)
00139         self._get_most_similar_obj_srv = rospy.ServiceProxy(
00140                                          '/fetch_pbd/get_most_similar_object',
00141                                          GetMostSimilarObject)
00142         self._get_object_list_srv = rospy.ServiceProxy(
00143                                         '/fetch_pbd/get_object_list',
00144                                         GetObjectList)
00145 
00146     # ##################################################################
00147     # Instance methods: Public (API)
00148     # ##################################################################
00149 
00150     def get_json(self):
00151         '''Returns json representation of primitive'''
00152 
00153         json = {}
00154 
00155         json['name'] = self._name
00156         json['number'] = self._number
00157         json['arm_state'] = ArmTarget._get_json_from_arm_state(self._arm_state)
00158         json['gripper_state'] = self._gripper_state
00159 
00160         return {'arm_target': json}
00161 
00162     def build_from_json(self, json):
00163         '''Fills out ArmTarget using json from db'''
00164 
00165         self._name = json['name']
00166         self._number = json['number']
00167         arm_state_json = json['arm_state']
00168 
00169         # build self._arm_state
00170         self._arm_state = ArmState()
00171         self._arm_state.ref_type = arm_state_json['ref_type']
00172         self._arm_state.joint_pose = arm_state_json['joint_pose']
00173         pose = ArmTarget._get_pose_stamped_from_json(arm_state_json['ee_pose'])
00174         self._arm_state.ee_pose = pose
00175 
00176         self._arm_state.ref_landmark = Landmark()
00177         landmark_name = arm_state_json['ref_landmark']['name']
00178         self._arm_state.ref_landmark.name = landmark_name
00179 
00180         landmark_pose_json = arm_state_json['ref_landmark']['pose']
00181         landmark_pose = ArmTarget._get_pose_from_json(landmark_pose_json)
00182         self._arm_state.ref_landmark.pose = landmark_pose
00183 
00184         landmark_dimensions = Vector3()
00185         x_dim = arm_state_json['ref_landmark']['dimensions']['x']
00186         y_dim = arm_state_json['ref_landmark']['dimensions']['y']
00187         z_dim = arm_state_json['ref_landmark']['dimensions']['z']
00188         landmark_dimensions.x = x_dim
00189         landmark_dimensions.y = y_dim
00190         landmark_dimensions.z = z_dim
00191 
00192         # build self._gripper_state
00193         self._gripper_state = json['gripper_state']
00194 
00195         self._arm_state.ref_landmark.dimensions = landmark_dimensions
00196 
00197     def check_pre_condition(self):
00198         ''' Currently just a placeholder
00199             Meant to return conditions that need to be met before a
00200             primitive can be executed. This could be something like
00201             "There should only be one object" or something.
00202 
00203             Returns:
00204                 None
00205         '''
00206         if self._arm_state.ref_type == ArmState.OBJECT:
00207             if not self._landmark_found:
00208                 return False, "No matching object found" + \
00209                         " for primitive: {}".format(self.get_name())
00210             else:
00211                 return True, None
00212         else: 
00213             return True, None
00214 
00215     def check_post_condition(self):
00216         ''' Currently just a placeholder
00217             Meant to return conditions that need to be met after a
00218             primitive is executed in order for execution to be a success.
00219             This could be something like "object must be 0.1m above surface"
00220 
00221             Returns:
00222                 None
00223         '''
00224 
00225         return True, None
00226 
00227     def add_marker_callbacks(self, click_cb, delete_cb, pose_change_cb,
00228                     action_change_cb):
00229         '''Adds marker to world'''
00230 
00231         # rospy.loginfo("Making marker")
00232         self._marker_click_cb = click_cb
00233         self._marker_delete_cb = delete_cb
00234         self._pose_change_cb = pose_change_cb
00235         self._action_change_cb = action_change_cb
00236         # self.update_ref_frames()
00237 
00238     def show_marker(self):
00239         '''Adds marker for primitive'''
00240         self._marker_visible = False
00241         if self.update_ref_frames():
00242             try:
00243                 self._update_menu()
00244                 self._update_viz_core()
00245                 self._menu_handler.apply(self._im_server, self.get_name())
00246                 self._im_server.applyChanges()
00247                 self._marker_visible = True
00248             except Exception, e:
00249                 rospy.logwarn("Show marker error: {}".format(e))
00250 
00251         return self._marker_visible
00252 
00253     def hide_marker(self):
00254         '''Removes marker from the world.'''
00255 
00256         rospy.loginfo("Deleting marker for: {}".format(self.get_name()))
00257         self._im_server.erase(self.get_name())
00258         self._im_server.applyChanges()
00259         self._marker_visible = False
00260 
00261     def marker_visible(self):
00262         '''Return whether or not marker is visible
00263 
00264         Returns:
00265             bool
00266         '''
00267         return self._marker_visible
00268 
00269     def update_ref_frames(self):
00270         '''Updates and re-assigns coordinate frames when the world changes.'''
00271 
00272         arm_pose = self._arm_state
00273         if arm_pose.ref_type == ArmState.OBJECT:
00274             prev_ref_obj = arm_pose.ref_landmark
00275             # rospy.loginfo("prev ref object: {}".format(prev_ref_obj))
00276             resp = self._get_most_similar_obj_srv(prev_ref_obj)
00277             if resp.has_similar:
00278                 self._arm_state.ref_landmark = resp.similar_object
00279                 self._arm_state.ee_pose.header.frame_id = resp.similar_object.name
00280                 self._landmark_found = True
00281                 return True
00282             else:
00283                 self._landmark_found = False
00284                 return False
00285         else:
00286             return True
00287 
00288     def change_ref_frame(self, ref_type, landmark):
00289         '''Sets new reference frame for primitive
00290 
00291         Args:
00292 
00293         '''
00294         self._arm_state.ref_type = ref_type
00295         # self._arm_state.ref_landmark = landmark
00296 
00297         self._convert_ref_frame(landmark)
00298         rospy.loginfo(
00299             'Switching reference frame for primitive ' +
00300             self.get_name())
00301         self._menu_handler.reApply(self._im_server)
00302         self._im_server.applyChanges()
00303         self.update_viz(False)
00304         self._action_change_cb()
00305 
00306     def get_ref_frame_name(self):
00307         '''Returns the name string for the reference frame object of the
00308         primitive.
00309 
00310         Returns:
00311             str|None: Under all normal circumstances, returns the str
00312                 reference frame name. Returns None in error.
00313         '''
00314         # "Normal" step (saved pose).
00315         ref_type = self._arm_state.ref_type
00316         ref_name = self._arm_state.ref_landmark.name
00317 
00318 
00319         # Update ref frame name if it's absolute.
00320         if ref_type == ArmState.ROBOT_BASE:
00321             ref_name = BASE_LINK
00322         elif ref_type == ArmState.PREVIOUS_TARGET:
00323             ref_name = "primitive_" + str(self._number - 1)
00324         elif ref_name == '':
00325             ref_name = BASE_LINK
00326             rospy.loginfo("Empty frame: {}".format(self._number))
00327 
00328         return ref_name
00329 
00330     def select(self, is_selected):
00331         '''Set whether primitive is selected or not
00332 
00333         Args:
00334             is_selected (bool)
00335         '''
00336         self._selected = is_selected
00337         self.set_control_visible(is_selected)
00338         if is_selected:
00339             self._color_mesh_reachable = COLOR_MESH_REACHABLE_SELECTED
00340             self._color_mesh_unreachable = COLOR_MESH_UNREACHABLE_SELECTED
00341         else:
00342             self._color_mesh_reachable = COLOR_MESH_REACHABLE
00343             self._color_mesh_unreachable = COLOR_MESH_UNREACHABLE
00344 
00345         # self.update_viz(False)
00346 
00347     def is_selected(self):
00348         '''Return whether or not primitive is selected
00349 
00350         Returns
00351             bool
00352         '''
00353         return self._selected
00354 
00355     def is_control_visible(self):
00356         '''Check if the marker control is visible
00357 
00358         Returns
00359             bool
00360         '''
00361         return self._is_control_visible
00362 
00363     def set_control_visible(self, visible=True):
00364         '''Set visibility of marker controls
00365 
00366         Args:
00367             visible (bool, optional)
00368         '''
00369         self._is_control_visible = visible
00370 
00371     def update_viz(self, check_reachable=True):
00372         '''Updates visualization fully.
00373         Args:
00374             check_reachable (bool) : whether to evaluate reachability
00375                                     before drawing marker
00376         '''
00377         rospy.loginfo("Updating viz for: {}".format(self.get_name()))
00378         draw_markers = True
00379         if self._arm_state.ref_type == ArmState.OBJECT:
00380             landmark_name = self._arm_state.ref_landmark.name
00381             resp = self._get_object_from_name_srv(landmark_name)
00382             if not resp.has_object:
00383                 draw_markers = False
00384 
00385         if draw_markers and self._marker_visible:
00386             try:
00387                 self._update_menu()
00388                 if self._update_viz_core(check_reachable):
00389                     self._menu_handler.apply(self._im_server, self.get_name())
00390                     self._im_server.applyChanges()
00391             except Exception, e:
00392                 rospy.logwarn("Error when updating primitive viz")
00393                 rospy.logwarn(e)
00394 
00395     def get_primitive_number(self):
00396         '''Returns what number this primitive is in the sequence
00397 
00398         Returns:
00399             int
00400         '''
00401         return self._number
00402 
00403     def set_primitive_number(self, number):
00404         '''Sets what number this primitive is in the sequence
00405 
00406         Args:
00407             num (int)
00408         '''
00409         self._number = number
00410 
00411     def is_object_required(self):
00412         '''Check if this primitive requires an object to be present
00413 
00414         Returns:
00415             bool
00416         '''
00417 
00418         is_required = False
00419         ref = self._arm_state.ref_type
00420 
00421         if ref == ArmState.OBJECT:
00422             is_required = True
00423 
00424         return is_required
00425 
00426     def execute(self):
00427         '''Execute this primitive
00428 
00429         Returns
00430             bool : Success of execution
00431         '''
00432         if not self._robot.move_arm_to_pose(self._arm_state):
00433             return False, "Problem finding IK solution"
00434         if not self._gripper_state == self._robot.get_gripper_state():
00435             self._robot.set_gripper_state(self._gripper_state)
00436         return True, None
00437 
00438     def head_busy(self):
00439         '''Return true if head busy
00440 
00441         Returns:
00442             bool
00443         '''
00444         return False
00445 
00446     def is_reachable(self):
00447         '''Check if robot can physically reach target'''
00448         self._reachable = self._robot.can_reach(self._arm_state)
00449         return self._reachable
00450 
00451     def get_relative_pose(self, use_final=True):
00452         '''Returns the relative pose of the primitive.
00453         Args:
00454             use_final (bool, optional) : Unused
00455         Returns:
00456             PoseStamped
00457         '''
00458         return self._arm_state.ee_pose
00459 
00460 
00461     def get_absolute_pose(self):
00462         '''Returns the absolute pose of the primitive.
00463 
00464         Args:
00465             None
00466 
00467         Returns:
00468             PoseStamped
00469         '''
00470         try:
00471             abs_pose = self._tf_listener.transformPose('base_link',
00472                                                self._arm_state.ee_pose)
00473             return abs_pose
00474         except:
00475             frame_id = self._arm_state.ee_pose.header.frame_id
00476             rospy.logwarn("Frame: {} does not exist".format(frame_id))
00477             return None
00478 
00479     def get_absolute_marker_pose(self, use_final=True):
00480         '''Returns the absolute pose of the primitive marker.
00481 
00482         Args:
00483             use_final (bool, optional). Unused
00484 
00485         Returns:
00486             PoseStamped
00487         '''
00488         try:
00489             abs_pose = self._tf_listener.transformPose('base_link',
00490                                                self._arm_state.ee_pose)
00491             return ArmTarget._offset_pose(abs_pose)
00492         except:
00493             frame_id = self._arm_state.ee_pose.header.frame_id
00494             # rospy.logwarn("Frame: {} does not exist".format(frame_id))
00495             return None
00496 
00497     def get_absolute_marker_position(self, use_final=True):
00498         '''Returns the absolute position of the primitive marker.
00499 
00500         Args:
00501             use_final (bool, optional) : Unused
00502                 True.
00503 
00504         Returns:
00505             Point
00506         '''
00507         abs_pose = self.get_absolute_marker_pose()
00508         if not abs_pose is None:
00509             return abs_pose.pose.position
00510         else:
00511             return None
00512 
00513     def decrease_id(self):
00514         '''Reduces the number of the primitive.'''
00515         self._number -= 1
00516 
00517     def set_name(self, name):
00518         '''Sets the display name for the primitive.
00519 
00520         Args:
00521             name (str) : A human-readable unique name for the primitive.
00522         '''
00523         self._name = name
00524 
00525     def get_name(self):
00526         '''Returns the display name for the primitive.
00527 
00528         Returns:
00529             str: A human-readable unique name for the primitive.
00530         '''
00531         return self._name
00532 
00533     def get_number(self):
00534         '''Returns number of primitive
00535 
00536         Returns:
00537             int
00538         '''
00539         return self._number
00540 
00541     def set_pose(self, new_pose):
00542         '''Changes the pose of the primitive to new_pose.
00543 
00544         Args:
00545             new_pose (PoseStamped)
00546         '''
00547         self._arm_state.ee_pose = new_pose
00548         self.update_viz()
00549         self._action_change_cb()
00550 
00551     def pose_editable(self):
00552         '''Return whether pose of primitive is editable
00553 
00554         Returns:
00555             bool : True
00556         '''
00557         return True
00558 
00559     def get_ref_type(self):
00560         '''Return reference type of primitive
00561 
00562         Returns:
00563             ArmState.ROBOT_BASE, etc
00564         '''
00565         return self._arm_state.ref_type
00566 
00567     # ##################################################################
00568     # Static methods: Internal ("private")
00569     # ##################################################################
00570 
00571     @staticmethod
00572     def _get_json_from_arm_state(arm_state):
00573         '''Return json containing data of arm_state
00574 
00575         Args:
00576             arm_state (ArmState)
00577         Returns:
00578             json (dict)
00579         '''
00580         json = {}
00581         json['ref_type'] = arm_state.ref_type
00582         json['joint_pose'] = arm_state.joint_pose
00583         pose = ArmTarget._get_json_from_pose_stamped(arm_state.ee_pose)
00584         json['ee_pose'] = pose
00585         landmark = arm_state.ref_landmark
00586         json['ref_landmark'] = ArmTarget._get_json_from_landmark(landmark)
00587         return json
00588 
00589     @staticmethod
00590     def _get_json_from_pose_stamped(pose_stamped):
00591         '''Return json containing data of pose_stamped
00592 
00593         Args:
00594             pose_stamped (PoseStamped)
00595         Returns:
00596             json (dict)
00597         '''
00598         json = {}
00599         json['pose'] = ArmTarget._get_json_from_pose(pose_stamped.pose)
00600         json['frame_id'] = pose_stamped.header.frame_id
00601 
00602         return json
00603 
00604     @staticmethod
00605     def _get_json_from_pose(pose):
00606         '''Return json containing data of pose
00607 
00608         Args:
00609             pose (Pose)
00610         Returns:
00611             json (dict)
00612         '''
00613         json = {}
00614         json['position'] = {}
00615         json['position']['x'] = pose.position.x
00616         json['position']['y'] = pose.position.y
00617         json['position']['z'] = pose.position.z
00618 
00619         json['orientation'] = {}
00620         json['orientation']['x'] = pose.orientation.x
00621         json['orientation']['y'] = pose.orientation.y
00622         json['orientation']['z'] = pose.orientation.z
00623         json['orientation']['w'] = pose.orientation.w
00624 
00625         return json
00626 
00627     @staticmethod
00628     def _get_json_from_landmark(landmark):
00629         '''Return json containing data of landmark
00630 
00631         Args:
00632             landmark (Landmark)
00633         Returns:
00634             json (dict)
00635         '''
00636         json = {}
00637         # json['type'] = landmark.type
00638         json['name'] = landmark.name
00639         json['pose'] = ArmTarget._get_json_from_pose(landmark.pose)
00640         json['dimensions'] = {}
00641         json['dimensions']['x'] = landmark.dimensions.x
00642         json['dimensions']['y'] = landmark.dimensions.y
00643         json['dimensions']['z'] = landmark.dimensions.z
00644 
00645         return json
00646 
00647     @staticmethod
00648     def _get_pose_stamped_from_json(json):
00649         '''Return PoseStamped msg from json
00650 
00651         Args:
00652             json (dict)
00653         Returns:
00654             PoseStamped
00655         '''
00656         pose_stamped = PoseStamped()
00657         pose = ArmTarget._get_pose_from_json(json['pose'])
00658         pose_stamped.pose = pose
00659         pose_stamped.header.frame_id = json['frame_id']
00660 
00661         return pose_stamped
00662 
00663     @staticmethod
00664     def _get_pose_from_json(json):
00665         '''Return Pose msg from json
00666 
00667         Args:
00668             json (dict)
00669         Returns:
00670             Pose
00671         '''
00672         pose = Pose()
00673 
00674         pose.position.x = json['position']['x']
00675         pose.position.y = json['position']['y']
00676         pose.position.z = json['position']['z']
00677 
00678         pose.orientation.x = json['orientation']['x']
00679         pose.orientation.y = json['orientation']['y']
00680         pose.orientation.z = json['orientation']['z']
00681         pose.orientation.w = json['orientation']['w']
00682 
00683         return pose
00684 
00685     @staticmethod
00686     def _diff(float1, float2, thresh):
00687         '''Return true if floats are different by a threshold
00688 
00689         Args:
00690             float1 (float)
00691             float2 (float)
00692             thresh (float)
00693         '''
00694         if math.fabs(float1 - float2) < thresh:
00695             return False
00696         else:
00697             return True
00698 
00699     @staticmethod
00700     def _offset_pose(pose, constant=1):
00701         '''Offsets the world pose for visualization.
00702 
00703         Args:
00704             pose (PoseStamped): The pose to offset.
00705             constant (int, optional): How much to scale the set offset
00706                 by (scales ArmTarget._offset). Defaults to 1.
00707 
00708         Returns:
00709             PoseStamped: The offset pose.
00710         '''
00711         transform = ArmTarget._get_matrix_from_pose(pose)
00712         offset_array = [constant * ArmTarget._offset, 0, 0]
00713         offset_transform = tf.transformations.translation_matrix(offset_array)
00714         hand_transform = tf.transformations.concatenate_matrices(
00715             transform, offset_transform)
00716 
00717         new_pose = PoseStamped()
00718         new_pose.header.frame_id = pose.header.frame_id
00719         new_pose.pose = ArmTarget._get_pose_from_transform(hand_transform)
00720         return new_pose
00721 
00722     @staticmethod
00723     def _get_matrix_from_pose(pose):
00724         '''Returns the transformation matrix for given pose.
00725 
00726         Args:
00727             pose (PoseStamped)
00728 
00729         Returns:
00730             Matrix3x3
00731         '''
00732         position, orientation = pose.pose.position, pose.pose.orientation
00733         rot_list = [orientation.x, orientation.y, orientation.z, orientation.w]
00734         transformation = tf.transformations.quaternion_matrix(rot_list)
00735         pos_list = [position.x, position.y, position.z]
00736         transformation[:3, 3] = pos_list
00737         return transformation
00738 
00739     @staticmethod
00740     def _get_pose_from_transform(transform):
00741         '''Returns pose for transformation matrix.
00742 
00743         Args:
00744             transform (Matrix3x3): (I think this is the correct type.
00745                 See ArmTarget as a reference for how to use.)
00746 
00747         Returns:
00748             Pose
00749         '''
00750         pos = transform[:3, 3].copy()
00751         rot = tf.transformations.quaternion_from_matrix(transform)
00752         return Pose(
00753             Point(pos[0], pos[1], pos[2]),
00754             Quaternion(rot[0], rot[1], rot[2], rot[3])
00755         )
00756 
00757     @staticmethod
00758     def _make_mesh_marker(color):
00759         '''Creates and returns a mesh marker.
00760 
00761         Returns:
00762             Marker
00763         '''
00764         mesh = Marker()
00765         mesh.mesh_use_embedded_materials = False
00766         mesh.type = Marker.MESH_RESOURCE
00767         mesh.scale.x = 1.0
00768         mesh.scale.y = 1.0
00769         mesh.scale.z = 1.0
00770         mesh.color = color
00771         return mesh
00772 
00773     # ##################################################################
00774     # Instance methods: Internal ("private")
00775     # ##################################################################
00776 
00777     def _update_menu(self):
00778         '''Recreates the menu when something has changed.'''
00779         rospy.loginfo("Making new menu")
00780         self._menu_handler = MenuHandler()
00781 
00782         # Insert sub entries.
00783         self._sub_ref_entries = []
00784         frame_entry = self._menu_handler.insert(MENU_OPTIONS['ref'])
00785         object_list = self._get_object_list_srv().object_list
00786         refs = [obj.name for obj in object_list]
00787         if self._number > 0:
00788             refs.append(PREVIOUS_PRIMITIVE)
00789         if len(refs) > 0:
00790             refs.append(BASE_LINK)
00791         for ref in refs:
00792             subent = self._menu_handler.insert(
00793                 ref, parent=frame_entry, callback=self._change_ref_cb)
00794             self._sub_ref_entries += [subent]
00795 
00796 
00797         # Make all unchecked to start.
00798         for subent in self._sub_ref_entries:
00799             self._menu_handler.setCheckState(subent, MenuHandler.UNCHECKED)
00800 
00801         # Check if necessary.
00802         menu_id = self._get_menu_ref_id(self._get_menu_ref())
00803         if not menu_id is None:
00804             # self.has_object = False
00805             self._menu_handler.setCheckState(menu_id, MenuHandler.CHECKED)
00806 
00807 
00808         # self._sub_target_entries = []
00809         # target_entry = self._menu_handler.insert(MENU_OPTIONS['target'])
00810         # object_list = self._get_object_list_srv().object_list
00811         # targets = [obj.name + " " for obj in object_list]
00812         # for target in targets:
00813         #     subent = self._menu_handler.insert(
00814         #         target, parent=target_entry, callback=self._change_target_cb)
00815         #     self._sub_target_entries += [subent]
00816 
00817         # Make all unchecked to start.
00818         # for subent in self._sub_target_entries:
00819         #     self._menu_handler.setCheckState(subent, MenuHandler.UNCHECKED)
00820 
00821         # Check if necessary.
00822         # menu_id = self._get_menu_target_id(self._get_menu_ref(target=True))
00823         # if not menu_id is None:
00824         #     # self.has_object = False
00825         #     self._menu_handler.setCheckState(menu_id, MenuHandler.CHECKED)
00826 
00827         # Inset main menu entries.
00828 
00829         self._menu_handler.insert(
00830             MENU_OPTIONS['move_here'], callback=self._move_to_cb)
00831         self._menu_handler.insert(
00832             MENU_OPTIONS['move_current'], callback=self._move_pose_to_cb)
00833         self._menu_handler.insert(
00834             MENU_OPTIONS['del'], callback=self._delete_primitive_cb)
00835 
00836         # Update.
00837 
00838     def _get_menu_ref_id(self, ref_name):
00839         '''Returns the unique menu id from its name or None if the
00840         object is not found.
00841 
00842         Args:
00843             ref_name (str)
00844         Returns:
00845             int (?)|None
00846         '''
00847         object_list = self._get_object_list_srv().object_list
00848         refs = [obj.name for obj in object_list]
00849         if self._number > 0:
00850             refs.append(PREVIOUS_PRIMITIVE)
00851         refs.append(BASE_LINK)
00852         if ref_name in refs:
00853             index = refs.index(ref_name)
00854             if index < len(self._sub_ref_entries):
00855                 return self._sub_ref_entries[index]
00856             else:
00857                 return None
00858         else:
00859             return None
00860 
00861     # def _get_menu_target_id(self, ref_name):
00862     #     '''Returns the unique menu id from its name or None if the
00863     #     object is not found.
00864 
00865     #     Args:
00866     #         ref_name (str)
00867     #     Returns:
00868     #         int (?)|None
00869     #     '''
00870     #     object_list = self._get_object_list_srv().object_list
00871     #     refs = [obj.name + " " for obj in object_list]
00872     #     if ref_name in refs:
00873     #         index = refs.index(ref_name)
00874     #         if index < len(self._sub_target_entries):
00875     #             return self._sub_target_entries[index]
00876     #         else:
00877     #             return None
00878     #     else:
00879     #         return None
00880 
00881 
00882     def _get_menu_ref_name(self, menu_id):
00883         '''Returns the menu name from its unique menu id.
00884 
00885         Args:
00886             menu_id (int)
00887         Returns:
00888             str
00889         '''
00890         index = self._sub_ref_entries.index(menu_id)
00891         object_list = self._get_object_list_srv().object_list
00892         refs = [obj.name for obj in object_list]
00893         if self._number > 0:
00894             refs.append(PREVIOUS_PRIMITIVE)
00895         refs.append(BASE_LINK)
00896         return refs[index]
00897 
00898     # def _get_menu_target_name(self, menu_id):
00899     #     '''Returns the menu name from its unique menu id.
00900 
00901     #     Args:
00902     #         menu_id (int)
00903     #     Returns:
00904     #         str
00905     #     '''
00906     #     index = self._sub_target_entries.index(menu_id)
00907     #     object_list = self._get_object_list_srv().object_list
00908     #     refs = [obj.name for obj in object_list]
00909     #     return refs[index]
00910 
00911 
00912     def _set_target(self, new_ref):
00913         '''Changes the reference frame of the primitive to
00914         new_ref_name.
00915 
00916         Args:
00917             new_ref_name
00918         '''
00919         # Get the id of the new ref (an int).
00920         self._arm_state.ref_type = ArmState.OBJECT
00921         new_ref_obj = self._get_object_from_name_srv(new_ref).obj
00922         rospy.loginfo("Setting reference of primitive" + 
00923                       "{} to object".format(self._number))
00924         self._arm_state.ref_landmark = new_ref_obj
00925         self._landmark_found = True
00926         self._arm_state.ee_pose.header.frame_id = new_ref_obj.name
00927 
00928     def _set_ref(self, new_ref):
00929         '''Changes the reference frame of the primitive to
00930         new_ref_name.
00931 
00932         Args:
00933             new_ref_name
00934         '''
00935         # Get the id of the new ref (an int).
00936         new_ref_obj = Landmark()
00937         if new_ref == PREVIOUS_PRIMITIVE:
00938             self._arm_state.ref_type = ArmState.PREVIOUS_TARGET
00939             rospy.loginfo("PREVIOUS!!!")
00940         elif new_ref == BASE_LINK:
00941             self._arm_state.ref_type = ArmState.ROBOT_BASE
00942         else:
00943             self._arm_state.ref_type = ArmState.OBJECT
00944             new_ref_obj = self._get_object_from_name_srv(new_ref).obj
00945             rospy.loginfo("OBJECT!!!")
00946 
00947         self._convert_ref_frame(new_ref_obj)
00948 
00949     def _convert_ref_frame(self, new_landmark):
00950         '''Convert arm_state to be in a different reference frame
00951 
00952             Args:
00953                 new_landmark (Landmark)
00954             Returns:
00955                 ArmState
00956         '''
00957         if self._arm_state.ref_type == ArmState.OBJECT:
00958             rospy.loginfo("Relative to object")
00959             if self._arm_state.ref_landmark.name != new_landmark.name:
00960                 ee_pose = self._tf_listener.transformPose(
00961                                     new_landmark.name,
00962                                     self._arm_state.ee_pose
00963                                 )
00964                 self._arm_state.ref_landmark = new_landmark
00965                 self._landmark_found = True
00966                 self._arm_state.ee_pose = ee_pose
00967         elif self._arm_state.ref_type == ArmState.ROBOT_BASE:
00968             ee_pose = self._tf_listener.transformPose(
00969                                     BASE_LINK,
00970                                     self._arm_state.ee_pose
00971                                 )
00972             self._arm_state.ee_pose = ee_pose
00973             self._arm_state.ref_landmark = Landmark()
00974             self._landmark_found = False
00975         elif self._arm_state.ref_type == ArmState.PREVIOUS_TARGET:
00976             prev_frame_name = 'primitive_' + str(self._number - 1)
00977             rospy.loginfo("Original pose: {}".format(self._arm_state.ee_pose))
00978             ee_pose = self._tf_listener.transformPose(
00979                                     prev_frame_name,
00980                                     self._arm_state.ee_pose
00981                                 )
00982             rospy.loginfo("New pose: {}".format(ee_pose))
00983 
00984             self._arm_state.ee_pose = ee_pose
00985             self._arm_state.ref_landmark = Landmark()
00986             self._landmark_found = False
00987 
00988     def _get_marker_pose(self):
00989         '''Returns the pose of the primitive.
00990 
00991         Returns:
00992             Pose
00993         '''
00994         rospy.loginfo("Pose frame is: {}".format(self.get_ref_frame_name()))
00995 
00996         try:
00997             rospy.loginfo("Pose: {}".format(self._arm_state.ee_pose))
00998             self._tf_listener.waitForTransform(BASE_LINK,
00999                                  self._arm_state.ee_pose.header.frame_id,
01000                                  rospy.Time.now(),
01001                                  rospy.Duration(4.0))
01002             intermediate_pose = self._tf_listener.transformPose(
01003                                                         BASE_LINK,
01004                                                         self._arm_state.ee_pose)
01005             offset_pose = ArmTarget._offset_pose(intermediate_pose)
01006             # return self._tf_listener.transformPose(BASE_LINK,
01007             #                                     offset_pose)
01008             return offset_pose
01009         except Exception, e:
01010             rospy.logwarn(e)
01011             rospy.logwarn("Frame not available yet: {}".format(self.get_ref_frame_name()))
01012             return None
01013 
01014     def _update_viz_core(self, check_reachable=True):
01015         '''Updates visualization after a change.
01016 
01017         Args:
01018             check_reachable (bool) : Check reachability of pose before drawing marker
01019         '''
01020         # Create a new IM control.
01021         menu_control = InteractiveMarkerControl()
01022         menu_control.interaction_mode = InteractiveMarkerControl.BUTTON
01023         menu_control.always_visible = True
01024         frame_id = BASE_LINK #self.get_ref_frame_name()
01025         pose = self._get_marker_pose()
01026         if pose is None:
01027             return
01028 
01029         if check_reachable:
01030             if not self.is_reachable():
01031                 rospy.logwarn("Marker pose not reachable")
01032             else:
01033                 rospy.loginfo("Marker pose is reachable")
01034 
01035         menu_control = self._make_gripper_marker(
01036                menu_control, self._gripper_state)
01037 
01038         # Make and add interactive marker.
01039         int_marker = InteractiveMarker()
01040         int_marker.name = self.get_name()
01041         int_marker.header.frame_id = frame_id
01042         int_marker.pose = pose.pose
01043         int_marker.scale = INT_MARKER_SCALE
01044         self._add_6dof_marker(int_marker, True)
01045         int_marker.controls.append(menu_control)
01046         prev_marker = self._im_server.get(self.get_name())
01047         prev_color = None
01048         if not prev_marker is None:
01049             if len(prev_marker.controls) > 0:
01050                 if len(prev_marker.controls[-1].markers) > 0:
01051                     prev_color = prev_marker.controls[-1].markers[-1].color
01052         new_color = None
01053         if len(int_marker.controls) > 0:
01054             if len(int_marker.controls[-1].markers) > 0:
01055                 new_color = int_marker.controls[-1].markers[-1].color
01056 
01057         if not prev_marker:
01058             self._im_server.insert(
01059                 int_marker, self._marker_feedback_cb)
01060             rospy.logwarn("Adding marker for primitive {}".format(self.get_number()))
01061             return True
01062         elif (prev_marker.pose != int_marker.pose) or (prev_color != new_color):
01063             rospy.loginfo("Updating marker")
01064             self._im_server.insert(
01065                 int_marker, self._marker_feedback_cb)
01066             return True
01067 
01068         rospy.logwarn("Not updating marker for primitive {}".format(self.get_number()))
01069         return False
01070 
01071     def _add_6dof_marker(self, int_marker, is_fixed):
01072         '''Adds a 6 DoF control marker to the interactive marker.
01073 
01074         Args:
01075             int_marker (InteractiveMarker)
01076             is_fixed (bool): Looks like whether position is fixed (?).
01077                 Currently only passed as True.
01078         '''
01079         # Each entry in options is (name, orientation, is_move)
01080         options = [
01081             ('rotate_x', Quaternion(1, 0, 0, 1), False),
01082             ('move_x', Quaternion(1, 0, 0, 1), True),
01083             ('rotate_z', Quaternion(0, 1, 0, 1), False),
01084             ('move_z', Quaternion(0, 1, 0, 1), True),
01085             ('rotate_y', Quaternion(0, 0, 1, 1), False),
01086             ('move_y', Quaternion(0, 0, 1, 1), True),
01087         ]
01088         for opt in options:
01089             name, orient, is_move = opt
01090             control = self._make_6dof_control(name, orient, is_move, is_fixed)
01091             int_marker.controls.append(control)
01092 
01093     def _make_6dof_control(self, name, orientation, is_move, is_fixed):
01094         '''Creates and returns one component of the 6dof controller.
01095 
01096         Args:
01097             name (str): Name for hte control
01098             orientation (Quaternion): How the control should be
01099                 oriented.
01100             is_move (bool): Looks like whether the marker moves the
01101                 object (?). Currently passed as True for moving markers,
01102                 False for rotating ones.
01103             is_fixed (bool): Looks like whether position is fixed (?).
01104                 Currently always passed as True.
01105 
01106         Returns:
01107             InteractiveMarkerControl
01108         '''
01109         control = InteractiveMarkerControl()
01110         control.name = name
01111         control.orientation = orientation
01112         control.always_visible = False
01113         if self._is_control_visible:
01114             if is_move:
01115                 control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS
01116             else:
01117                 control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS
01118         else:
01119             control.interaction_mode = InteractiveMarkerControl.NONE
01120         if is_fixed:
01121             control.orientation_mode = InteractiveMarkerControl.FIXED
01122         return control
01123 
01124     def _set_new_pose(self, new_pose, frame_id):
01125         '''Changes the pose of the primitive to new_pose.
01126 
01127         Args:
01128             new_pose (Pose)
01129         '''
01130         rospy.loginfo("Setting new ee_pose!!!")
01131         pose_stamped = PoseStamped()
01132         pose_stamped.header.frame_id = frame_id
01133         pose_stamped.pose = new_pose
01134         pose_stamped_transformed = self._tf_listener.transformPose(
01135                                                     self.get_ref_frame_name(),
01136                                                     pose_stamped)
01137         self._arm_state.ee_pose = ArmTarget._offset_pose(
01138                                                     pose_stamped_transformed,
01139                                                     -1)
01140         self.update_viz()
01141 
01142     def _pose_changed(self, new_pose, frame_id):
01143         '''Check if marker pose has changed
01144 
01145         Args: 
01146             pose (Pose)
01147         '''
01148         pose_stamped = PoseStamped()
01149         pose_stamped.header.frame_id = frame_id
01150         pose_stamped.pose = new_pose
01151         pose_stamped_transformed = self._tf_listener.transformPose(
01152                                                     self.get_ref_frame_name(),
01153                                                     pose_stamped)
01154         offset_pose = ArmTarget._offset_pose(pose_stamped_transformed,
01155                                                     -1)
01156         if ArmTarget._diff(offset_pose.pose.position.x, 
01157                             self._arm_state.ee_pose.pose.position.x,
01158                             0.001) \
01159             or ArmTarget._diff(offset_pose.pose.position.y, 
01160                             self._arm_state.ee_pose.pose.position.y,
01161                             0.001) \
01162             or ArmTarget._diff(offset_pose.pose.position.z, 
01163                             self._arm_state.ee_pose.pose.position.z,
01164                             0.001) \
01165             or ArmTarget._diff(offset_pose.pose.orientation.x, 
01166                             self._arm_state.ee_pose.pose.orientation.x,
01167                             0.01) \
01168             or ArmTarget._diff(offset_pose.pose.orientation.y, 
01169                             self._arm_state.ee_pose.pose.orientation.y,
01170                             0.01) \
01171             or ArmTarget._diff(offset_pose.pose.orientation.z, 
01172                             self._arm_state.ee_pose.pose.orientation.z,
01173                             0.01) \
01174             or ArmTarget._diff(offset_pose.pose.orientation.w, 
01175                             self._arm_state.ee_pose.pose.orientation.w,
01176                             0.01):
01177             rospy.loginfo("New pose: {}".format(new_pose))
01178             rospy.loginfo("New pose transformed: {}".format(offset_pose))
01179             rospy.loginfo("Old pose: {}".format(self._arm_state.ee_pose))
01180             return True
01181         else:
01182             return False
01183 
01184     def _get_mesh_marker_color(self):
01185         '''Gets the color for the mesh marker (thing that looks like a
01186         gripper) for this primitive.
01187 
01188         A simple implementation of this will return one color for
01189         reachable poses, another for unreachable ones. Future
01190         implementations may provide further visual cues.
01191 
01192         Returns:
01193             ColorRGBA: The color for the gripper mesh for this arm target.
01194         '''
01195         if self._reachable:
01196             return self._color_mesh_reachable
01197         else:
01198             return self._color_mesh_unreachable
01199 
01200     def _make_gripper_marker(self, control, gripper_state=GripperState.CLOSED):
01201         '''Makes a gripper marker, adds it to control, returns control.
01202 
01203         Args:
01204             control (InteractiveMarkerControl): IM Control we're using.
01205             is_hand_open (bool, optional): Whether the gripper is open.
01206                 Defaults to False (closed).
01207 
01208         Returns:
01209             InteractiveMarkerControl: The passed control.
01210         '''
01211 
01212         mesh_color = self._get_mesh_marker_color()
01213         # frame_id = self._get_menu_ref()
01214 
01215         # Create mesh 1 (palm).
01216         mesh1 = ArmTarget._make_mesh_marker(mesh_color)
01217         mesh1.mesh_resource = STR_GRIPPER_PALM_FILE
01218         mesh1.pose.position.x = ArmTarget._offset
01219         mesh1.pose.orientation.w = 1
01220         # mesh1.header.frame_id = frame_id
01221 
01222         # TODO (sarah): make all of these numbers into constants
01223         if gripper_state == GripperState.OPEN:
01224             mesh2 = ArmTarget._make_mesh_marker(mesh_color)
01225             mesh2.mesh_resource = STR_L_GRIPPER_FINGER_FILE
01226             mesh2.pose.position.x = 0.08
01227             mesh2.pose.position.y = -0.165
01228             mesh2.pose.orientation.w = 1
01229             # mesh2.header.frame_id = frame_id
01230 
01231             mesh3 = ArmTarget._make_mesh_marker(mesh_color)
01232             mesh3.mesh_resource = STR_R_GRIPPER_FINGER_FILE
01233             mesh3.pose.position.x = 0.08
01234             mesh3.pose.position.y = 0.165
01235             mesh3.pose.orientation.w = 1
01236             # mesh3.header.frame_id = frame_id
01237         else:
01238             mesh2 = ArmTarget._make_mesh_marker(mesh_color)
01239             mesh2.mesh_resource = STR_L_GRIPPER_FINGER_FILE
01240             mesh2.pose.position.x = 0.08
01241             mesh2.pose.position.y = -0.116
01242             mesh2.pose.orientation.w = 1
01243             # mesh2.header.frame_id = frame_id
01244 
01245             mesh3 = ArmTarget._make_mesh_marker(mesh_color)
01246             mesh3.mesh_resource = STR_R_GRIPPER_FINGER_FILE
01247             mesh3.pose.position.x = 0.08
01248             mesh3.pose.position.y = 0.116
01249             mesh3.pose.orientation.w = 1
01250             # mesh3.header.frame_id = frame_id
01251 
01252         # Append all meshes we made.
01253         control.markers.append(mesh1)
01254         control.markers.append(mesh2)
01255         control.markers.append(mesh3)
01256 
01257         # Return back the control.
01258         # TODO(mbforbes): Why do we do this?
01259         return control
01260 
01261     def _delete_primitive_cb(self, feedback):
01262         '''Callback for when delete is requested.
01263 
01264         Args:
01265             feedback (InteractiveMarkerFeedback): Unused
01266         '''
01267         self._marker_delete_cb(self._number)
01268 
01269     def _move_to_cb(self, feedback):
01270         '''Callback for when moving to a pose is requested.
01271 
01272         Args:
01273             feedback (InteractiveMarkerFeedback): Unused
01274         '''
01275         self._robot.move_arm_to_pose(self._arm_state)
01276 
01277     def _move_pose_to_cb(self, feedback):
01278         '''Callback for when a pose change to current is requested.
01279 
01280         Args:
01281             feedback (InteractiveMarkerFeedback): Unused
01282 
01283         '''
01284         self._arm_state = self._robot.get_arm_state()
01285         self._gripper_state = self._robot.get_gripper_state()
01286         self.update_ref_frames()
01287         self.update_viz()
01288         self._pose_change_cb()
01289 
01290     def _change_target_cb(self, feedback):
01291         '''Callback for when a reference frame change is requested.
01292 
01293         Args:
01294             feedback (InteractiveMarkerFeedback (?))
01295         '''
01296         self._menu_handler.setCheckState(
01297             self._get_menu_target_id(self._get_menu_ref(target=True)), MenuHandler.UNCHECKED)
01298         self._menu_handler.setCheckState(
01299             feedback.menu_entry_id, MenuHandler.CHECKED)
01300         new_ref = self._get_menu_target_name(feedback.menu_entry_id)
01301         self._set_target(new_ref)
01302         rospy.loginfo(
01303             'Switching reference frame to ' + new_ref + ' for primitive ' +
01304             self.get_name())
01305         self._menu_handler.reApply(self._im_server)
01306         self._im_server.applyChanges()
01307         self.update_viz(False)
01308         self._action_change_cb()
01309 
01310     def _change_ref_cb(self, feedback):
01311         '''Callback for when a reference frame change is requested.
01312 
01313         Args:
01314             feedback (InteractiveMarkerFeedback (?))
01315         '''
01316         self._menu_handler.setCheckState(
01317             self._get_menu_ref_id(self._get_menu_ref()), MenuHandler.UNCHECKED)
01318         self._menu_handler.setCheckState(
01319             feedback.menu_entry_id, MenuHandler.CHECKED)
01320         new_ref = self._get_menu_ref_name(feedback.menu_entry_id)
01321         self._set_ref(new_ref)
01322         rospy.loginfo(
01323             'Switching reference frame to ' + new_ref + ' for primitive ' +
01324             self.get_name())
01325         self._menu_handler.reApply(self._im_server)
01326         self._im_server.applyChanges()
01327         self.update_viz(False)
01328         self._action_change_cb()
01329 
01330     def _marker_feedback_cb(self, feedback):
01331         '''Callback for when an event occurs on the marker.
01332 
01333         Args:
01334             feedback (InteractiveMarkerFeedback)
01335         '''
01336         if feedback.event_type == InteractiveMarkerFeedback.MOUSE_UP:
01337             # Set the visibility of the 6DOF controller.
01338             # This happens a ton, and doesn't need to be logged like
01339             # normal events (e.g. clicking on most marker controls
01340             # fires here).
01341             if self._pose_changed(feedback.pose, feedback.header.frame_id):
01342                 rospy.loginfo('Pose change.')
01343                 self._set_new_pose(feedback.pose, feedback.header.frame_id)
01344                 self._pose_change_cb()
01345                 self._action_change_cb()
01346             else:
01347                 rospy.loginfo('Changing visibility of the pose controls.')
01348                 self._is_control_visible = not self._is_control_visible
01349                 self._marker_click_cb(
01350                     self._number, self._is_control_visible)
01351                 self._set_new_pose(feedback.pose, feedback.header.frame_id)
01352                 self._pose_change_cb()
01353                 self._action_change_cb()
01354         else:
01355             # This happens a ton, and doesn't need to be logged like
01356             # normal events (e.g. clicking on most marker controls
01357             # fires here).
01358             rospy.logdebug('Unknown event: ' + str(feedback.event_type))
01359 
01360     def _get_menu_ref(self, target=False):
01361         '''Returns the name string for the reference frame object of the
01362         primitive. 
01363 
01364         Returns:
01365             str|None: Under all normal circumstances, returns the str
01366                 reference frame name. Returns None in error.
01367         '''
01368         # "Normal" step (saved pose).
01369         ref_type = self._arm_state.ref_type
01370         ref_name = self._arm_state.ref_landmark.name
01371 
01372         if not target:
01373             # Update ref frame name if it's absolute.
01374             if ref_type == ArmState.ROBOT_BASE:
01375                 ref_name = BASE_LINK
01376             elif ref_type == ArmState.PREVIOUS_TARGET:
01377                 ref_name = PREVIOUS_PRIMITIVE
01378             elif ref_name == '':
01379                 ref_name = BASE_LINK
01380                 rospy.loginfo("Empty frame: {}".format(self._number))
01381         else:
01382             ref_name = ref_name + " "
01383 
01384         return ref_name
01385 
01386 
01387 


fetch_pbd_interaction
Author(s): Sarah Elliott
autogenerated on Thu Jun 6 2019 18:27:21