Go to the documentation of this file.00001
00002 import rospy
00003 from PyQt4.QtGui import *
00004 from PyQt4.QtCore import *
00005 import rcommander.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', SafeMoveArmState)
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.robot.left
00045 else:
00046 arm_obj = self.rcommander.robot.right
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 new_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 set_node_properties(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
00080 class SafeMoveArmState(tu.StateBase):
00081
00082
00083
00084
00085 def __init__(self, name, arm, joints):
00086 tu.StateBase.__init__(self, name)
00087 self.arm = arm
00088 self.joints = joints
00089
00090 def get_smach_state(self):
00091 return SafeMoveArmStateSmach(self.arm, self.joints)
00092
00093 class SafeMoveArmStateSmach(smach.State):
00094
00095 TIME_OUT = 60
00096
00097 def __init__(self, arm, joints):
00098 smach.State.__init__(self, outcomes = ['succeeded', 'preempted', 'failed'], input_keys = [], output_keys = [])
00099 self.joints = joints
00100
00101 if arm == 'left':
00102 self.move_arm_client = actionlib.SimpleActionClient('move_left_arm', an.MoveArmAction)
00103 self.joint_names = rospy.get_param('/l_arm_controller/joints')
00104 self.group_name = 'left_arm'
00105
00106 if arm == 'right':
00107 self.move_arm_client = actionlib.SimpleActionClient('move_right_arm', an.MoveArmAction)
00108 self.joint_names = rospy.get_param('/r_arm_controller/joints')
00109 self.group_name = 'right_arm'
00110
00111 def _still_going(self):
00112 state = self.action_client.get_state()
00113 gripper_event_detected = state not in [am.GoalStatus.ACTIVE, am.GoalStatus.PENDING]
00114 return gripper_event_detected
00115
00116 def execute(self, userdata):
00117
00118 goal = an.MoveArmGoal()
00119 goal.motion_plan_request.group_name = self.group_name
00120 goal.motion_plan_request.num_planning_attempts = 2;
00121 goal.motion_plan_request.allowed_planning_time = rospy.Duration(5.0);
00122 goal.motion_plan_request.planner_id = ""
00123 goal.planner_service_name = "ompl_planning/plan_kinematic_path"
00124
00125 for (joint_name, joint_angle) in zip(self.joint_names, self.joints):
00126 joint_constraint = an.JointConstraint()
00127 joint_constraint.joint_name = joint_name
00128 joint_constraint.position = joint_angle
00129 joint_constraint.tolerance_below = .1
00130 joint_constraint.tolerance_above = .1
00131 goal.motion_plan_request.goal_constraints.joint_constraints.append(joint_constraint)
00132 self.move_arm_client.send_goal(goal)
00133
00134
00135 r = rospy.Rate(30)
00136 start_time = rospy.get_time()
00137 state = self.move_arm_client.get_state()
00138 preempted = False
00139 succeeded = False
00140 while True:
00141
00142 if self.preempt_requested():
00143 rospy.loginfo('SafeMoveArmState: preempt requested')
00144 self.move_arm_client.cancel_goal()
00145 self.service_preempt()
00146 preempted = True
00147 break
00148
00149
00150 if (rospy.get_time() - start_time) > SafeMoveArmStateSmach.TIME_OUT:
00151 self.move_arm_client.cancel_goal()
00152 rospy.loginfo('SafeMoveArmState: timed out!')
00153 break
00154
00155 if (state not in [am.GoalStatus.ACTIVE, am.GoalStatus.PENDING]):
00156 if state == am.GoalStatus.SUCCEEDED:
00157 if result.error_code.val == 1:
00158 rospy.loginfo('SafeMoveArmState: Succeeded!')
00159 succeeded = True
00160
00161
00162 break
00163 r.sleep()
00164
00165 if preempted:
00166 return 'preempted'
00167
00168 if succeeded:
00169 return 'succeeded'
00170
00171 return 'failed'
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279