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
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
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
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
00087
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
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
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
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
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
00144
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]
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