class RobocupInteractiveMarker(object): def __init__(self, server): self.server = server self.pose = Pose() self.publish = True self.int_marker = None self.make_marker() self.menu_handler = MenuHandler() item = self.menu_handler.insert("publish", callback=self.menu_callback) self.menu_handler.setCheckState(item, MenuHandler.CHECKED) self.menu_handler.apply(self.server, self.marker_name) def feedback(self, feedback): self.pose = feedback.pose self.server.applyChanges() def menu_callback(self, feedback): item = feedback.menu_entry_id if self.menu_handler.getCheckState(item) == MenuHandler.CHECKED: self.menu_handler.setCheckState(item, MenuHandler.UNCHECKED) self.publish = False else: self.publish = True self.menu_handler.setCheckState(item, MenuHandler.CHECKED) self.menu_handler.reApply(self.server) self.server.applyChanges() def make_marker(self): self.int_marker = InteractiveMarker() self.int_marker.header.frame_id = "map" self.int_marker.pose = self.pose self.int_marker.scale = 1 self.int_marker.name = self.marker_name control = InteractiveMarkerControl() control.orientation.w = math.sqrt(2) / 2 control.orientation.x = 0 control.orientation.y = math.sqrt(2) / 2 control.orientation.z = 0 control.interaction_mode = self.interaction_mode self.int_marker.controls.append(copy.deepcopy(control)) # make a box which also moves in the plane markers = self.make_individual_markers(self.int_marker) for marker in markers: control.markers.append(marker) control.always_visible = True self.int_marker.controls.append(control) # we want to use our special callback function self.server.insert(self.int_marker, self.feedback)
class GripperMarkers: _offset = 0.09 def __init__(self, side_prefix): self.ik = IK(side_prefix) self.side_prefix = side_prefix self._im_server = InteractiveMarkerServer('ik_request_markers') self._tf_listener = TransformListener() self._menu_handler = MenuHandler() self._menu_handler.insert('Move arm here', callback=self.move_to_pose_cb) self.is_control_visible = False self.ee_pose = self.get_ee_pose() self.update_viz() self._menu_handler.apply(self._im_server, 'ik_target_marker') self._im_server.applyChanges() # Code for moving the robots joints switch_srv_name = 'pr2_controller_manager/switch_controller' rospy.loginfo('Waiting for switch controller service...') rospy.wait_for_service(switch_srv_name) self.switch_service_client = rospy.ServiceProxy( switch_srv_name, SwitchController) self.r_joint_names = [ 'r_shoulder_pan_joint', 'r_shoulder_lift_joint', 'r_upper_arm_roll_joint', 'r_elbow_flex_joint', 'r_forearm_roll_joint', 'r_wrist_flex_joint', 'r_wrist_roll_joint' ] self.l_joint_names = [ 'l_shoulder_pan_joint', 'l_shoulder_lift_joint', 'l_upper_arm_roll_joint', 'l_elbow_flex_joint', 'l_forearm_roll_joint', 'l_wrist_flex_joint', 'l_wrist_roll_joint' ] # Create a trajectory action client r_traj_controller_name = '/r_arm_controller/joint_trajectory_action' self.r_traj_action_client = SimpleActionClient(r_traj_controller_name, JointTrajectoryAction) rospy.loginfo( 'Waiting for a response from the trajectory action server for RIGHT arm...' ) self.r_traj_action_client.wait_for_server() l_traj_controller_name = '/l_arm_controller/joint_trajectory_action' self.l_traj_action_client = SimpleActionClient(l_traj_controller_name, JointTrajectoryAction) rospy.loginfo( 'Waiting for a response from the trajectory action server for LEFT arm...' ) self.l_traj_action_client.wait_for_server() def get_ee_pose(self): from_frame = 'base_link' to_frame = self.side_prefix + '_wrist_roll_link' try: t = self._tf_listener.getLatestCommonTime(from_frame, to_frame) (pos, rot) = self._tf_listener.lookupTransform(from_frame, to_frame, t) except: rospy.logerr('Could not get end effector pose through TF.') pos = [1.0, 0.0, 1.0] rot = [0.0, 0.0, 0.0, 1.0] return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def move_to_pose_cb(self, dummy): rospy.loginfo('You pressed the `Move arm here` button from the menu.') joint_positions = self.ik.get_ik_for_ee(self.ee_pose) print 'joint: ' + str(joint_positions) if (joint_positions != None): self.toggle_arm(self.side_prefix, 'Freeze', False) #joint_positions = [-0.993560463247, -0.357041076593, 0.0534981848008, -1.24934444608, -3.10068096283, -1.7906747183, -28.4704855309] print 'returned from IK: ' + str(joint_positions) #print 'random position : ' + str([-0.993560463247, -0.357041076593, 0.0534981848008, -1.24934444608, -3.10068096283, -1.7906747183, -28.4704855309]) #joint_positions = [-1.03129153, -0.35312086, -0.08, -1.25402906, -2.98718287, -1.7816027, 3.03965124] self.move_to_joints(self.side_prefix, list(joint_positions), 5.0) print 'done' def toggle_arm(self, side, toggle, button): controller_name = side + '_arm_controller' print 'toggle' start_controllers = [] stop_controllers = [] if (toggle == 'Relax'): stop_controllers.append(controller_name) else: start_controllers.append(controller_name) self.set_arm_mode(start_controllers, stop_controllers) def set_arm_mode(self, start_controllers, stop_controllers): try: self.switch_service_client(start_controllers, stop_controllers, 1) except rospy.ServiceException: rospy.logerr('Could not change arm mode.') def move_to_joints(self, side_prefix, positions, time_to_joint): '''Moves the arm to the desired joints''' velocities = [0] * len(positions) traj_goal = JointTrajectoryGoal() traj_goal.trajectory.header.stamp = (rospy.Time.now() + rospy.Duration(0.1)) traj_goal.trajectory.points.append( JointTrajectoryPoint( positions=positions, velocities=velocities, time_from_start=rospy.Duration(time_to_joint))) if (side_prefix == 'r'): traj_goal.trajectory.joint_names = self.r_joint_names self.r_traj_action_client.send_goal(traj_goal) else: traj_goal.trajectory.joint_names = self.l_joint_names self.l_traj_action_client.send_goal(traj_goal) def marker_clicked_cb(self, feedback): if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE: self.ee_pose = feedback.pose self.update_viz() self._menu_handler.reApply(self._im_server) self._im_server.applyChanges() elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK: rospy.loginfo('Changing visibility of the pose controls.') if (self.is_control_visible): self.is_control_visible = False else: self.is_control_visible = True else: rospy.loginfo('Unhandled event: ' + str(feedback.event_type)) def update_viz(self): menu_control = InteractiveMarkerControl() menu_control.interaction_mode = InteractiveMarkerControl.BUTTON menu_control.always_visible = True frame_id = 'base_link' pose = self.ee_pose menu_control = self._add_gripper_marker(menu_control) text_pos = Point() text_pos.x = pose.position.x text_pos.y = pose.position.y text_pos.z = pose.position.z + 0.1 text = 'x=' + str(pose.position.x) + ' y=' + str( pose.position.y) + ' x=' + str(pose.position.z) menu_control.markers.append( Marker(type=Marker.TEXT_VIEW_FACING, id=0, scale=Vector3(0, 0, 0.03), text=text, color=ColorRGBA(0.0, 0.0, 0.0, 0.5), header=Header(frame_id=frame_id), pose=Pose(text_pos, Quaternion(0, 0, 0, 1)))) int_marker = InteractiveMarker() int_marker.name = 'ik_target_marker' int_marker.header.frame_id = frame_id int_marker.pose = pose int_marker.scale = 0.2 self._add_6dof_marker(int_marker) int_marker.controls.append(menu_control) self._im_server.insert(int_marker, self.marker_clicked_cb) def _add_gripper_marker(self, control): is_hand_open = False if is_hand_open: angle = 28 * numpy.pi / 180.0 else: angle = 0 transform1 = tf.transformations.euler_matrix(0, 0, angle) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, 0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices( transform1, transform2) mesh1 = self._make_mesh_marker() mesh1.mesh_resource = ( 'package://pr2_description/meshes/gripper_v0/gripper_palm.dae') mesh1.pose.position.x = -GripperMarkers._offset mesh1.pose.orientation.w = 1 mesh2 = self._make_mesh_marker() mesh2.mesh_resource = ( 'package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh2.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh3 = self._make_mesh_marker() mesh3.mesh_resource = ( 'package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh3.pose = GripperMarkers.get_pose_from_transform(t_distal) quat = tf.transformations.quaternion_multiply( tf.transformations.quaternion_from_euler(numpy.pi, 0, 0), tf.transformations.quaternion_from_euler(0, 0, angle)) transform1 = tf.transformations.quaternion_matrix(quat) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, -0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices( transform1, transform2) mesh4 = self._make_mesh_marker() mesh4.mesh_resource = ( 'package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh4.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh5 = self._make_mesh_marker() mesh5.mesh_resource = ( 'package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh5.pose = GripperMarkers.get_pose_from_transform(t_distal) control.markers.append(mesh1) control.markers.append(mesh2) control.markers.append(mesh3) control.markers.append(mesh4) control.markers.append(mesh5) return control @staticmethod def get_pose_from_transform(transform): pos = transform[:3, 3].copy() rot = tf.transformations.quaternion_from_matrix(transform) return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def _make_mesh_marker(self): mesh = Marker() mesh.mesh_use_embedded_materials = False mesh.type = Marker.MESH_RESOURCE mesh.scale.x = 1.0 mesh.scale.y = 1.0 mesh.scale.z = 1.0 mesh.color = ColorRGBA(0.0, 0.5, 1.0, 0.6) ik_solution = self.ik.get_ik_for_ee(self.ee_pose) if (ik_solution == None): mesh.color = ColorRGBA(1.0, 0.0, 0.0, 0.6) else: mesh.color = ColorRGBA(0.0, 1.0, 0.0, 0.6) return mesh def _add_6dof_marker(self, int_marker): is_fixed = True control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed) int_marker.controls.append(control) def _make_6dof_control(self, name, orientation, is_move, is_fixed): control = InteractiveMarkerControl() control.name = name control.orientation = orientation control.always_visible = False if (self.is_control_visible): if is_move: control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS else: control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS else: control.interaction_mode = InteractiveMarkerControl.NONE if is_fixed: control.orientation_mode = InteractiveMarkerControl.FIXED return control
class ActionStepMarker: ''' Marker for visualizing the steps of an action''' _im_server = None _offset = 0.09 _ref_object_list = None _ref_names = None _marker_click_cb = None def __init__(self, step_number, arm_index, action_step, marker_click_cb): if ActionStepMarker._im_server == None: im_server = InteractiveMarkerServer('programmed_actions') ActionStepMarker._im_server = im_server self.action_step = action_step self.arm_index = arm_index self.step_number = step_number self.is_requested = False self.is_deleted = False self.is_control_visible = False self.is_edited = False self.has_object = False self._sub_entries = None self._menu_handler = None ActionStepMarker._marker_click_cb = marker_click_cb def _is_reachable(self): '''Checks if there is an IK solution for action step''' dummy, is_reachable = Arms.solve_ik_for_arm(self.arm_index, self.get_target()) rospy.loginfo('Reachability of pose in ActionStepMarker : ' + str(is_reachable)) return is_reachable def get_uid(self): '''Returns a unique id of the marker''' return (2 * self.step_number + self.arm_index) def _get_name(self): '''Generates the unique name for the marker''' return ('step' + str(self.step_number) + 'arm' + str(self.arm_index)) def decrease_id(self): '''Reduces the index of the marker''' self.step_number -= 1 self._update_menu() def update_ref_frames(self, ref_frame_list): '''Updates and re-assigns coordinate frames when the world changes''' # There is a new list of objects # If the current frames are already assigned to object, # we need to figure out the correspondences ActionStepMarker._ref_object_list = ref_frame_list arm_pose = self.get_target() if (arm_pose.refFrame == ArmState.OBJECT): prev_ref_obj = arm_pose.refFrameObject new_ref_obj = World.get_most_similar_obj(prev_ref_obj, ref_frame_list) self.has_object = False if (new_ref_obj != None): self.has_object = True arm_pose.refFrameObject = new_ref_obj ActionStepMarker._ref_names = ['base_link'] for i in range(len(ActionStepMarker._ref_object_list)): ActionStepMarker._ref_names.append( ActionStepMarker._ref_object_list[i].name) self._update_menu() def destroy(self): '''Removes marker from the world''' ActionStepMarker._im_server.erase(self._get_name()) ActionStepMarker._im_server.applyChanges() def _update_menu(self): '''Recreates the menu when something has changed''' self._menu_handler = MenuHandler() frame_entry = self._menu_handler.insert('Reference frame') self._sub_entries = [None] * len(ActionStepMarker._ref_names) for i in range(len(ActionStepMarker._ref_names)): self._sub_entries[i] = self._menu_handler.insert( ActionStepMarker._ref_names[i], parent=frame_entry, callback=self.change_ref_cb) self._menu_handler.insert('Move arm here', callback=self.move_to_cb) self._menu_handler.insert('Move to current arm pose', callback=self.move_pose_to_cb) self._menu_handler.insert('Delete', callback=self.delete_step_cb) for i in range(len(ActionStepMarker._ref_names)): self._menu_handler.setCheckState(self._sub_entries[i], MenuHandler.UNCHECKED) menu_id = self._get_menu_id(self._get_ref_name()) if menu_id == None: self.has_object = False else: self._menu_handler.setCheckState(menu_id, MenuHandler.CHECKED) self._update_viz_core() self._menu_handler.apply(ActionStepMarker._im_server, self._get_name()) ActionStepMarker._im_server.applyChanges() def _get_menu_id(self, ref_name): '''Returns the unique menu id from its name None if the object is not found''' if ref_name in ActionStepMarker._ref_names: index = ActionStepMarker._ref_names.index(ref_name) return self._sub_entries[index] else: return None def _get_menu_name(self, menu_id): '''Returns the menu name from its unique menu id''' index = self._sub_entries.index(menu_id) return ActionStepMarker._ref_names[index] def _get_ref_name(self): '''Returns the name string for the reference frame object of the action step''' ref_name = None if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: ref_frame = self.action_step.armTarget.rArm.refFrame ref_name = self.action_step.armTarget.rArm.refFrameObject.name else: ref_frame = self.action_step.armTarget.lArm.refFrame ref_name = self.action_step.armTarget.lArm.refFrameObject.name elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): if self.arm_index == 0: ref_frame = self.action_step.armTrajectory.rRefFrame ref_name = self.action_step.armTrajectory.rRefFrameObject.name else: ref_frame = self.action_step.armTrajectory.lRefFrame ref_name = self.action_step.armTrajectory.lRefFrameObject.name else: rospy.logerr('Unhandled marker type: ' + str(self.action_step.type)) if (ref_frame == ArmState.ROBOT_BASE): ref_name = 'base_link' return ref_name def _set_ref(self, new_ref_name): '''Changes the reference frame of the action step''' new_ref = World.get_ref_from_name(new_ref_name) if (new_ref != ArmState.ROBOT_BASE): index = ActionStepMarker._ref_names.index(new_ref_name) new_ref_obj = ActionStepMarker._ref_object_list[index - 1] else: new_ref_obj = Object() if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: self.action_step.armTarget.rArm = World.convert_ref_frame( self.action_step.armTarget.rArm, new_ref, new_ref_obj) else: self.action_step.armTarget.lArm = World.convert_ref_frame( self.action_step.armTarget.lArm, new_ref, new_ref_obj) elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): for i in range(len(self.action_step.armTrajectory.timing)): if self.arm_index == 0: arm_old = self.action_step.armTrajectory.rArm[i] arm_new = World.convert_ref_frame(arm_old, new_ref, new_ref_obj) self.action_step.armTrajectory.rArm[i] = arm_new else: arm_old = self.action_step.armTrajectory.lArm[i] arm_new = World.convert_ref_frame(arm_old, new_ref, new_ref_obj) self.action_step.armTrajectory.lArm[i] = arm_new if self.arm_index == 0: self.action_step.armTrajectory.rRefFrameObject = new_ref_obj self.action_step.armTrajectory.rRefFrame = new_ref else: self.action_step.armTrajectory.lRefFrameObject = new_ref_obj self.action_step.armTrajectory.lRefFrame = new_ref def _is_hand_open(self): '''Checks if the gripper is open for the action step''' if self.arm_index == 0: gripper_state = self.action_step.gripperAction.rGripper else: gripper_state = self.action_step.gripperAction.lGripper return (gripper_state == GripperState.OPEN) def set_new_pose(self, new_pose): '''Changes the pose of the action step''' if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: pose = ActionStepMarker._offset_pose(new_pose, -1) self.action_step.armTarget.rArm.ee_pose = pose else: pose = ActionStepMarker._offset_pose(new_pose, -1) self.action_step.armTarget.lArm.ee_pose = pose self.update_viz() elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): rospy.logwarn('Modification of whole trajectory ' + 'segments is not implemented.') def get_absolute_position(self, is_start=True): '''Returns the absolute position of the action step''' pose = self.get_absolute_pose(is_start) return pose.position def get_absolute_pose(self, is_start=True): '''Returns the absolute pose of the action step''' if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: arm_pose = self.action_step.armTarget.rArm else: arm_pose = self.action_step.armTarget.lArm elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): if self.arm_index == 0: if is_start: index = len(self.action_step.armTrajectory.rArm) - 1 arm_pose = self.action_step.armTrajectory.rArm[index] else: arm_pose = self.action_step.armTrajectory.rArm[0] else: if is_start: index = len(self.action_step.armTrajectory.lArm) - 1 arm_pose = self.action_step.armTrajectory.lArm[index] else: arm_pose = self.action_step.armTrajectory.lArm[0] #if (arm_pose.refFrame == ArmState.OBJECT and # World.has_object(arm_pose.refFrameObject.name)): # return ActionStepMarker._offset_pose(arm_pose.ee_pose) #else: world_pose = World.get_absolute_pose(arm_pose) return ActionStepMarker._offset_pose(world_pose) def get_pose(self): '''Returns the pose of the action step''' target = self.get_target() if (target != None): return ActionStepMarker._offset_pose(target.ee_pose) @staticmethod def _offset_pose(pose, constant=1): '''Offsets the world pose for visualization''' transform = World.get_matrix_from_pose(pose) offset_array = [constant * ActionStepMarker._offset, 0, 0] offset_transform = tf.transformations.translation_matrix(offset_array) hand_transform = tf.transformations.concatenate_matrices( transform, offset_transform) return World.get_pose_from_transform(hand_transform) def set_target(self, target): '''Sets the new pose for the action step''' if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: self.action_step.armTarget.rArm = target else: self.action_step.armTarget.lArm = target self.has_object = True self._update_menu() self.is_edited = False def get_target(self, traj_index=None): '''Returns the pose for the action step''' if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: return self.action_step.armTarget.rArm else: return self.action_step.armTarget.lArm elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): if self.arm_index == 0: if traj_index == None: traj = self.action_step.armTrajectory.rArm traj_index = int(len(traj) / 2) return self.action_step.armTrajectory.rArm[traj_index] else: if traj_index == None: traj = self.action_step.armTrajectory.lArm traj_index = int(len(traj) / 2) return self.action_step.armTrajectory.lArm[traj_index] def _get_traj_pose(self, index): '''Returns a single pose for trajectory''' if (self.action_step.type == ActionStep.ARM_TRAJECTORY): if self.arm_index == 0: target = self.action_step.armTrajectory.rArm[index] else: target = self.action_step.armTrajectory.lArm[index] return target.ee_pose else: rospy.logerr('Cannot request trajectory pose ' + 'on non-trajectory action step.') def _update_viz_core(self): '''Updates visualization after a change''' menu_control = InteractiveMarkerControl() menu_control.interaction_mode = InteractiveMarkerControl.BUTTON menu_control.always_visible = True frame_id = self._get_ref_name() pose = self.get_pose() if (self.action_step.type == ActionStep.ARM_TARGET): menu_control = self._make_gripper_marker(menu_control, self._is_hand_open()) elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): point_list = [] for j in range(len(self.action_step.armTrajectory.timing)): point_list.append(self._get_traj_pose(j).position) main_marker = Marker(type=Marker.SPHERE_LIST, id=self.get_uid(), lifetime=rospy.Duration(2), scale=Vector3(0.02, 0.02, 0.02), header=Header(frame_id=frame_id), color=ColorRGBA(0.8, 0.4, 0.0, 0.8), points=point_list) menu_control.markers.append(main_marker) menu_control.markers.append( ActionStepMarker.make_sphere_marker(self.get_uid() + 2000, self._get_traj_pose(0), frame_id, 0.05)) last_index = len(self.action_step.armTrajectory.timing) - 1 menu_control.markers.append( ActionStepMarker.make_sphere_marker( self.get_uid() + 3000, self._get_traj_pose(last_index), frame_id, 0.05)) else: rospy.logerr('Non-handled action step type ' + str(self.action_step.type)) ref_frame = World.get_ref_from_name(frame_id) if (ref_frame == ArmState.OBJECT): menu_control.markers.append( Marker(type=Marker.ARROW, id=(1000 + self.get_uid()), lifetime=rospy.Duration(2), scale=Vector3(0.02, 0.03, 0.04), header=Header(frame_id=frame_id), color=ColorRGBA(1.0, 0.8, 0.2, 0.5), points=[pose.position, Point(0, 0, 0)])) text_pos = Point() text_pos.x = pose.position.x text_pos.y = pose.position.y text_pos.z = pose.position.z + 0.1 menu_control.markers.append( Marker(type=Marker.TEXT_VIEW_FACING, id=self.get_uid(), scale=Vector3(0, 0, 0.03), text='Step' + str(self.step_number), color=ColorRGBA(0.0, 0.0, 0.0, 0.5), header=Header(frame_id=frame_id), pose=Pose(text_pos, Quaternion(0, 0, 0, 1)))) int_marker = InteractiveMarker() int_marker.name = self._get_name() int_marker.header.frame_id = frame_id int_marker.pose = pose int_marker.scale = 0.2 self._add_6dof_marker(int_marker, True) int_marker.controls.append(menu_control) ActionStepMarker._im_server.insert(int_marker, self.marker_feedback_cb) @staticmethod def make_sphere_marker(uid, pose, frame_id, radius): '''Creates a sphere marker''' return Marker(type=Marker.SPHERE, id=uid, lifetime=rospy.Duration(2), scale=Vector3(radius, radius, radius), pose=pose, header=Header(frame_id=frame_id), color=ColorRGBA(1.0, 0.5, 0.0, 0.8)) def marker_feedback_cb(self, feedback): '''Callback for when an event occurs on the marker''' if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE: self.set_new_pose(feedback.pose) self.update_viz() elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK: # Set the visibility of the 6DOF controller rospy.loginfo('Changing visibility of the pose controls.') if (self.is_control_visible): self.is_control_visible = False else: self.is_control_visible = True ActionStepMarker._marker_click_cb(self.get_uid(), self.is_control_visible) else: rospy.loginfo('Unknown event' + str(feedback.event_type)) def delete_step_cb(self, dummy): '''Callback for when delete is requested''' self.is_deleted = True def move_to_cb(self, dummy): '''Callback for when moving to a pose is requested''' self.is_requested = True def move_pose_to_cb(self, dummy): '''Callback for when a pose change to current is requested''' self.is_edited = True def pose_reached(self): '''Update when a requested pose is reached''' self.is_requested = False def change_ref_cb(self, feedback): '''Callback for when a reference frame change is requested''' self._menu_handler.setCheckState( self._get_menu_id(self._get_ref_name()), MenuHandler.UNCHECKED) self._menu_handler.setCheckState(feedback.menu_entry_id, MenuHandler.CHECKED) new_ref = self._get_menu_name(feedback.menu_entry_id) self._set_ref(new_ref) rospy.loginfo('Switching reference frame to ' + new_ref + ' for action step ' + self._get_name()) self._menu_handler.reApply(ActionStepMarker._im_server) ActionStepMarker._im_server.applyChanges() self.update_viz() def update_viz(self): '''Updates visualization fully''' self._update_viz_core() self._menu_handler.reApply(ActionStepMarker._im_server) ActionStepMarker._im_server.applyChanges() def _add_6dof_marker(self, int_marker, is_fixed): '''Adds a 6 DoF control marker to the interactive marker''' control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed) int_marker.controls.append(control) def _make_6dof_control(self, name, orientation, is_move, is_fixed): '''Creates one component of the 6dof controller''' control = InteractiveMarkerControl() control.name = name control.orientation = orientation control.always_visible = False if (self.is_control_visible): if is_move: control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS else: control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS else: control.interaction_mode = InteractiveMarkerControl.NONE if is_fixed: control.orientation_mode = InteractiveMarkerControl.FIXED return control def _make_mesh_marker(self): '''Creates a mesh marker''' mesh = Marker() mesh.mesh_use_embedded_materials = False mesh.type = Marker.MESH_RESOURCE mesh.scale.x = 1.0 mesh.scale.y = 1.0 mesh.scale.z = 1.0 if self._is_reachable(): mesh.color = ColorRGBA(1.0, 0.5, 0.0, 0.6) else: mesh.color = ColorRGBA(0.5, 0.5, 0.5, 0.6) return mesh def _make_gripper_marker(self, control, is_hand_open=False): '''Makes a gripper marker''' if is_hand_open: angle = 28 * numpy.pi / 180.0 else: angle = 0 transform1 = tf.transformations.euler_matrix(0, 0, angle) transform1[:3, 3] = [0.07691 - ActionStepMarker._offset, 0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices( transform1, transform2) mesh1 = self._make_mesh_marker() mesh1.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/gripper_palm.dae') mesh1.pose.position.x = -ActionStepMarker._offset mesh1.pose.orientation.w = 1 mesh2 = self._make_mesh_marker() mesh2.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger.dae') mesh2.pose = World.get_pose_from_transform(t_proximal) mesh3 = self._make_mesh_marker() mesh3.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger_tip.dae') mesh3.pose = World.get_pose_from_transform(t_distal) quat = tf.transformations.quaternion_multiply( tf.transformations.quaternion_from_euler(numpy.pi, 0, 0), tf.transformations.quaternion_from_euler(0, 0, angle)) transform1 = tf.transformations.quaternion_matrix(quat) transform1[:3, 3] = [0.07691 - ActionStepMarker._offset, -0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices( transform1, transform2) mesh4 = self._make_mesh_marker() mesh4.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger.dae') mesh4.pose = World.get_pose_from_transform(t_proximal) mesh5 = self._make_mesh_marker() mesh5.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger_tip.dae') mesh5.pose = World.get_pose_from_transform(t_distal) control.markers.append(mesh1) control.markers.append(mesh2) control.markers.append(mesh3) control.markers.append(mesh4) control.markers.append(mesh5) return control
help='Output folder to where the collected data will be stored.', type=str, required=True) ap.add_argument("-c", "--calibration_file", help='full path to calibration file.', type=str, required=True) args = vars(ap.parse_args()) # Initialize ROS stuff rospy.init_node("collect_and_label") # rospack = rospkg.RosPack() # get an instance of RosPack with the default search paths server = InteractiveMarkerServer("data_labeler") robot_description = rospy.get_param('/robot_description') rospy.sleep(0.5) # Process robot description and create an instance of class Sensor for each sensor data_collector = DataCollectorAndLabeler(args['output_folder'], server, menu_handler, args['marker_scale'], args['calibration_file']) createInteractiveMarker(data_collector.world_link) initMenu() menu_handler.reApply(server) server.applyChanges() print('Changes applied ...') rospy.spin()
class GripperMarkers: _offset = 0.09 def __init__(self, side_prefix): self.side_prefix = side_prefix self._im_server = InteractiveMarkerServer('ik_request_markers_' + self.side_prefix) self._tf_listener = TransformListener() self._menu_handler = MenuHandler() self._menu_handler.insert('Move arm here', callback=self.move_to_pose_cb) self.r_joint_names = [ 'r_shoulder_pan_joint', 'r_shoulder_lift_joint', 'r_upper_arm_roll_joint', 'r_elbow_flex_joint', 'r_forearm_roll_joint', 'r_wrist_flex_joint', 'r_wrist_roll_joint' ] self.l_joint_names = [ 'l_shoulder_pan_joint', 'l_shoulder_lift_joint', 'l_upper_arm_roll_joint', 'l_elbow_flex_joint', 'l_forearm_roll_joint', 'l_wrist_flex_joint', 'l_wrist_roll_joint' ] # Create a trajectory action client r_traj_contoller_name = None l_traj_contoller_name = None if self.side_prefix == 'r': r_traj_controller_name = '/r_arm_controller/joint_trajectory_action' self.r_traj_action_client = SimpleActionClient( r_traj_controller_name, JointTrajectoryAction) rospy.loginfo('Waiting for a response from the trajectory ' + 'action server for RIGHT arm...') self.r_traj_action_client.wait_for_server() else: l_traj_controller_name = '/l_arm_controller/joint_trajectory_action' self.l_traj_action_client = SimpleActionClient( l_traj_controller_name, JointTrajectoryAction) rospy.loginfo('Waiting for a response from the trajectory ' + 'action server for LEFT arm...') self.l_traj_action_client.wait_for_server() self.is_control_visible = False self.ee_pose = self.get_ee_pose() self.ik = IK(side_prefix) self.update_viz() self._menu_handler.apply(self._im_server, 'ik_target_marker_' + self.side_prefix) self._im_server.applyChanges() print self.ik def get_ee_pose(self): from_frame = 'base_link' to_frame = self.side_prefix + '_wrist_roll_link' try: if self._tf_listener.frameExists( from_frame) and self._tf_listener.frameExists(to_frame): t = self._tf_listener.getLatestCommonTime(from_frame, to_frame) # t = rospy.Time.now() (pos, rot) = self._tf_listener.lookupTransform( to_frame, from_frame, t) # Note argument order :( else: rospy.logerr( 'TF frames do not exist; could not get end effector pose.') except Exception as err: rospy.logerr('Could not get end effector pose through TF.') rospy.logerr(err) pos = [1.0, 0.0, 1.0] rot = [0.0, 0.0, 0.0, 1.0] return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def move_to_pose_cb(self, feedback): rospy.loginfo('You pressed the `Move arm here` button from the menu.') '''Moves the arm to the desired joints''' print feedback time_to_joint = 2.0 positions = self.ik.get_ik_for_ee(feedback.pose) velocities = [0] * len(positions) traj_goal = JointTrajectoryGoal() traj_goal.trajectory.header.stamp = (rospy.Time.now() + rospy.Duration(0.1)) traj_goal.trajectory.points.append( JointTrajectoryPoint( positions=positions, velocities=velocities, time_from_start=rospy.Duration(time_to_joint))) if (self.side_prefix == 'r'): traj_goal.trajectory.joint_names = self.r_joint_names self.r_traj_action_client.send_goal(traj_goal) else: traj_goal.trajectory.joint_names = self.l_joint_names self.l_traj_action_client.send_goal(traj_goal) pass def marker_clicked_cb(self, feedback): if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE: self.ee_pose = feedback.pose self.update_viz() self._menu_handler.reApply(self._im_server) self._im_server.applyChanges() elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK: rospy.loginfo('Changing visibility of the pose controls.') if (self.is_control_visible): self.is_control_visible = False else: self.is_control_visible = True else: rospy.loginfo('Unhandled event: ' + str(feedback.event_type)) def update_viz(self): menu_control = InteractiveMarkerControl() menu_control.interaction_mode = InteractiveMarkerControl.BUTTON menu_control.always_visible = True frame_id = 'base_link' pose = self.ee_pose menu_control = self._add_gripper_marker(menu_control) text_pos = Point() text_pos.x = pose.position.x text_pos.y = pose.position.y text_pos.z = pose.position.z + 0.1 text = 'x=' + str(pose.position.x) + ' y=' + str( pose.position.y) + ' x=' + str(pose.position.z) menu_control.markers.append( Marker(type=Marker.TEXT_VIEW_FACING, id=0, scale=Vector3(0, 0, 0.03), text=text, color=ColorRGBA(0.0, 0.0, 0.0, 0.5), header=Header(frame_id=frame_id), pose=Pose(text_pos, Quaternion(0, 0, 0, 1)))) int_marker = InteractiveMarker() int_marker.name = 'ik_target_marker_' + self.side_prefix int_marker.header.frame_id = frame_id int_marker.pose = pose int_marker.scale = 0.2 self._add_6dof_marker(int_marker) int_marker.controls.append(menu_control) self._im_server.insert(int_marker, self.marker_clicked_cb) def _add_gripper_marker(self, control): is_hand_open = False if is_hand_open: angle = 28 * numpy.pi / 180.0 else: angle = 0 transform1 = tf.transformations.euler_matrix(0, 0, angle) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, 0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices( transform1, transform2) mesh1 = self._make_mesh_marker() mesh1.mesh_resource = ( 'package://pr2_description/meshes/gripper_v0/gripper_palm.dae') mesh1.pose.position.x = -GripperMarkers._offset mesh1.pose.orientation.w = 1 mesh2 = self._make_mesh_marker() mesh2.mesh_resource = ( 'package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh2.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh3 = self._make_mesh_marker() mesh3.mesh_resource = ( 'package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh3.pose = GripperMarkers.get_pose_from_transform(t_distal) quat = tf.transformations.quaternion_multiply( tf.transformations.quaternion_from_euler(numpy.pi, 0, 0), tf.transformations.quaternion_from_euler(0, 0, angle)) transform1 = tf.transformations.quaternion_matrix(quat) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, -0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices( transform1, transform2) mesh4 = self._make_mesh_marker() mesh4.mesh_resource = ( 'package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh4.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh5 = self._make_mesh_marker() mesh5.mesh_resource = ( 'package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh5.pose = GripperMarkers.get_pose_from_transform(t_distal) control.markers.append(mesh1) control.markers.append(mesh2) control.markers.append(mesh3) control.markers.append(mesh4) control.markers.append(mesh5) return control @staticmethod def get_pose_from_transform(transform): pos = transform[:3, 3].copy() rot = tf.transformations.quaternion_from_matrix(transform) return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def _make_mesh_marker(self): mesh = Marker() mesh.mesh_use_embedded_materials = False mesh.type = Marker.MESH_RESOURCE mesh.scale.x = 1.0 mesh.scale.y = 1.0 mesh.scale.z = 1.0 print self ik_solution = self.ik.get_ik_for_ee(self.ee_pose) if (ik_solution is None): mesh.color = ColorRGBA(1.0, 0.0, 0.0, 0.6) else: mesh.color = ColorRGBA(0.0, 1.0, 0.0, 0.6) return mesh def _add_6dof_marker(self, int_marker): is_fixed = True control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed) int_marker.controls.append(control) def _make_6dof_control(self, name, orientation, is_move, is_fixed): control = InteractiveMarkerControl() control.name = name control.orientation = orientation control.always_visible = False if (self.is_control_visible): if is_move: control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS else: control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS else: control.interaction_mode = InteractiveMarkerControl.NONE if is_fixed: control.orientation_mode = InteractiveMarkerControl.FIXED return control
class ActionStepMarker: ''' Marker for visualizing the steps of an action''' _im_server = None _offset = 0.09 _ref_object_list = None _ref_names = None _marker_click_cb = None def __init__(self, step_number, arm_index, action_step, marker_click_cb): if ActionStepMarker._im_server == None: im_server = InteractiveMarkerServer('programmed_actions') ActionStepMarker._im_server = im_server self.action_step = action_step self.arm_index = arm_index self.step_number = step_number self.is_requested = False self.is_deleted = False self.is_control_visible = False self.is_edited = False self.has_object = False self._sub_entries = None self._menu_handler = None ActionStepMarker._marker_click_cb = marker_click_cb def _is_reachable(self): '''Checks if there is an IK solution for action step''' dummy, is_reachable = Arms.solve_ik_for_arm(self.arm_index, self.get_target()) rospy.loginfo('Reachability of pose in ActionStepMarker : ' + str(is_reachable)) return is_reachable def get_uid(self): '''Returns a unique id of the marker''' return (2 * self.step_number + self.arm_index) def _get_name(self): '''Generates the unique name for the marker''' return ('step' + str(self.step_number) + 'arm' + str(self.arm_index)) def decrease_id(self): '''Reduces the index of the marker''' self.step_number -= 1 self._update_menu() def update_ref_frames(self, ref_frame_list): '''Updates and re-assigns coordinate frames when the world changes''' # There is a new list of objects # If the current frames are already assigned to object, # we need to figure out the correspondences ActionStepMarker._ref_object_list = ref_frame_list arm_pose = self.get_target() if (arm_pose.refFrame == ArmState.OBJECT): prev_ref_obj = arm_pose.refFrameObject new_ref_obj = World.get_most_similar_obj(prev_ref_obj, ref_frame_list) self.has_object = False if (new_ref_obj != None): self.has_object = True arm_pose.refFrameObject = new_ref_obj ActionStepMarker._ref_names = ['base_link'] for i in range(len(ActionStepMarker._ref_object_list)): ActionStepMarker._ref_names.append( ActionStepMarker._ref_object_list[i].name) self._update_menu() def destroy(self): '''Removes marker from the world''' ActionStepMarker._im_server.erase(self._get_name()) ActionStepMarker._im_server.applyChanges() def _update_menu(self): '''Recreates the menu when something has changed''' self._menu_handler = MenuHandler() frame_entry = self._menu_handler.insert('Reference frame') self._sub_entries = [None] * len(ActionStepMarker._ref_names) for i in range(len(ActionStepMarker._ref_names)): self._sub_entries[i] = self._menu_handler.insert( ActionStepMarker._ref_names[i], parent=frame_entry, callback=self.change_ref_cb) self._menu_handler.insert('Move arm here', callback=self.move_to_cb) self._menu_handler.insert('Move to current arm pose', callback=self.move_pose_to_cb) self._menu_handler.insert('Delete', callback=self.delete_step_cb) for i in range(len(ActionStepMarker._ref_names)): self._menu_handler.setCheckState(self._sub_entries[i], MenuHandler.UNCHECKED) menu_id = self._get_menu_id(self._get_ref_name()) if menu_id == None: self.has_object = False else: self._menu_handler.setCheckState(menu_id, MenuHandler.CHECKED) self._update_viz_core() self._menu_handler.apply(ActionStepMarker._im_server, self._get_name()) ActionStepMarker._im_server.applyChanges() def _get_menu_id(self, ref_name): '''Returns the unique menu id from its name None if the object is not found''' if ref_name in ActionStepMarker._ref_names: index = ActionStepMarker._ref_names.index(ref_name) return self._sub_entries[index] else: return None def _get_menu_name(self, menu_id): '''Returns the menu name from its unique menu id''' index = self._sub_entries.index(menu_id) return ActionStepMarker._ref_names[index] def _get_ref_name(self): '''Returns the name string for the reference frame object of the action step''' ref_name = None if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: ref_frame = self.action_step.armTarget.rArm.refFrame ref_name = self.action_step.armTarget.rArm.refFrameObject.name else: ref_frame = self.action_step.armTarget.lArm.refFrame ref_name = self.action_step.armTarget.lArm.refFrameObject.name elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): if self.arm_index == 0: ref_frame = self.action_step.armTrajectory.rRefFrame ref_name = self.action_step.armTrajectory.rRefFrameObject.name else: ref_frame = self.action_step.armTrajectory.lRefFrame ref_name = self.action_step.armTrajectory.lRefFrameObject.name else: rospy.logerr('Unhandled marker type: ' + str(self.action_step.type)) if (ref_frame == ArmState.ROBOT_BASE): ref_name = 'base_link' return ref_name def _set_ref(self, new_ref_name): '''Changes the reference frame of the action step''' new_ref = World.get_ref_from_name(new_ref_name) if (new_ref != ArmState.ROBOT_BASE): index = ActionStepMarker._ref_names.index(new_ref_name) new_ref_obj = ActionStepMarker._ref_object_list[index - 1] else: new_ref_obj = Object() if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: self.action_step.armTarget.rArm = World.convert_ref_frame( self.action_step.armTarget.rArm, new_ref, new_ref_obj) else: self.action_step.armTarget.lArm = World.convert_ref_frame( self.action_step.armTarget.lArm, new_ref, new_ref_obj) elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): for i in range(len(self.action_step.armTrajectory.timing)): if self.arm_index == 0: arm_old = self.action_step.armTrajectory.rArm[i] arm_new = World.convert_ref_frame(arm_old, new_ref, new_ref_obj) self.action_step.armTrajectory.rArm[i] = arm_new else: arm_old = self.action_step.armTrajectory.lArm[i] arm_new = World.convert_ref_frame(arm_old, new_ref, new_ref_obj) self.action_step.armTrajectory.lArm[i] = arm_new if self.arm_index == 0: self.action_step.armTrajectory.rRefFrameObject = new_ref_obj self.action_step.armTrajectory.rRefFrame = new_ref else: self.action_step.armTrajectory.lRefFrameObject = new_ref_obj self.action_step.armTrajectory.lRefFrame = new_ref def _is_hand_open(self): '''Checks if the gripper is open for the action step''' if self.arm_index == 0: gripper_state = self.action_step.gripperAction.rGripper else: gripper_state = self.action_step.gripperAction.lGripper return (gripper_state == GripperState.OPEN) def set_new_pose(self, new_pose): '''Changes the pose of the action step''' if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: pose = ActionStepMarker._offset_pose(new_pose, -1) self.action_step.armTarget.rArm.ee_pose = pose else: pose = ActionStepMarker._offset_pose(new_pose, -1) self.action_step.armTarget.lArm.ee_pose = pose self.update_viz() elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): rospy.logwarn('Modification of whole trajectory ' + 'segments is not implemented.') def get_absolute_position(self, is_start=True): '''Returns the absolute position of the action step''' pose = self.get_absolute_pose(is_start) return pose.position def get_absolute_pose(self, is_start=True): '''Returns the absolute pose of the action step''' if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: arm_pose = self.action_step.armTarget.rArm else: arm_pose = self.action_step.armTarget.lArm elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): if self.arm_index == 0: if is_start: index = len(self.action_step.armTrajectory.rArm) - 1 arm_pose = self.action_step.armTrajectory.rArm[index] else: arm_pose = self.action_step.armTrajectory.rArm[0] else: if is_start: index = len(self.action_step.armTrajectory.lArm) - 1 arm_pose = self.action_step.armTrajectory.lArm[index] else: arm_pose = self.action_step.armTrajectory.lArm[0] #if (arm_pose.refFrame == ArmState.OBJECT and # World.has_object(arm_pose.refFrameObject.name)): # return ActionStepMarker._offset_pose(arm_pose.ee_pose) #else: world_pose = World.get_absolute_pose(arm_pose) return ActionStepMarker._offset_pose(world_pose) def get_pose(self): '''Returns the pose of the action step''' target = self.get_target() if (target != None): return ActionStepMarker._offset_pose(target.ee_pose) @staticmethod def _offset_pose(pose, constant=1): '''Offsets the world pose for visualization''' transform = World.get_matrix_from_pose(pose) offset_array = [constant * ActionStepMarker._offset, 0, 0] offset_transform = tf.transformations.translation_matrix(offset_array) hand_transform = tf.transformations.concatenate_matrices(transform, offset_transform) return World.get_pose_from_transform(hand_transform) def set_target(self, target): '''Sets the new pose for the action step''' if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: self.action_step.armTarget.rArm = target else: self.action_step.armTarget.lArm = target self.has_object = True self._update_menu() self.is_edited = False def get_target(self, traj_index=None): '''Returns the pose for the action step''' if (self.action_step.type == ActionStep.ARM_TARGET): if self.arm_index == 0: return self.action_step.armTarget.rArm else: return self.action_step.armTarget.lArm elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): if self.arm_index == 0: if traj_index == None: traj = self.action_step.armTrajectory.rArm traj_index = int(len(traj) / 2) return self.action_step.armTrajectory.rArm[traj_index] else: if traj_index == None: traj = self.action_step.armTrajectory.lArm traj_index = int(len(traj) / 2) return self.action_step.armTrajectory.lArm[traj_index] def _get_traj_pose(self, index): '''Returns a single pose for trajectory''' if (self.action_step.type == ActionStep.ARM_TRAJECTORY): if self.arm_index == 0: target = self.action_step.armTrajectory.rArm[index] else: target = self.action_step.armTrajectory.lArm[index] return target.ee_pose else: rospy.logerr('Cannot request trajectory pose ' + 'on non-trajectory action step.') def _update_viz_core(self): '''Updates visualization after a change''' menu_control = InteractiveMarkerControl() menu_control.interaction_mode = InteractiveMarkerControl.BUTTON menu_control.always_visible = True frame_id = self._get_ref_name() pose = self.get_pose() if (self.action_step.type == ActionStep.ARM_TARGET): menu_control = self._make_gripper_marker(menu_control, self._is_hand_open()) elif (self.action_step.type == ActionStep.ARM_TRAJECTORY): point_list = [] for j in range(len(self.action_step.armTrajectory.timing)): point_list.append(self._get_traj_pose(j).position) main_marker = Marker(type=Marker.SPHERE_LIST, id=self.get_uid(), lifetime=rospy.Duration(2), scale=Vector3(0.02, 0.02, 0.02), header=Header(frame_id=frame_id), color=ColorRGBA(0.8, 0.4, 0.0, 0.8), points=point_list) menu_control.markers.append(main_marker) menu_control.markers.append(ActionStepMarker.make_sphere_marker( self.get_uid() + 2000, self._get_traj_pose(0), frame_id, 0.05)) last_index = len(self.action_step.armTrajectory.timing) - 1 menu_control.markers.append(ActionStepMarker.make_sphere_marker( self.get_uid() + 3000, self._get_traj_pose(last_index), frame_id, 0.05)) else: rospy.logerr('Non-handled action step type ' + str(self.action_step.type)) ref_frame = World.get_ref_from_name(frame_id) if (ref_frame == ArmState.OBJECT): menu_control.markers.append(Marker(type=Marker.ARROW, id=(1000 + self.get_uid()), lifetime=rospy.Duration(2), scale=Vector3(0.02, 0.03, 0.04), header=Header(frame_id=frame_id), color=ColorRGBA(1.0, 0.8, 0.2, 0.5), points=[pose.position, Point(0, 0, 0)])) text_pos = Point() text_pos.x = pose.position.x text_pos.y = pose.position.y text_pos.z = pose.position.z + 0.1 menu_control.markers.append(Marker(type=Marker.TEXT_VIEW_FACING, id=self.get_uid(), scale=Vector3(0, 0, 0.03), text='Step' + str(self.step_number), color=ColorRGBA(0.0, 0.0, 0.0, 0.5), header=Header(frame_id=frame_id), pose=Pose(text_pos, Quaternion(0, 0, 0, 1)))) int_marker = InteractiveMarker() int_marker.name = self._get_name() int_marker.header.frame_id = frame_id int_marker.pose = pose int_marker.scale = 0.2 self._add_6dof_marker(int_marker, True) int_marker.controls.append(menu_control) ActionStepMarker._im_server.insert(int_marker, self.marker_feedback_cb) @staticmethod def make_sphere_marker(uid, pose, frame_id, radius): '''Creates a sphere marker''' return Marker(type=Marker.SPHERE, id=uid, lifetime=rospy.Duration(2), scale=Vector3(radius, radius, radius), pose=pose, header=Header(frame_id=frame_id), color=ColorRGBA(1.0, 0.5, 0.0, 0.8)) def marker_feedback_cb(self, feedback): '''Callback for when an event occurs on the marker''' if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE: self.set_new_pose(feedback.pose) self.update_viz() elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK: # Set the visibility of the 6DOF controller rospy.loginfo('Changing visibility of the pose controls.') if (self.is_control_visible): self.is_control_visible = False else: self.is_control_visible = True ActionStepMarker._marker_click_cb(self.get_uid(), self.is_control_visible) else: rospy.loginfo('Unknown event' + str(feedback.event_type)) def delete_step_cb(self, dummy): '''Callback for when delete is requested''' self.is_deleted = True def move_to_cb(self, dummy): '''Callback for when moving to a pose is requested''' self.is_requested = True def move_pose_to_cb(self, dummy): '''Callback for when a pose change to current is requested''' self.is_edited = True def pose_reached(self): '''Update when a requested pose is reached''' self.is_requested = False def change_ref_cb(self, feedback): '''Callback for when a reference frame change is requested''' self._menu_handler.setCheckState( self._get_menu_id(self._get_ref_name()), MenuHandler.UNCHECKED) self._menu_handler.setCheckState(feedback.menu_entry_id, MenuHandler.CHECKED) new_ref = self._get_menu_name(feedback.menu_entry_id) self._set_ref(new_ref) rospy.loginfo('Switching reference frame to ' + new_ref + ' for action step ' + self._get_name()) self._menu_handler.reApply(ActionStepMarker._im_server) ActionStepMarker._im_server.applyChanges() self.update_viz() def update_viz(self): '''Updates visualization fully''' self._update_viz_core() self._menu_handler.reApply(ActionStepMarker._im_server) ActionStepMarker._im_server.applyChanges() def _add_6dof_marker(self, int_marker, is_fixed): '''Adds a 6 DoF control marker to the interactive marker''' control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed) int_marker.controls.append(control) def _make_6dof_control(self, name, orientation, is_move, is_fixed): '''Creates one component of the 6dof controller''' control = InteractiveMarkerControl() control.name = name control.orientation = orientation control.always_visible = False if (self.is_control_visible): if is_move: control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS else: control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS else: control.interaction_mode = InteractiveMarkerControl.NONE if is_fixed: control.orientation_mode = InteractiveMarkerControl.FIXED return control def _make_mesh_marker(self): '''Creates a mesh marker''' mesh = Marker() mesh.mesh_use_embedded_materials = False mesh.type = Marker.MESH_RESOURCE mesh.scale.x = 1.0 mesh.scale.y = 1.0 mesh.scale.z = 1.0 if self._is_reachable(): mesh.color = ColorRGBA(1.0, 0.5, 0.0, 0.6) else: mesh.color = ColorRGBA(0.5, 0.5, 0.5, 0.6) return mesh def _make_gripper_marker(self, control, is_hand_open=False): '''Makes a gripper marker''' if is_hand_open: angle = 28 * numpy.pi / 180.0 else: angle = 0 transform1 = tf.transformations.euler_matrix(0, 0, angle) transform1[:3, 3] = [0.07691 - ActionStepMarker._offset, 0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1, transform2) mesh1 = self._make_mesh_marker() mesh1.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/gripper_palm.dae') mesh1.pose.position.x = -ActionStepMarker._offset mesh1.pose.orientation.w = 1 mesh2 = self._make_mesh_marker() mesh2.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger.dae') mesh2.pose = World.get_pose_from_transform(t_proximal) mesh3 = self._make_mesh_marker() mesh3.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger_tip.dae') mesh3.pose = World.get_pose_from_transform(t_distal) quat = tf.transformations.quaternion_multiply( tf.transformations.quaternion_from_euler(numpy.pi, 0, 0), tf.transformations.quaternion_from_euler(0, 0, angle)) transform1 = tf.transformations.quaternion_matrix(quat) transform1[:3, 3] = [0.07691 - ActionStepMarker._offset, -0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1, transform2) mesh4 = self._make_mesh_marker() mesh4.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger.dae') mesh4.pose = World.get_pose_from_transform(t_proximal) mesh5 = self._make_mesh_marker() mesh5.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger_tip.dae') mesh5.pose = World.get_pose_from_transform(t_distal) control.markers.append(mesh1) control.markers.append(mesh2) control.markers.append(mesh3) control.markers.append(mesh4) control.markers.append(mesh5) return control
class GripperMarkers: _offset = 0.09 def __init__(self, side_prefix): self.ik = IK(side_prefix) self.side_prefix = side_prefix self._im_server = InteractiveMarkerServer('ik_request_markers') self._tf_listener = TransformListener() self._menu_handler = MenuHandler() self._menu_handler.insert('Move arm here', callback=self.move_to_pose_cb) self.is_control_visible = False self.ee_pose = self.get_ee_pose() self.update_viz() self._menu_handler.apply(self._im_server, 'ik_target_marker') self._im_server.applyChanges() def get_ee_pose(self): from_frame = '/base_link' to_frame = '/' + self.side_prefix + '_wrist_roll_link' try: t = self._tf_listener.getLatestCommonTime(from_frame, to_frame) (pos, rot) = self._tf_listener.lookupTransform(from_frame, to_frame, t) except: rospy.logwarn('Could not get end effector pose through TF.') pos = [1.0, 0.0, 1.0] rot = [0.0, 0.0, 0.0, 1.0] return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def move_to_pose_cb(self, dummy): rospy.loginfo('You pressed the `Move arm here` button from the menu.') target_pose = GripperMarkers._offset_pose(self.ee_pose) ik_solution = self.ik.get_ik_for_ee(target_pose) #TODO: Send the arms to ik_solution def marker_clicked_cb(self, feedback): if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE: self.ee_pose = feedback.pose self.update_viz() self._menu_handler.reApply(self._im_server) self._im_server.applyChanges() elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK: rospy.loginfo('Changing visibility of the pose controls.') if (self.is_control_visible): self.is_control_visible = False else: self.is_control_visible = True else: rospy.loginfo('Unhandled event: ' + str(feedback.event_type)) def update_viz(self): menu_control = InteractiveMarkerControl() menu_control.interaction_mode = InteractiveMarkerControl.BUTTON menu_control.always_visible = True frame_id = 'base_link' pose = self.ee_pose menu_control = self._add_gripper_marker(menu_control) text_pos = Point() text_pos.x = pose.position.x text_pos.y = pose.position.y text_pos.z = pose.position.z + 0.1 text = 'x=' + str(pose.position.x) + ' y=' + str(pose.position.y) + ' x=' + str(pose.position.z) menu_control.markers.append(Marker(type=Marker.TEXT_VIEW_FACING, id=0, scale=Vector3(0, 0, 0.03), text=text, color=ColorRGBA(0.0, 0.0, 0.0, 0.5), header=Header(frame_id=frame_id), pose=Pose(text_pos, Quaternion(0, 0, 0, 1)))) int_marker = InteractiveMarker() int_marker.name = 'ik_target_marker' int_marker.header.frame_id = frame_id int_marker.pose = pose int_marker.scale = 0.2 self._add_6dof_marker(int_marker) int_marker.controls.append(menu_control) self._im_server.insert(int_marker, self.marker_clicked_cb) def _add_gripper_marker(self, control): is_hand_open=False if is_hand_open: angle = 28 * numpy.pi / 180.0 else: angle = 0 transform1 = tf.transformations.euler_matrix(0, 0, angle) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, 0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1, transform2) mesh1 = self._make_mesh_marker() mesh1.mesh_resource = ('package://pr2_description/meshes/gripper_v0/gripper_palm.dae') mesh1.pose.position.x = -GripperMarkers._offset mesh1.pose.orientation.w = 1 mesh2 = self._make_mesh_marker() mesh2.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh2.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh3 = self._make_mesh_marker() mesh3.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh3.pose = GripperMarkers.get_pose_from_transform(t_distal) quat = tf.transformations.quaternion_multiply( tf.transformations.quaternion_from_euler(numpy.pi, 0, 0), tf.transformations.quaternion_from_euler(0, 0, angle)) transform1 = tf.transformations.quaternion_matrix(quat) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, -0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1,transform2) mesh4 = self._make_mesh_marker() mesh4.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh4.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh5 = self._make_mesh_marker() mesh5.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh5.pose = GripperMarkers.get_pose_from_transform(t_distal) control.markers.append(mesh1) control.markers.append(mesh2) control.markers.append(mesh3) control.markers.append(mesh4) control.markers.append(mesh5) return control @staticmethod def get_pose_from_transform(transform): pos = transform[:3,3].copy() rot = tf.transformations.quaternion_from_matrix(transform) return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) @staticmethod def _offset_pose(pose): transform = GripperMarkers.get_matrix_from_pose(pose) offset_array = [GripperMarkers._offset, 0, 0] offset_transform = tf.transformations.translation_matrix(offset_array) hand_transform = tf.transformations.concatenate_matrices(transform, offset_transform) return GripperMarkers.get_pose_from_transform(hand_transform) @staticmethod def get_matrix_from_pose(pose): rotation = [pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w] transformation = tf.transformations.quaternion_matrix(rotation) position = [pose.position.x, pose.position.y, pose.position.z] transformation[:3, 3] = position return transformation def _make_mesh_marker(self): mesh = Marker() mesh.mesh_use_embedded_materials = False mesh.type = Marker.MESH_RESOURCE mesh.scale.x = 1.0 mesh.scale.y = 1.0 mesh.scale.z = 1.0 target_pose = GripperMarkers._offset_pose(self.ee_pose) ik_solution = self.ik.get_ik_for_ee(target_pose) if (ik_solution == None): mesh.color = ColorRGBA(1.0, 0.0, 0.0, 0.6) else: mesh.color = ColorRGBA(0.0, 1.0, 0.0, 0.6) mesh.color = ColorRGBA(0.0, 0.5, 1.0, 0.6) return mesh def _add_6dof_marker(self, int_marker): is_fixed = True control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed) int_marker.controls.append(control) def _make_6dof_control(self, name, orientation, is_move, is_fixed): control = InteractiveMarkerControl() control.name = name control.orientation = orientation control.always_visible = False if (self.is_control_visible): if is_move: control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS else: control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS else: control.interaction_mode = InteractiveMarkerControl.NONE if is_fixed: control.orientation_mode = InteractiveMarkerControl.FIXED return control
class GripperMarkers: _offset = -0.09 _tf_listener = None def __init__(self, side_prefix): if GripperMarkers._tf_listener is None: GripperMarkers._tf_listener = TransformListener() self.ik = IK(side_prefix) self.side_prefix = side_prefix self._im_server = InteractiveMarkerServer(side_prefix + '_ik_request_markers') self._menu_handler = MenuHandler() self._menu_handler.insert('Move arm here', callback=self.move_to_pose_cb) self.is_control_visible = False self.marker_pose = self._offset_pose(self.get_ee_pose(), -GripperMarkers._offset) self.update_viz() self._menu_handler.apply(self._im_server, 'ik_target_marker') self._im_server.applyChanges() def get_ee_pose(self): from_frame = '/base_link' to_frame = '/' + self.side_prefix + '_wrist_roll_link' try: GripperMarkers._tf_listener.waitForTransform(from_frame, to_frame, rospy.Time(0), rospy.Duration(5)) t = GripperMarkers._tf_listener.getLatestCommonTime(from_frame, to_frame) (pos, rot) = GripperMarkers._tf_listener.lookupTransform(from_frame, to_frame, t) except: rospy.logwarn('Could not get end effector pose through TF.') pos = [1.0, 0.0, 1.0] rot = [0.0, 0.0, 0.0, 1.0] return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def move_to_pose_cb(self, dummy): rospy.loginfo('You pressed the `Move arm here` button from the menu.') target_pose = GripperMarkers._offset_pose(self.marker_pose, GripperMarkers._offset) ik_solution = self.ik.get_ik_for_ee(target_pose) if (ik_solution == None): rospy.logwarn('No IK solutions for this pose, cannot move.') else: self.ik.move_to_joints(ik_solution, 2.0) pass def marker_clicked_cb(self, feedback): if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE: self.marker_pose = feedback.pose self.update_viz() self._menu_handler.reApply(self._im_server) self._im_server.applyChanges() elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK: rospy.loginfo('Changing visibility of the pose controls.') if (self.is_control_visible): self.is_control_visible = False else: self.is_control_visible = True else: rospy.loginfo('Unhandled event: ' + str(feedback.event_type)) def update_viz(self): menu_control = InteractiveMarkerControl() menu_control.interaction_mode = InteractiveMarkerControl.BUTTON menu_control.always_visible = True frame_id = 'base_link' pose = self.marker_pose menu_control = self._add_gripper_marker(menu_control) text_pos = Point() text_pos.x = pose.position.x text_pos.y = pose.position.y text_pos.z = pose.position.z + 0.1 #text = 'x=' + str(pose.position.x) + ' y=' + str(pose.position.y) + ' x=' + str(pose.position.z) text = self.side_prefix + '_arm' menu_control.markers.append(Marker(type=Marker.TEXT_VIEW_FACING, id=0, scale=Vector3(0, 0, 0.05), text=text, color=ColorRGBA(0.0, 0.0, 0.0, 0.5), header=Header(frame_id=frame_id), pose=Pose(text_pos, Quaternion(0, 0, 0, 1)))) int_marker = InteractiveMarker() int_marker.name = 'ik_target_marker' int_marker.header.frame_id = frame_id int_marker.pose = pose int_marker.scale = 0.2 self._add_6dof_marker(int_marker) int_marker.controls.append(menu_control) self._im_server.insert(int_marker, self.marker_clicked_cb) def _add_gripper_marker(self, control): is_hand_open=False if is_hand_open: angle = 28 * numpy.pi / 180.0 else: angle = 0 offset = -GripperMarkers._offset transform1 = tf.transformations.euler_matrix(0, 0, angle) transform1[:3, 3] = [0.07691 - offset, 0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1, transform2) mesh1 = self._make_mesh_marker() mesh1.mesh_resource = ('package://pr2_description/meshes/gripper_v0/gripper_palm.dae') mesh1.pose.position.x = -offset mesh1.pose.orientation.w = 1 mesh2 = self._make_mesh_marker() mesh2.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh2.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh3 = self._make_mesh_marker() mesh3.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh3.pose = GripperMarkers.get_pose_from_transform(t_distal) quat = tf.transformations.quaternion_multiply( tf.transformations.quaternion_from_euler(numpy.pi, 0, 0), tf.transformations.quaternion_from_euler(0, 0, angle)) transform1 = tf.transformations.quaternion_matrix(quat) transform1[:3, 3] = [0.07691 - offset, -0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1,transform2) mesh4 = self._make_mesh_marker() mesh4.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh4.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh5 = self._make_mesh_marker() mesh5.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh5.pose = GripperMarkers.get_pose_from_transform(t_distal) control.markers.append(mesh1) control.markers.append(mesh2) control.markers.append(mesh3) control.markers.append(mesh4) control.markers.append(mesh5) return control @staticmethod def get_pose_from_transform(transform): pos = transform[:3,3].copy() rot = tf.transformations.quaternion_from_matrix(transform) return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) @staticmethod def _offset_pose(pose, x_offset): transform = GripperMarkers.get_matrix_from_pose(pose) offset_array = [x_offset, 0, 0] offset_transform = tf.transformations.translation_matrix(offset_array) hand_transform = tf.transformations.concatenate_matrices(transform, offset_transform) return GripperMarkers.get_pose_from_transform(hand_transform) @staticmethod def get_matrix_from_pose(pose): rotation = [pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w] transformation = tf.transformations.quaternion_matrix(rotation) position = [pose.position.x, pose.position.y, pose.position.z] transformation[:3, 3] = position return transformation def _make_mesh_marker(self): mesh = Marker() mesh.mesh_use_embedded_materials = False mesh.type = Marker.MESH_RESOURCE mesh.scale.x = 1.0 mesh.scale.y = 1.0 mesh.scale.z = 1.0 target_pose = GripperMarkers._offset_pose(self.marker_pose, GripperMarkers._offset) ik_solution = self.ik.get_ik_for_ee(target_pose) if (ik_solution == None): mesh.color = ColorRGBA(1.0, 0.0, 0.0, 0.6) else: mesh.color = ColorRGBA(0.0, 1.0, 0.0, 0.6) return mesh def _add_6dof_marker(self, int_marker): is_fixed = True control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed) int_marker.controls.append(control) def _make_6dof_control(self, name, orientation, is_move, is_fixed): control = InteractiveMarkerControl() control.name = name control.orientation = orientation control.always_visible = False if (self.is_control_visible): if is_move: control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS else: control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS else: control.interaction_mode = InteractiveMarkerControl.NONE if is_fixed: control.orientation_mode = InteractiveMarkerControl.FIXED return control
class GripperMarkers: _offset = 0.09 def __init__(self, side_prefix): self._ik_service = IK(side_prefix) r_traj_controller_name = '/r_arm_controller/joint_trajectory_action' self.r_traj_action_client = SimpleActionClient(r_traj_controller_name, JointTrajectoryAction) rospy.loginfo('Waiting for a response from the trajectory action server for RIGHT arm...') self.r_traj_action_client.wait_for_server() l_traj_controller_name = '/l_arm_controller/joint_trajectory_action' self.l_traj_action_client = SimpleActionClient(l_traj_controller_name, JointTrajectoryAction) rospy.loginfo('Waiting for a response from the trajectory action server for LEFT arm...') self.l_traj_action_client.wait_for_server() self.r_joint_names = ['r_shoulder_pan_joint', 'r_shoulder_lift_joint', 'r_upper_arm_roll_joint', 'r_elbow_flex_joint', 'r_forearm_roll_joint', 'r_wrist_flex_joint', 'r_wrist_roll_joint'] self.l_joint_names = ['l_shoulder_pan_joint', 'l_shoulder_lift_joint', 'l_upper_arm_roll_joint', 'l_elbow_flex_joint', 'l_forearm_roll_joint', 'l_wrist_flex_joint', 'l_wrist_roll_joint'] rospy.Subscriber('ar_pose_marker', AlvarMarkers, self.marker_cb) self.side_prefix = side_prefix self._im_server = InteractiveMarkerServer("ik_request_markers_{}".format(side_prefix)) self._tf_listener = TransformListener() self._menu_handler = MenuHandler() self._menu_handler.insert("Move {} arm here".format(side_prefix), callback=self.move_to_pose_cb) self.is_control_visible = False self.ee_pose = self.get_ee_pose() self.update_viz() self._menu_handler.apply(self._im_server, 'ik_target_marker') self._im_server.applyChanges() def get_ee_pose(self): from_frame = '/base_link' to_frame = '/' + self.side_prefix + '_wrist_roll_link' try: t = self._tf_listener.getLatestCommonTime(from_frame, to_frame) (pos, rot) = self._tf_listener.lookupTransform(from_frame, to_frame, t) except Exception as e: rospy.logerr('Could not get end effector pose through TF.') pos = [1.0, 0.0, 1.0] rot = [0.0, 0.0, 0.0, 1.0] import traceback traceback.print_exc() return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def move_to_pose_cb(self, dummy): target_pose = GripperMarkers._offset_pose(self.ee_pose) ik_sol = self._ik_service.get_ik_for_ee(target_pose) self.move_to_joints(self.side_prefix, [ik_sol], 1.0) def marker_clicked_cb(self, feedback): if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE: self.ee_pose = feedback.pose self.update_viz() self._menu_handler.reApply(self._im_server) self._im_server.applyChanges() elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK: rospy.loginfo('Changing visibility of the pose controls.') if (self.is_control_visible): self.is_control_visible = False else: self.is_control_visible = True else: rospy.loginfo('Unhandled event: ' + str(feedback.event_type)) def marker_cb(self, pose_markers): rospy.loginfo('AR Marker Pose updating') transform = GripperMarkers.get_matrix_from_pose(pose_markers.markers[0].pose.pose) offset_array = [0, 0, .03] offset_transform = tf.transformations.translation_matrix(offset_array) hand_transform = tf.transformations.concatenate_matrices(transform, offset_transform) self.ee_pose = GripperMarkers.get_pose_from_transform(hand_transform) self.update_viz() def update_viz(self): menu_control = InteractiveMarkerControl() menu_control.interaction_mode = InteractiveMarkerControl.BUTTON menu_control.always_visible = True frame_id = 'base_link' pose = self.ee_pose menu_control = self._add_gripper_marker(menu_control) text_pos = Point() text_pos.x = pose.position.x text_pos.y = pose.position.y text_pos.z = pose.position.z + 0.1 text = "x=%.3f y=%.3f z=%.3f" % (pose.position.x, pose.position.y, pose.position.z) menu_control.markers.append(Marker(type=Marker.TEXT_VIEW_FACING, id=0, scale=Vector3(0, 0, 0.03), text=text, color=ColorRGBA(0.0, 0.0, 0.0, 0.5), header=Header(frame_id=frame_id), pose=Pose(text_pos, Quaternion(0, 0, 0, 1)))) label_pos = Point() label_pos.x = pose.position.x label_pos.y = pose.position.y label_pos.z = pose.position.z label = "{} arm".format(self.side_prefix) menu_control.markers.append(Marker(type=Marker.TEXT_VIEW_FACING, id=0, scale=Vector3(0, 0, 0.03), text=label, color=ColorRGBA(0.0, 0.0, 0.0, 0.9), header=Header(frame_id=frame_id), pose=Pose(label_pos, Quaternion(0, 0, 0, 1)))) int_marker = InteractiveMarker() int_marker.name = 'ik_target_marker' int_marker.header.frame_id = frame_id int_marker.pose = pose int_marker.scale = 0.2 self._add_6dof_marker(int_marker) int_marker.controls.append(menu_control) self._im_server.insert(int_marker, self.marker_clicked_cb) def _add_gripper_marker(self, control): is_hand_open=False if is_hand_open: angle = 28 * numpy.pi / 180.0 else: angle = 0 transform1 = tf.transformations.euler_matrix(0, 0, angle) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, 0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1, transform2) mesh1 = self._make_mesh_marker() mesh1.mesh_resource = ('package://pr2_description/meshes/gripper_v0/gripper_palm.dae') mesh1.pose.position.x = -GripperMarkers._offset mesh1.pose.orientation.w = 1 mesh2 = self._make_mesh_marker() mesh2.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh2.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh3 = self._make_mesh_marker() mesh3.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh3.pose = GripperMarkers.get_pose_from_transform(t_distal) quat = tf.transformations.quaternion_multiply( tf.transformations.quaternion_from_euler(numpy.pi, 0, 0), tf.transformations.quaternion_from_euler(0, 0, angle)) transform1 = tf.transformations.quaternion_matrix(quat) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, -0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1,transform2) mesh4 = self._make_mesh_marker() mesh4.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh4.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh5 = self._make_mesh_marker() mesh5.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh5.pose = GripperMarkers.get_pose_from_transform(t_distal) control.markers.append(mesh1) control.markers.append(mesh2) control.markers.append(mesh3) control.markers.append(mesh4) control.markers.append(mesh5) return control @staticmethod def _offset_pose(pose): transform = GripperMarkers.get_matrix_from_pose(pose) offset_array = [-GripperMarkers._offset, 0, 0] offset_transform = tf.transformations.translation_matrix(offset_array) hand_transform = tf.transformations.concatenate_matrices(transform, offset_transform) return GripperMarkers.get_pose_from_transform(hand_transform) @staticmethod def get_matrix_from_pose(pose): rotation = [pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w] transformation = tf.transformations.quaternion_matrix(rotation) position = [pose.position.x, pose.position.y, pose.position.z] transformation[:3, 3] = position return transformation @staticmethod def get_pose_from_transform(transform): pos = transform[:3,3].copy() rot = tf.transformations.quaternion_from_matrix(transform) return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def _make_mesh_marker(self): mesh = Marker() mesh.mesh_use_embedded_materials = False mesh.type = Marker.MESH_RESOURCE mesh.scale.x = 1.0 mesh.scale.y = 1.0 mesh.scale.z = 1.0 target_pose = GripperMarkers._offset_pose(self.ee_pose) ik_sol = self._ik_service.get_ik_for_ee(target_pose) if ik_sol == None: mesh.color = ColorRGBA(1.0, 0.0, 0.0, 0.6) else: mesh.color = ColorRGBA(0.0, 1.0, 0.0, 0.6) return mesh def _add_6dof_marker(self, int_marker): is_fixed = True control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed) int_marker.controls.append(control) def _make_6dof_control(self, name, orientation, is_move, is_fixed): control = InteractiveMarkerControl() control.name = name control.orientation = orientation control.always_visible = False if (self.is_control_visible): if is_move: control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS else: control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS else: control.interaction_mode = InteractiveMarkerControl.NONE if is_fixed: control.orientation_mode = InteractiveMarkerControl.FIXED return control def move_to_joints(self, side_prefix, positions, time_to_joint): '''Moves the arm to the desired joints''' traj_goal = JointTrajectoryGoal() traj_goal.trajectory.header.stamp = (rospy.Time.now() + rospy.Duration(0.1)) time_move = time_to_joint print "using following positions %s" % positions for pose in positions: velocities = [0] * len(pose) traj_goal.trajectory.points.append(JointTrajectoryPoint(positions=pose, velocities=velocities, time_from_start=rospy.Duration(time_move))) time_move += time_to_joint if (side_prefix == 'r'): traj_goal.trajectory.joint_names = self.r_joint_names self.r_traj_action_client.send_goal(traj_goal) else: traj_goal.trajectory.joint_names = self.l_joint_names self.l_traj_action_client.send_goal(traj_goal)
class GripperMarkers: _offset = 0.09 def __init__(self, side_prefix): self.ik = IK(side_prefix) self.side_prefix = side_prefix self._im_server = InteractiveMarkerServer('ik_request_markers') self._tf_listener = TransformListener() self._menu_handler = MenuHandler() self._menu_handler.insert('Move arm here', callback=self.move_to_pose_cb) self.is_control_visible = False self.ee_pose = self.get_ee_pose() self.update_viz() self._menu_handler.apply(self._im_server, 'ik_target_marker') self._im_server.applyChanges() # Code for moving the robots joints switch_srv_name = 'pr2_controller_manager/switch_controller' rospy.loginfo('Waiting for switch controller service...') rospy.wait_for_service(switch_srv_name) self.switch_service_client = rospy.ServiceProxy(switch_srv_name, SwitchController) self.r_joint_names = ['r_shoulder_pan_joint', 'r_shoulder_lift_joint', 'r_upper_arm_roll_joint', 'r_elbow_flex_joint', 'r_forearm_roll_joint', 'r_wrist_flex_joint', 'r_wrist_roll_joint'] self.l_joint_names = ['l_shoulder_pan_joint', 'l_shoulder_lift_joint', 'l_upper_arm_roll_joint', 'l_elbow_flex_joint', 'l_forearm_roll_joint', 'l_wrist_flex_joint', 'l_wrist_roll_joint'] # Create a trajectory action client r_traj_controller_name = '/r_arm_controller/joint_trajectory_action' self.r_traj_action_client = SimpleActionClient(r_traj_controller_name, JointTrajectoryAction) rospy.loginfo('Waiting for a response from the trajectory action server for RIGHT arm...') self.r_traj_action_client.wait_for_server() l_traj_controller_name = '/l_arm_controller/joint_trajectory_action' self.l_traj_action_client = SimpleActionClient(l_traj_controller_name, JointTrajectoryAction) rospy.loginfo('Waiting for a response from the trajectory action server for LEFT arm...') self.l_traj_action_client.wait_for_server() def get_ee_pose(self): from_frame = 'base_link' to_frame = self.side_prefix + '_wrist_roll_link' try: t = self._tf_listener.getLatestCommonTime(from_frame, to_frame) (pos, rot) = self._tf_listener.lookupTransform(from_frame, to_frame, t) except: rospy.logerr('Could not get end effector pose through TF.') pos = [1.0, 0.0, 1.0] rot = [0.0, 0.0, 0.0, 1.0] return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def move_to_pose_cb(self, dummy): rospy.loginfo('You pressed the `Move arm here` button from the menu.') joint_positions = self.ik.get_ik_for_ee(self.ee_pose) print 'joint: ' + str(joint_positions) if(joint_positions != None): self.toggle_arm(self.side_prefix, 'Freeze', False) #joint_positions = [-0.993560463247, -0.357041076593, 0.0534981848008, -1.24934444608, -3.10068096283, -1.7906747183, -28.4704855309] print 'returned from IK: ' + str(joint_positions) #print 'random position : ' + str([-0.993560463247, -0.357041076593, 0.0534981848008, -1.24934444608, -3.10068096283, -1.7906747183, -28.4704855309]) #joint_positions = [-1.03129153, -0.35312086, -0.08, -1.25402906, -2.98718287, -1.7816027, 3.03965124] self.move_to_joints(self.side_prefix, list(joint_positions), 5.0) print 'done' def toggle_arm(self, side, toggle, button): controller_name = side + '_arm_controller' print 'toggle' start_controllers = [] stop_controllers = [] if (toggle == 'Relax'): stop_controllers.append(controller_name) else: start_controllers.append(controller_name) self.set_arm_mode(start_controllers, stop_controllers) def set_arm_mode(self, start_controllers, stop_controllers): try: self.switch_service_client(start_controllers, stop_controllers, 1) except rospy.ServiceException: rospy.logerr('Could not change arm mode.') def move_to_joints(self, side_prefix, positions, time_to_joint): '''Moves the arm to the desired joints''' velocities = [0] * len(positions) traj_goal = JointTrajectoryGoal() traj_goal.trajectory.header.stamp = (rospy.Time.now() + rospy.Duration(0.1)) traj_goal.trajectory.points.append(JointTrajectoryPoint(positions=positions, velocities=velocities, time_from_start=rospy.Duration(time_to_joint))) if (side_prefix == 'r'): traj_goal.trajectory.joint_names = self.r_joint_names self.r_traj_action_client.send_goal(traj_goal) else: traj_goal.trajectory.joint_names = self.l_joint_names self.l_traj_action_client.send_goal(traj_goal) def marker_clicked_cb(self, feedback): if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE: self.ee_pose = feedback.pose self.update_viz() self._menu_handler.reApply(self._im_server) self._im_server.applyChanges() elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK: rospy.loginfo('Changing visibility of the pose controls.') if (self.is_control_visible): self.is_control_visible = False else: self.is_control_visible = True else: rospy.loginfo('Unhandled event: ' + str(feedback.event_type)) def update_viz(self): menu_control = InteractiveMarkerControl() menu_control.interaction_mode = InteractiveMarkerControl.BUTTON menu_control.always_visible = True frame_id = 'base_link' pose = self.ee_pose menu_control = self._add_gripper_marker(menu_control) text_pos = Point() text_pos.x = pose.position.x text_pos.y = pose.position.y text_pos.z = pose.position.z + 0.1 text = 'x=' + str(pose.position.x) + ' y=' + str(pose.position.y) + ' x=' + str(pose.position.z) menu_control.markers.append(Marker(type=Marker.TEXT_VIEW_FACING, id=0, scale=Vector3(0, 0, 0.03), text=text, color=ColorRGBA(0.0, 0.0, 0.0, 0.5), header=Header(frame_id=frame_id), pose=Pose(text_pos, Quaternion(0, 0, 0, 1)))) int_marker = InteractiveMarker() int_marker.name = 'ik_target_marker' int_marker.header.frame_id = frame_id int_marker.pose = pose int_marker.scale = 0.2 self._add_6dof_marker(int_marker) int_marker.controls.append(menu_control) self._im_server.insert(int_marker, self.marker_clicked_cb) def _add_gripper_marker(self, control): is_hand_open=False if is_hand_open: angle = 28 * numpy.pi / 180.0 else: angle = 0 transform1 = tf.transformations.euler_matrix(0, 0, angle) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, 0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1, transform2) mesh1 = self._make_mesh_marker() mesh1.mesh_resource = ('package://pr2_description/meshes/gripper_v0/gripper_palm.dae') mesh1.pose.position.x = -GripperMarkers._offset mesh1.pose.orientation.w = 1 mesh2 = self._make_mesh_marker() mesh2.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh2.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh3 = self._make_mesh_marker() mesh3.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh3.pose = GripperMarkers.get_pose_from_transform(t_distal) quat = tf.transformations.quaternion_multiply( tf.transformations.quaternion_from_euler(numpy.pi, 0, 0), tf.transformations.quaternion_from_euler(0, 0, angle)) transform1 = tf.transformations.quaternion_matrix(quat) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, -0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1,transform2) mesh4 = self._make_mesh_marker() mesh4.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh4.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh5 = self._make_mesh_marker() mesh5.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh5.pose = GripperMarkers.get_pose_from_transform(t_distal) control.markers.append(mesh1) control.markers.append(mesh2) control.markers.append(mesh3) control.markers.append(mesh4) control.markers.append(mesh5) return control @staticmethod def get_pose_from_transform(transform): pos = transform[:3,3].copy() rot = tf.transformations.quaternion_from_matrix(transform) return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def _make_mesh_marker(self): mesh = Marker() mesh.mesh_use_embedded_materials = False mesh.type = Marker.MESH_RESOURCE mesh.scale.x = 1.0 mesh.scale.y = 1.0 mesh.scale.z = 1.0 mesh.color = ColorRGBA(0.0, 0.5, 1.0, 0.6) ik_solution = self.ik.get_ik_for_ee(self.ee_pose) if (ik_solution == None): mesh.color = ColorRGBA(1.0, 0.0, 0.0, 0.6) else: mesh.color = ColorRGBA(0.0, 1.0, 0.0, 0.6) return mesh def _add_6dof_marker(self, int_marker): is_fixed = True control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed) int_marker.controls.append(control) def _make_6dof_control(self, name, orientation, is_move, is_fixed): control = InteractiveMarkerControl() control.name = name control.orientation = orientation control.always_visible = False if (self.is_control_visible): if is_move: control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS else: control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS else: control.interaction_mode = InteractiveMarkerControl.NONE if is_fixed: control.orientation_mode = InteractiveMarkerControl.FIXED return control
class GripperMarkers: _offset = 0.09 def __init__(self, side_prefix): self.side_prefix = side_prefix self._im_server = InteractiveMarkerServer('ik_request_markers_' + self.side_prefix) self._tf_listener = TransformListener() self._menu_handler = MenuHandler() self._menu_handler.insert('Move arm here', callback=self.move_to_pose_cb) self.r_joint_names = ['r_shoulder_pan_joint', 'r_shoulder_lift_joint', 'r_upper_arm_roll_joint', 'r_elbow_flex_joint', 'r_forearm_roll_joint', 'r_wrist_flex_joint', 'r_wrist_roll_joint'] self.l_joint_names = ['l_shoulder_pan_joint', 'l_shoulder_lift_joint', 'l_upper_arm_roll_joint', 'l_elbow_flex_joint', 'l_forearm_roll_joint', 'l_wrist_flex_joint', 'l_wrist_roll_joint'] # Create a trajectory action client r_traj_contoller_name = None l_traj_contoller_name = None if self.side_prefix == 'r': r_traj_controller_name = '/r_arm_controller/joint_trajectory_action' self.r_traj_action_client = SimpleActionClient(r_traj_controller_name, JointTrajectoryAction) rospy.loginfo('Waiting for a response from the trajectory ' + 'action server for RIGHT arm...') self.r_traj_action_client.wait_for_server() else: l_traj_controller_name = '/l_arm_controller/joint_trajectory_action' self.l_traj_action_client = SimpleActionClient(l_traj_controller_name, JointTrajectoryAction) rospy.loginfo('Waiting for a response from the trajectory ' + 'action server for LEFT arm...') self.l_traj_action_client.wait_for_server() self.is_control_visible = False self.ee_pose = self.get_ee_pose() self.ik = IK(side_prefix) self.update_viz() self._menu_handler.apply(self._im_server, 'ik_target_marker_' + self.side_prefix) self._im_server.applyChanges() print self.ik def get_ee_pose(self): from_frame = 'base_link' to_frame = self.side_prefix + '_wrist_roll_link' try: if self._tf_listener.frameExists(from_frame) and self._tf_listener.frameExists(to_frame): t = self._tf_listener.getLatestCommonTime(from_frame, to_frame) # t = rospy.Time.now() (pos, rot) = self._tf_listener.lookupTransform(to_frame, from_frame, t) # Note argument order :( else: rospy.logerr('TF frames do not exist; could not get end effector pose.') except Exception as err: rospy.logerr('Could not get end effector pose through TF.') rospy.logerr(err) pos = [1.0, 0.0, 1.0] rot = [0.0, 0.0, 0.0, 1.0] return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def move_to_pose_cb(self, feedback): rospy.loginfo('You pressed the `Move arm here` button from the menu.') '''Moves the arm to the desired joints''' print feedback time_to_joint = 2.0 positions = self.ik.get_ik_for_ee(feedback.pose) velocities = [0] * len(positions) traj_goal = JointTrajectoryGoal() traj_goal.trajectory.header.stamp = (rospy.Time.now() + rospy.Duration(0.1)) traj_goal.trajectory.points.append(JointTrajectoryPoint(positions=positions, velocities=velocities, time_from_start=rospy.Duration(time_to_joint))) if (self.side_prefix == 'r'): traj_goal.trajectory.joint_names = self.r_joint_names self.r_traj_action_client.send_goal(traj_goal) else: traj_goal.trajectory.joint_names = self.l_joint_names self.l_traj_action_client.send_goal(traj_goal) pass def marker_clicked_cb(self, feedback): if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE: self.ee_pose = feedback.pose self.update_viz() self._menu_handler.reApply(self._im_server) self._im_server.applyChanges() elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK: rospy.loginfo('Changing visibility of the pose controls.') if (self.is_control_visible): self.is_control_visible = False else: self.is_control_visible = True else: rospy.loginfo('Unhandled event: ' + str(feedback.event_type)) def update_viz(self): menu_control = InteractiveMarkerControl() menu_control.interaction_mode = InteractiveMarkerControl.BUTTON menu_control.always_visible = True frame_id = 'base_link' pose = self.ee_pose menu_control = self._add_gripper_marker(menu_control) text_pos = Point() text_pos.x = pose.position.x text_pos.y = pose.position.y text_pos.z = pose.position.z + 0.1 text = 'x=' + str(pose.position.x) + ' y=' + str(pose.position.y) + ' x=' + str(pose.position.z) menu_control.markers.append(Marker(type=Marker.TEXT_VIEW_FACING, id=0, scale=Vector3(0, 0, 0.03), text=text, color=ColorRGBA(0.0, 0.0, 0.0, 0.5), header=Header(frame_id=frame_id), pose=Pose(text_pos, Quaternion(0, 0, 0, 1)))) int_marker = InteractiveMarker() int_marker.name = 'ik_target_marker_' + self.side_prefix int_marker.header.frame_id = frame_id int_marker.pose = pose int_marker.scale = 0.2 self._add_6dof_marker(int_marker) int_marker.controls.append(menu_control) self._im_server.insert(int_marker, self.marker_clicked_cb) def _add_gripper_marker(self, control): is_hand_open=False if is_hand_open: angle = 28 * numpy.pi / 180.0 else: angle = 0 transform1 = tf.transformations.euler_matrix(0, 0, angle) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, 0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1, transform2) mesh1 = self._make_mesh_marker() mesh1.mesh_resource = ('package://pr2_description/meshes/gripper_v0/gripper_palm.dae') mesh1.pose.position.x = -GripperMarkers._offset mesh1.pose.orientation.w = 1 mesh2 = self._make_mesh_marker() mesh2.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh2.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh3 = self._make_mesh_marker() mesh3.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh3.pose = GripperMarkers.get_pose_from_transform(t_distal) quat = tf.transformations.quaternion_multiply( tf.transformations.quaternion_from_euler(numpy.pi, 0, 0), tf.transformations.quaternion_from_euler(0, 0, angle)) transform1 = tf.transformations.quaternion_matrix(quat) transform1[:3, 3] = [0.07691 - GripperMarkers._offset, -0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1,transform2) mesh4 = self._make_mesh_marker() mesh4.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger.dae') mesh4.pose = GripperMarkers.get_pose_from_transform(t_proximal) mesh5 = self._make_mesh_marker() mesh5.mesh_resource = ('package://pr2_description/meshes/gripper_v0/l_finger_tip.dae') mesh5.pose = GripperMarkers.get_pose_from_transform(t_distal) control.markers.append(mesh1) control.markers.append(mesh2) control.markers.append(mesh3) control.markers.append(mesh4) control.markers.append(mesh5) return control @staticmethod def get_pose_from_transform(transform): pos = transform[:3,3].copy() rot = tf.transformations.quaternion_from_matrix(transform) return Pose(Point(pos[0], pos[1], pos[2]), Quaternion(rot[0], rot[1], rot[2], rot[3])) def _make_mesh_marker(self): mesh = Marker() mesh.mesh_use_embedded_materials = False mesh.type = Marker.MESH_RESOURCE mesh.scale.x = 1.0 mesh.scale.y = 1.0 mesh.scale.z = 1.0 print self ik_solution = self.ik.get_ik_for_ee(self.ee_pose) if (ik_solution is None): mesh.color = ColorRGBA(1.0, 0.0, 0.0, 0.6) else: mesh.color = ColorRGBA(0.0, 1.0, 0.0, 0.6) return mesh def _add_6dof_marker(self, int_marker): is_fixed = True control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed) int_marker.controls.append(control) def _make_6dof_control(self, name, orientation, is_move, is_fixed): control = InteractiveMarkerControl() control.name = name control.orientation = orientation control.always_visible = False if (self.is_control_visible): if is_move: control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS else: control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS else: control.interaction_mode = InteractiveMarkerControl.NONE if is_fixed: control.orientation_mode = InteractiveMarkerControl.FIXED return control
class ArmStepMarker: ''' Marker for visualizing the steps of an action''' _offset = 0.09 _marker_click_cb = None _reference_change_cb = None def __init__(self, step_number, arm_index, action_step, marker_click_cb, reference_change_cb, parent_sequence): self.action_step = action_step self.arm_index = arm_index self.step_number = step_number self.is_requested = False self.is_deleted = False self.is_control_visible = False self.is_edited = False self.has_object = False self.is_dimmed = False self.is_fake = False self._sub_entries = None self._menu_handler = None ArmStepMarker._marker_click_cb = marker_click_cb ArmStepMarker._reference_change_cb = reference_change_cb self.parent_step_sequence = parent_sequence def _is_reachable(self): '''Checks if there is an IK solution for action step''' dummy, is_reachable = Robot.solve_ik_for_arm(self.arm_index, self.get_target()) # rospy.loginfo('Reachability of pose in ArmStepMarker : ' + # str(is_reachable)) return is_reachable def get_uid(self): '''Returns a unique id of the marker''' return (2 * self.step_number + self.arm_index) def _get_name(self): '''Generates the unique name for the marker''' return ('step' + str(self.step_number) + 'arm' + str(self.arm_index)) def decrease_id(self): '''Reduces the index of the marker''' self.step_number -= 1 self._update_menu() def update_ref_frames(self, ref_frame_list, new_ref_obj): '''Updates and re-assigns coordinate frames when the world changes''' # There is a new list of objects # If the current frames are already assigned to object, # we need to figure out the correspondences self.parent_step_sequence.ref_object_list = ref_frame_list arm_pose = self.get_target() if (arm_pose.refFrame == ArmState.OBJECT): self.has_object = False if (new_ref_obj != None): self.has_object = True arm_pose.refFrameObject = new_ref_obj self.parent_step_sequence.ref_names = ['base_link'] for i in range(len(self.parent_step_sequence.ref_object_list)): self.parent_step_sequence.ref_names.append( self.parent_step_sequence.ref_object_list[i].name) self._update_menu() def destroy(self): '''Removes marker from the world''' self.parent_step_sequence.im_server.erase(self._get_name()) self.parent_step_sequence.im_server.applyChanges() def _update_menu(self): '''Recreates the menu when something has changed''' self._menu_handler = MenuHandler() frame_entry = self._menu_handler.insert('Reference frame') self._sub_entries = [None] * len(self.parent_step_sequence.ref_names) for i in range(len(self.parent_step_sequence.ref_names)): self._sub_entries[i] = self._menu_handler.insert( self.parent_step_sequence.ref_names[i], parent=frame_entry, callback=self.change_ref_cb) self._menu_handler.insert('Move arm here', callback=self.move_to_cb) self._menu_handler.insert('Move to current arm pose', callback=self.move_pose_to_cb) self._menu_handler.insert('Delete', callback=self.delete_step_cb) for i in range(len(self.parent_step_sequence.ref_names)): self._menu_handler.setCheckState(self._sub_entries[i], MenuHandler.UNCHECKED) menu_id = self._get_menu_id(self._get_ref_name()) if menu_id is None: self.has_object = False else: self._menu_handler.setCheckState(menu_id, MenuHandler.CHECKED) self._update_viz_core() self._menu_handler.apply(self.parent_step_sequence.im_server, self._get_name()) self.parent_step_sequence.im_server.applyChanges() def _get_menu_id(self, ref_name): '''Returns the unique menu id from its name None if the object is not found''' if ref_name in self.parent_step_sequence.ref_names: index = self.parent_step_sequence.ref_names.index(ref_name) return self._sub_entries[index] else: return None def _get_menu_name(self, menu_id): '''Returns the menu name from its unique menu id''' index = self._sub_entries.index(menu_id) return self.parent_step_sequence.ref_names[index] def _get_ref_name(self): '''Returns the name string for the reference frame object of the action step''' ref_name = None if (self.action_step.type == ArmStepType.ARM_TARGET): if self.arm_index == 0: ref_frame = self.action_step.armTarget.rArm.refFrame ref_name = self.action_step.armTarget.rArm.refFrameObject.name else: ref_frame = self.action_step.armTarget.lArm.refFrame ref_name = self.action_step.armTarget.lArm.refFrameObject.name elif (self.action_step.type == ArmStepType.ARM_TRAJECTORY): if self.arm_index == 0: ref_frame = self.action_step.armTrajectory.rRefFrame ref_name = self.action_step.armTrajectory.rRefFrameOject.name else: ref_frame = self.action_step.armTrajectory.lRefFrame ref_name = self.action_step.armTrajectory.lRefFrameOject.name else: rospy.logerr('Unhandled marker type: ' + str(self.action_step.type)) if (ref_frame == ArmState.ROBOT_BASE): ref_name = 'base_link' return ref_name def _set_ref(self, new_ref_name): '''Changes the reference frame of the action step''' new_ref = World.get_world().get_ref_from_name(new_ref_name) if (new_ref != ArmState.ROBOT_BASE): index = self.parent_step_sequence.ref_names.index(new_ref_name) new_ref_obj = self.parent_step_sequence.ref_object_list[index - 1] else: new_ref_obj = Object() if (self.action_step.type == ArmStepType.ARM_TARGET): if self.arm_index == 0: self.action_step.armTarget.rArm = World.get_world().convert_ref_frame( self.action_step.armTarget.rArm, new_ref, new_ref_obj) else: self.action_step.armTarget.lArm = World.get_world().convert_ref_frame( self.action_step.armTarget.lArm, new_ref, new_ref_obj) elif (self.action_step.type == ArmStepType.ARM_TRAJECTORY): for i in range(len(self.action_step.armTrajectory.timing)): if self.arm_index == 0: arm_old = self.action_step.armTrajectory.rArm[i] arm_new = World.get_world().convert_ref_frame(arm_old, new_ref, new_ref_obj) self.action_step.armTrajectory.rArm[i] = arm_new else: arm_old = self.action_step.armTrajectory.lArm[i] arm_new = World.get_world().convert_ref_frame(arm_old, new_ref, new_ref_obj) self.action_step.armTrajectory.lArm[i] = arm_new if self.arm_index == 0: self.action_step.armTrajectory.rRefFrameObject = new_ref_obj self.action_step.armTrajectory.rRefFrame = new_ref else: self.action_step.armTrajectory.lRefFrameObject = new_ref_obj self.action_step.armTrajectory.lRefFrame = new_ref ArmStepMarker._reference_change_cb(self.get_uid(), new_ref, new_ref_obj) def _is_hand_open(self): '''Checks if the gripper is open for the action step''' if self.arm_index == 0: gripper_state = self.action_step.gripperAction.rGripper else: gripper_state = self.action_step.gripperAction.lGripper return (gripper_state == GripperState.OPEN) def set_new_pose(self, new_pose): '''Changes the pose of the action step''' if (self.action_step.type == ArmStepType.ARM_TARGET): if self.arm_index == 0: pose = ArmStepMarker._offset_pose(new_pose, -1) self.action_step.armTarget.rArm.ee_pose = pose else: pose = ArmStepMarker._offset_pose(new_pose, -1) self.action_step.armTarget.lArm.ee_pose = pose rospy.loginfo('Set new pose for action step.') self.update_viz() elif (self.action_step.type == ArmStepType.ARM_TRAJECTORY): rospy.logwarn('Modification of whole trajectory ' + 'segments is not implemented.') def get_absolute_position(self, is_start=True): '''Returns the absolute position of the action step''' pose = self.get_absolute_pose(is_start) return pose.position def get_absolute_pose(self, is_start=True): '''Returns the absolute pose of the action step''' if (self.action_step.type == ArmStepType.ARM_TARGET): if self.arm_index == 0: arm_pose = self.action_step.armTarget.rArm else: arm_pose = self.action_step.armTarget.lArm elif (self.action_step.type == ArmStepType.ARM_TRAJECTORY): if self.arm_index == 0: if is_start: index = len(self.action_step.armTrajectory.rArm) - 1 arm_pose = self.action_step.armTrajectory.rArm[index] else: arm_pose = self.action_step.armTrajectory.rArm[0] else: if is_start: index = len(self.action_step.armTrajectory.lArm) - 1 arm_pose = self.action_step.armTrajectory.lArm[index] else: arm_pose = self.action_step.armTrajectory.lArm[0] #if (arm_pose.refFrame == ArmState.OBJECT and # World.has_object(arm_pose.refFrameObject.name)): # return ArmStepMarker._offset_pose(arm_pose.ee_pose) #else: world_pose = World.get_world().get_absolute_pose(arm_pose) return ArmStepMarker._offset_pose(world_pose) def get_pose(self): '''Returns the pose of the action step''' target = self.get_target() if (target != None): return ArmStepMarker._offset_pose(target.ee_pose) @staticmethod def _offset_pose(pose, constant=1): '''Offsets the world pose for visualization''' transform = World.get_world().get_matrix_from_pose(pose) offset_array = [constant * ArmStepMarker._offset, 0, 0] offset_transform = tf.transformations.translation_matrix(offset_array) hand_transform = tf.transformations.concatenate_matrices(transform, offset_transform) return World.get_world().get_pose_from_transform(hand_transform) def set_target(self, target): '''Sets the new pose for the action step''' if (self.action_step.type == ArmStepType.ARM_TARGET): if self.arm_index == 0: self.action_step.armTarget.rArm = target else: self.action_step.armTarget.lArm = target self.has_object = True self._update_menu() self.is_edited = False def get_target(self, traj_index=None): '''Returns the pose for the action step''' if (self.action_step.type == ArmStepType.ARM_TARGET): if self.arm_index == 0: return self.action_step.armTarget.rArm else: return self.action_step.armTarget.lArm elif (self.action_step.type == ArmStepType.ARM_TRAJECTORY): if self.arm_index == 0: if traj_index is None: traj = self.action_step.armTrajectory.rArm traj_index = int(len(traj) / 2) return self.action_step.armTrajectory.rArm[traj_index] else: if traj_index is None: traj = self.action_step.armTrajectory.lArm traj_index = int(len(traj) / 2) return self.action_step.armTrajectory.lArm[traj_index] def _get_traj_pose(self, index): '''Returns a single pose for trajectory''' if (self.action_step.type == ArmStepType.ARM_TRAJECTORY): if self.arm_index == 0: target = self.action_step.armTrajectory.rArm[index] else: target = self.action_step.armTrajectory.lArm[index] return target.ee_pose else: rospy.logerr('Cannot request trajectory pose ' + 'on non-trajectory action step.') def _update_viz_core(self): '''Updates visualization after a change''' menu_control = InteractiveMarkerControl() menu_control.interaction_mode = InteractiveMarkerControl.BUTTON menu_control.always_visible = True frame_id = self._get_ref_name() pose = self.get_pose() if (self.action_step.type == ArmStepType.ARM_TARGET): menu_control = self._make_gripper_marker(menu_control, self._is_hand_open()) elif (self.action_step.type == ArmStepType.ARM_TRAJECTORY): point_list = [] for j in range(len(self.action_step.armTrajectory.timing)): point_list.append(self._get_traj_pose(j).position) main_marker = Marker(type=Marker.SPHERE_LIST, id=self.get_uid(), lifetime=rospy.Duration(2), scale=Vector3(0.02, 0.02, 0.02), header=Header(frame_id=frame_id), color=ColorRGBA(0.8, 0.4, 0.0, 0.8), points=point_list) menu_control.markers.append(main_marker) menu_control.markers.append(ArmStepMarker.make_sphere_marker( self.get_uid() + 2000, self._get_traj_pose(0), frame_id, 0.05)) last_index = len(self.action_step.armTrajectory.timing) - 1 menu_control.markers.append(ArmStepMarker.make_sphere_marker( self.get_uid() + 3000, self._get_traj_pose(last_index), frame_id, 0.05)) else: rospy.logerr('Non-handled action step type ' + str(self.action_step.type)) ref_frame = World.get_world().get_ref_from_name(frame_id) if (ref_frame == ArmState.OBJECT): # The following is needed to properly display the arrtow in browser, due to the fact that ros3djs # displays all nested markers in the reference frame of the interactive marker. # Thus, we need to calculate the position of the object in the reference frame of the interactive marker. quat = [pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w] inv_quat_matrix = quaternion_matrix(quaternion_inverse(quat)) pose_vec = numpy.array((pose.position.x, pose.position.y, pose.position.z, 0)) new_pose = numpy.dot(inv_quat_matrix, pose_vec) menu_control.markers.append(Marker(type=Marker.ARROW, id=(1000 + self.get_uid()), lifetime=rospy.Duration(2), scale=Vector3(0.01, 0.01, 0.0001), header=Header(frame_id=frame_id), color=ColorRGBA(0.8, 0.8, 0.0, 0.6), points=[Point(0, 0, 0), Point(-new_pose[0], -new_pose[1], -new_pose[2])])) # Calculate text position so that they "orbit" around the marker; # this is done so that poses in identical or similar positions # have non-overlapping text. Note that to do this without moving # the text around as the camera is moved, we assume that the viewer # is always looking directly at the robot, so we assume the x dimension # is constant and "orbin" in the y-z plane. n_orbitals = 8 # this should be a constant offset = 0.15 # this should be a constant orbital = (self.step_number - 1) % n_orbitals # - 1 to make 0-based angle_rad = (float(orbital) / n_orbitals) * (-2 * numpy.pi) + \ (numpy.pi / 2.0) # start above, at pi/2 (90 degrees) text_pos = Point() text_pos.x = 0 text_pos.y = numpy.cos(angle_rad) * offset text_pos.z = numpy.sin(angle_rad) * offset r,g,b = self.get_marker_color() menu_control.markers.append(Marker(type=Marker.TEXT_VIEW_FACING, id=self.get_uid(), scale=Vector3(0.06, 0.06, 0.06), lifetime=rospy.Duration(1.5), text='Step ' + str(self.step_number), color=ColorRGBA(r, g, b, 1.0), header=Header(frame_id=frame_id), pose=Pose(text_pos, Quaternion(0, 0, 0, 1)))) int_marker = InteractiveMarker() int_marker.name = self._get_name() int_marker.header.frame_id = frame_id int_marker.pose = pose int_marker.scale = 0.2 self._add_6dof_marker(int_marker, True) int_marker.controls.append(menu_control) self.parent_step_sequence.im_server.insert(int_marker, self.marker_feedback_cb) @staticmethod def make_sphere_marker(uid, pose, frame_id, radius): '''Creates a sphere marker''' return Marker(type=Marker.SPHERE, id=uid, lifetime=rospy.Duration(2), scale=Vector3(radius, radius, radius), pose=pose, header=Header(frame_id=frame_id), color=ColorRGBA(1.0, 0.5, 0.0, 0.8)) def marker_feedback_cb(self, feedback): '''Callback for when an event occurs on the marker''' if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE: self.set_new_pose(feedback.pose) self.update_viz() elif feedback.event_type == InteractiveMarkerFeedback.BUTTON_CLICK: # Set the visibility of the 6DOF controller rospy.loginfo('Changing visibility of the pose controls.') if (self.is_control_visible): self.is_control_visible = False else: self.is_control_visible = True ArmStepMarker._marker_click_cb(self.get_uid(), self.is_control_visible) else: rospy.loginfo('Unknown event' + str(feedback.event_type)) def delete_step_cb(self, dummy): '''Callback for when delete is requested''' self.is_deleted = True def move_to_cb(self, dummy): '''Callback for when moving to a pose is requested''' self.is_requested = True def move_pose_to_cb(self, dummy): '''Callback for when a pose change to current is requested''' self.is_edited = True def pose_reached(self): '''Update when a requested pose is reached''' self.is_requested = False def change_ref_cb(self, feedback): '''Callback for when a reference frame change is requested''' self._menu_handler.setCheckState( self._get_menu_id(self._get_ref_name()), MenuHandler.UNCHECKED) self._menu_handler.setCheckState(feedback.menu_entry_id, MenuHandler.CHECKED) new_ref = self._get_menu_name(feedback.menu_entry_id) self._set_ref(new_ref) rospy.loginfo('Switching reference frame to ' + new_ref + ' for action step ' + self._get_name()) self._menu_handler.reApply(self.parent_step_sequence.im_server) self.parent_step_sequence.im_server.applyChanges() self.update_viz() def update_viz(self): '''Updates visualization fully''' self._update_viz_core() self._menu_handler.reApply(self.parent_step_sequence.im_server) self.parent_step_sequence.im_server.applyChanges() def _add_6dof_marker(self, int_marker, is_fixed): '''Adds a 6 DoF control marker to the interactive marker''' control = self._make_6dof_control('rotate_x', Quaternion(1, 0, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_x', Quaternion(1, 0, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_z', Quaternion(0, 1, 0, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_z', Quaternion(0, 1, 0, 1), True, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('rotate_y', Quaternion(0, 0, 1, 1), False, is_fixed) int_marker.controls.append(control) control = self._make_6dof_control('move_y', Quaternion(0, 0, 1, 1), True, is_fixed) int_marker.controls.append(control) def _make_6dof_control(self, name, orientation, is_move, is_fixed): '''Creates one component of the 6dof controller''' control = InteractiveMarkerControl() control.name = name control.orientation = orientation control.always_visible = False if (self.is_control_visible): if is_move: control.interaction_mode = InteractiveMarkerControl.MOVE_AXIS else: control.interaction_mode = InteractiveMarkerControl.ROTATE_AXIS else: control.interaction_mode = InteractiveMarkerControl.NONE if is_fixed: control.orientation_mode = InteractiveMarkerControl.FIXED return control def get_marker_color(self): '''Makes marker colors in a gradient according to the progression set in _get_rgb_from_abs_pos() (below). returns (r,g,b) tuple, each from 0.0 to 1.0 ''' total = self.parent_step_sequence.total_n_markers # These are 1-based indexing; turn them into 0-based indexing. idx = self.step_number - 1 # First calculate "absolute" color position, plotting on a 0.0 - 1.0 # scale. This only applies if there's more than one step; otherwise we # set to 0.0 (though it could be anything, as it just gets multiplied # by 0, as the idx must be 0 if there's only one step total). abs_step_size = 1.0 / float(total - 1) if total > 1 else 0.0 abs_pos = abs_step_size * idx # Then, use our helper method to turn this into an RGB value. return self._get_rgb_from_abs_pos(abs_pos) def _get_rgb_from_abs_pos(self, abs_pos): '''Turns abs_pos, a float from 0.0 to 1.0 inclusive, into an rgb value of the range currently programmed. The progression is as follows (in order to avoid green hues, which could be confused with the objects), by gradient "bucket" step: - 0 yellow (start) -> red - 1 red -> purple - 2 purple -> blue - 3 blue -> cyan (end) Returns (r,g,b) tuple of floats, each from 0.0 to 1.0 inclusive.''' # Bucket settings (make constant) bucket = self.arm_index bucket_pos = abs_pos # Now translate to colors; todo later implement with better data # structure. r = 0.0 g = 0.0 b = 0.0 if bucket == 0: # yellow -> red r = 1.0 g = 1.0 - bucket_pos elif bucket == 1: # cyan -> blue g = 1.0 - bucket_pos b = 1.0 else: # Set white as error color rospy.logwarn("Bad color gradient; bucket " + str(bucket) + " and bucket position " + str(bucket_pos)) r,g,b = 1.0, 1.0, 1.0 return (r,g,b) def _make_mesh_marker(self): '''Creates a mesh marker''' mesh = Marker() mesh.mesh_use_embedded_materials = False mesh.type = Marker.MESH_RESOURCE mesh.scale.x = 1.0 mesh.scale.y = 1.0 mesh.scale.z = 1.0 alpha = 0.6 if self.is_dimmed: alpha = 0.1 if self.is_fake: alpha = 0.4 mesh.color = ColorRGBA(0.3, 0.3, 0.3, alpha) return mesh if self._is_reachable(): # Original: some kinda orange # r,g,b = 1.0, 0.5, 0.0 # New: rainbow! See method comment for details. r,g,b = self.get_marker_color() mesh.color = ColorRGBA(r, g, b, alpha) else: mesh.color = ColorRGBA(0.5, 0.5, 0.5, alpha) return mesh def _make_gripper_marker(self, control, is_hand_open=False): '''Makes a gripper marker''' if is_hand_open: angle = 28 * numpy.pi / 180.0 else: angle = 0 transform1 = tf.transformations.euler_matrix(0, 0, angle) transform1[:3, 3] = [0.07691 - ArmStepMarker._offset, 0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1, transform2) mesh1 = self._make_mesh_marker() mesh1.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/gripper_palm.dae') mesh1.pose.position.x = -ArmStepMarker._offset mesh1.pose.orientation.w = 1 mesh2 = self._make_mesh_marker() mesh2.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger.dae') mesh2.pose = World.get_world().get_pose_from_transform(t_proximal) mesh3 = self._make_mesh_marker() mesh3.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger_tip.dae') mesh3.pose = World.get_world().get_pose_from_transform(t_distal) quat = tf.transformations.quaternion_multiply( tf.transformations.quaternion_from_euler(numpy.pi, 0, 0), tf.transformations.quaternion_from_euler(0, 0, angle)) transform1 = tf.transformations.quaternion_matrix(quat) transform1[:3, 3] = [0.07691 - ArmStepMarker._offset, -0.01, 0] transform2 = tf.transformations.euler_matrix(0, 0, -angle) transform2[:3, 3] = [0.09137, 0.00495, 0] t_proximal = transform1 t_distal = tf.transformations.concatenate_matrices(transform1, transform2) mesh4 = self._make_mesh_marker() mesh4.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger.dae') mesh4.pose = World.get_world().get_pose_from_transform(t_proximal) mesh5 = self._make_mesh_marker() mesh5.mesh_resource = ('package://pr2_description/meshes/' + 'gripper_v0/l_finger_tip.dae') mesh5.pose = World.get_world().get_pose_from_transform(t_distal) control.markers.append(mesh1) control.markers.append(mesh2) control.markers.append(mesh3) control.markers.append(mesh4) control.markers.append(mesh5) return control
class IntCollisionEnv(CollisionEnvServices): def __init__(self, setup, world_frame): super(IntCollisionEnv, self).__init__(setup, world_frame) self.im_server = InteractiveMarkerServer(self.NS + "markers") self.check_attached_timer = rospy.Timer(rospy.Duration(0.1), self.check_attached_timer_cb) self.create_menus() def create_menus(self): self.global_menu_handler = MenuHandler() g_art = self.global_menu_handler.insert("Artificial") self.global_menu_handler.insert("Add primitive", parent=g_art, callback=self.global_menu_add_prim_cb) self.global_menu_handler.insert("Clear all", parent=g_art, callback=self.global_menu_clear_all_cb) self.global_menu_handler.insert( "Clear all (permanent)", parent=g_art, callback=self.global_menu_clear_all_perm_cb) self.global_menu_handler.insert("Save all", parent=g_art, callback=self.global_menu_save_all_cb) self.global_menu_handler.insert("Reload", parent=g_art, callback=self.global_menu_reload_cb) g_det = self.global_menu_handler.insert("Detected") self.global_menu_handler.insert("Pause", parent=g_det, callback=self.global_menu_pause_cb) self.global_menu_handler.insert( "Clear all", parent=g_det, callback=self.global_menu_det_clear_all_cb) self.a_obj_menu_handler = MenuHandler() mov = self.a_obj_menu_handler.insert("Moveable", callback=self.menu_moveable_cb) self.a_obj_menu_handler.setCheckState(mov, MenuHandler.UNCHECKED) sc = self.a_obj_menu_handler.insert("Scaleable", callback=self.menu_scaleable_cb) self.a_obj_menu_handler.setCheckState(sc, MenuHandler.UNCHECKED) self.a_obj_menu_handler.insert("Save", callback=self.menu_save_cb) self.a_obj_menu_handler.insert("Clear", callback=self.menu_remove_cb) self.d_obj_menu_handler = MenuHandler() self.d_obj_menu_handler.insert("Clear", callback=self.d_menu_clear_cb) int_marker = InteractiveMarker() int_marker.header.frame_id = self.world_frame int_marker.pose.position.z = 1.2 int_marker.scale = 0.5 int_marker.name = "global_menu" int_marker.description = "Global Menu" control = InteractiveMarkerControl() control.interaction_mode = InteractiveMarkerControl.BUTTON control.always_visible = True marker = Marker() marker.type = Marker.CUBE marker.scale.x = 0.05 marker.scale.y = 0.05 marker.scale.z = 0.05 marker.color.r = 0.5 marker.color.g = 0.5 marker.color.b = 0.5 marker.color.a = 0.5 control.markers.append(marker) int_marker.controls.append(control) self.im_server.insert(int_marker, self.ignored_cb) self.global_menu_handler.apply(self.im_server, int_marker.name) self.im_server.applyChanges() def ignored_cb(self, feedback): pass def d_menu_clear_cb(self, f): pass def global_menu_det_clear_all_cb(self, f): for name in self.clear_all_det(): self.im_server.erase(name) self.im_server.applyChanges() def global_menu_pause_cb(self, f): handle = f.menu_entry_id state = self.global_menu_handler.getCheckState(handle) if state == MenuHandler.CHECKED: self.global_menu_handler.setCheckState(handle, MenuHandler.UNCHECKED) self.paused = False else: self.global_menu_handler.setCheckState(handle, MenuHandler.CHECKED) self.paused = True self.global_menu_handler.reApply(self.im_server) self.im_server.applyChanges() def global_menu_save_all_cb(self, f): self.save_primitives() def global_menu_add_prim_cb(self, feedback): p = CollisionPrimitive() p.name = self._generate_name() p.bbox.type = SolidPrimitive.BOX p.bbox.dimensions = [0.1, 0.1, 0.1] p.pose.header.frame_id = self.world_frame p.pose.pose.orientation.w = 1 p.pose.pose.position.z = 0.5 p.setup = self.setup self.add_primitive(p) def global_menu_reload_cb(self, feedback): self.reload() def global_menu_clear_all_cb(self, feedback): self.clear_all(permanent=False) def global_menu_clear_all_perm_cb(self, feedback): self.clear_all() def menu_save_cb(self, f): self.save_primitive(f.marker_name) def menu_scaleable_cb(self, f): handle = f.menu_entry_id state = self.a_obj_menu_handler.getCheckState(handle) if state == MenuHandler.CHECKED: self.a_obj_menu_handler.setCheckState(handle, MenuHandler.UNCHECKED) # TODO else: self.a_obj_menu_handler.setCheckState(handle, MenuHandler.CHECKED) # TODO self.a_obj_menu_handler.reApply(self.im_server) self.im_server.applyChanges() def menu_moveable_cb(self, feedback): handle = feedback.menu_entry_id state = self.a_obj_menu_handler.getCheckState(handle) if state == MenuHandler.CHECKED: self.a_obj_menu_handler.setCheckState(handle, MenuHandler.UNCHECKED) # if feedback.marker_name in self.moveable: # self.moveable.remove(feedback.marker_name) self.im_server.erase(feedback.marker_name) self.im_server.insert( make_def(self.artificial_objects[feedback.marker_name]), self.process_im_feedback) else: self.a_obj_menu_handler.setCheckState(handle, MenuHandler.CHECKED) self.make_interactive( self.artificial_objects[feedback.marker_name]) self.a_obj_menu_handler.reApply(self.im_server) self.im_server.applyChanges() def menu_remove_cb(self, feedback): self.remove_name(feedback.marker_name) def process_im_feedback(self, feedback): if feedback.event_type == InteractiveMarkerFeedback.POSE_UPDATE: ps = PoseStamped() ps.header = feedback.header ps.pose = feedback.pose if feedback.marker_name in self.artificial_objects: self.set_primitive_pose(feedback.marker_name, ps) elif feedback.marker_name: # detected objects pass def make_interactive(self, p): im = self.im_server.get(p.name) for v in (("x", (1, 0, 0, 1)), ("y", (0, 0, 1, 1)), ("z", (0, 1, 0, 1))): im.controls.append(rotate_axis_control("rotate_" + v[0], v[1])) im.controls.append(move_axis_control("move_" + v[0], v[1])) def remove_name(self, name): super(IntCollisionEnv, self).remove_name(name) self.im_server.erase(name) self.im_server.applyChanges() def add_primitive(self, p): super(IntCollisionEnv, self).add_primitive(p) self.im_server.insert(make_def(p), self.process_im_feedback) self.a_obj_menu_handler.apply(self.im_server, p.name) self.im_server.applyChanges() def reload(self): self.im_server.clear() self.create_menus() super(IntCollisionEnv, self).reload() def add_detected(self, name, ps, object_type): super(IntCollisionEnv, self).add_detected(name, ps, object_type) p = CollisionPrimitive() p.name = name p.pose = ps p.bbox = object_type.bbox self.im_server.insert(make_def(p, color=(0, 0, 1)), self.process_im_feedback) self.im_server.applyChanges() def clear_detected(self, name): super(IntCollisionEnv, self).clear_detected(name) self.im_server.erase(name) self.im_server.applyChanges() def check_attached_timer_cb(self, evt): for name, ps, bbox in self.get_attached(): p = CollisionPrimitive() p.name = name p.pose = ps p.bbox = bbox self.im_server.insert(make_def(p, color=(1, 0, 0)), self.process_im_feedback) self.im_server.applyChanges()