move_arm_tool.py
Go to the documentation of this file.
00001 import roslib; roslib.load_manifest('rcommander')
00002 import rospy
00003 from PyQt4.QtGui import *
00004 from PyQt4.QtCore import *
00005 import tool_utils as tu
00006 import arm_navigation_msgs.msg as an
00007 import actionlib
00008 import actionlib_msgs.msg as am
00009 import numpy as np
00010 import smach
00011 
00012 
00013 class SafeMoveArmTool(tu.ToolBase):
00014 
00015     def __init__(self, rcommander):
00016         tu.ToolBase.__init__(self, rcommander, 'save_move', 'Safe Move')
00017         #self.left, self.right = pu.PR2Arm.create_arms(rcommander.tf_listener, 'both')
00018         self.joint_name_fields = ["shoulder_pan_joint", "shoulder_lift_joint", "upper_arm_roll_joint", 
00019                                   "elbow_flex_joint", "forearm_roll_joint", "wrist_flex_joint", "wrist_roll_joint"]
00020 
00021     def fill_property_box(self, pbox):
00022         formlayout = pbox.layout()
00023 
00024         self.arm_box = QComboBox(pbox)
00025         self.arm_box.addItem('left')
00026         self.arm_box.addItem('right')
00027         formlayout.addRow('&Arm', self.arm_box)
00028 
00029         #Controls for displaying the current joint states
00030         for name in self.joint_name_fields:
00031             exec("self.%s = QLineEdit(pbox)" % name)
00032             exec("formlayout.addRow(\"&\" + name, self.%s)" % name)
00033 
00034         #Controls for getting the current joint states
00035         self.pose_button = QPushButton(pbox)
00036         self.pose_button.setText('Current Joint Angles')
00037         self.rcommander.connect(self.pose_button, SIGNAL('clicked()'), self.get_current_joint_angles)
00038         formlayout.addRow(self.pose_button)
00039         self.reset()
00040 
00041 
00042     def get_current_joint_angles(self):
00043         if ('Left' == str(self.arm_box.currentText())):
00044             arm_obj = self.rcommander.left_arm
00045         else:
00046             arm_obj = self.rcommander.right_arm
00047 
00048         pose_mat = arm_obj.pose()
00049         for idx, name in enumerate(self.joint_name_fields):
00050             deg = np.degrees(pose_mat[idx, 0])
00051             exec('line_edit = self.%s' % name)
00052             line_edit.setText(str(deg))
00053 
00054 
00055     def _create_node(self, name=None):
00056         if name == None:
00057             nname = self.name + str(self.counter)
00058         else:
00059             nname = name
00060 
00061         joints = []
00062         for name in self.joint_name_fields:
00063             exec('rad = np.radians(float(str(self.%s.text())))' % name)
00064             joints.append(rad)
00065         return SafeMoveArmState(nname, str(self.arm_box.currentText()), joints)
00066 
00067     def _node_selected(self, my_node):
00068         self.arm_box.setCurrentIndex(self.arm_box.findText(my_node.arm))
00069         for idx, name in enumerate(self.joint_name_fields):
00070             deg = np.degrees(my_node.joints[idx])
00071             exec('line_edit = self.%s' % name)
00072             line_edit.setText(str(deg))
00073 
00074     def reset(self):
00075         self.arm_box.setCurrentIndex(self.arm_box.findText('left'))
00076         for name in self.joint_name_fields:
00077             exec('self.%s.setText(str(0.))' % name)
00078 
00079     def get_smach_class(self):
00080         return SafeMoveArmState
00081 
00082 class SafeMoveArmState(smach.State, tu.StateBase): 
00083 
00084     TIME_OUT = 60
00085 
00086     # @param name
00087     # @param arm 'left' or 'right'
00088     def __init__(self, name, arm, joints):
00089         self.name = name
00090         self.arm = arm
00091         self.joints = joints
00092         self.__init_unpicklables__()
00093 
00094     def _still_going(self):
00095         state = self.action_client.get_state()
00096         gripper_event_detected = state not in [am.GoalStatus.ACTIVE, am.GoalStatus.PENDING]
00097         return gripper_event_detected
00098 
00099     def execute(self, userdata):        
00100         #Construct goal and send it
00101         goal = an.MoveArmGoal()
00102         goal.motion_plan_request.group_name = self.group_name
00103         goal.motion_plan_request.num_planning_attempts = 2;
00104         goal.motion_plan_request.allowed_planning_time = rospy.Duration(5.0);
00105         goal.motion_plan_request.planner_id = ""
00106         goal.planner_service_name = "ompl_planning/plan_kinematic_path"
00107 
00108         for (joint_name, joint_angle) in zip(self.joint_names, self.joints):
00109             joint_constraint = an.JointConstraint()
00110             joint_constraint.joint_name = joint_name
00111             joint_constraint.position = joint_angle
00112             joint_constraint.tolerance_below = .1
00113             joint_constraint.tolerance_above = .1
00114             goal.motion_plan_request.goal_constraints.joint_constraints.append(joint_constraint) 
00115         self.move_arm_client.send_goal(goal)
00116     
00117         #Wait for action to finish
00118         r = rospy.Rate(30)
00119         start_time = rospy.get_time()
00120         state = self.move_arm_client.get_state()
00121         preempted = False
00122         succeeded = False
00123         while True:
00124             #we have been preempted
00125             if self.preempt_requested():
00126                 rospy.loginfo('SafeMoveArmState: preempt requested')
00127                 self.move_arm_client.cancel_goal()
00128                 self.service_preempt()
00129                 preempted = True
00130                 break
00131             
00132             #we timed out
00133             if (rospy.get_time() - start_time) > SafeMoveArmState.TIME_OUT:
00134                 self.move_arm_client.cancel_goal()
00135                 rospy.loginfo('SafeMoveArmState: timed out!')
00136                 break
00137 
00138             if (state not in [am.GoalStatus.ACTIVE, am.GoalStatus.PENDING]):
00139                 if state == am.GoalStatus.SUCCEEDED:
00140                     if result.error_code.val == 1:
00141                         rospy.loginfo('SafeMoveArmState: Succeeded!')
00142                         succeeded = True
00143                     #elif result.error_code.val == ArmNavigationErrorCodes.START_STATE_IN_COLLISION:
00144                     #    succeeded = False
00145                 break
00146             r.sleep()
00147 
00148         if preempted:
00149             return 'preempted'
00150 
00151         if succeeded:
00152             return 'succeeded'
00153 
00154         return 'failed'
00155 
00156 
00157     def __init_unpicklables__(self):
00158         tu.StateBase.__init__(self, self.name)
00159         smach.State.__init__(self, outcomes = ['succeeded', 'preempted', 'failed'], input_keys = [], output_keys = [])
00160 
00161         if self.arm == 'left':
00162             self.move_arm_client = actionlib.SimpleActionClient('move_left_arm', an.MoveArmAction)
00163             self.joint_names = rospy.get_param('/l_arm_controller/joints')
00164             self.group_name = 'left_arm'
00165 
00166         if self.arm == 'right':
00167             self.move_arm_client = actionlib.SimpleActionClient('move_right_arm', an.MoveArmAction)
00168             self.joint_names = rospy.get_param('/r_arm_controller/joints')
00169             self.group_name = 'right_arm'
00170 
00171 
00172     def __getstate__(self):
00173         state = tu.StateBase.__getstate__(self)
00174         my_state = [self.name, self.arm, self.joints] #Change this
00175         return {'state_base': state, 'self': my_state}
00176 
00177 
00178     def __setstate__(self, state):
00179         tu.StateBase.__setstate__(self, state['state_base'])
00180         self.name, self.arm, self.joints = state['self']
00181         self.__init_unpicklables__()
00182 
00183 
00184 
00185 
00186 


rcommander
Author(s): Hai Nguyen (haidai@gmail.com)
autogenerated on Thu Nov 28 2013 11:46:34