00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import copy
00036 import math
00037
00038 import actionlib
00039 from moveit_commander import MoveGroupCommander
00040 from moveit_commander import MoveItCommanderException
00041 import rospy
00042 from pr2_controllers_msgs.msg import JointTrajectoryAction
00043 from pr2_controllers_msgs.msg import JointTrajectoryGoal
00044 from trajectory_msgs.msg import JointTrajectoryPoint
00045 from tf.transformations import quaternion_from_euler
00046
00047 from hironx_ros_bridge.constant import Constant
00048
00049 _MSG_ASK_ISSUEREPORT = 'Your report to ' + \
00050 'https://github.com/start-jsk/rtmros_hironx/issues ' + \
00051 'about the issue you are seeing is appreciated.'
00052
00053
00054 class ROS_Client(object):
00055 '''
00056 This class:
00057
00058 - holds methods that are specific to Kawada Industries' dual-arm
00059 robot called Hiro, via ROS.
00060 - As of July 2014, this class is only intended to be used through HIRONX
00061 class.
00062 '''
00063
00064 _MSG_NO_MOVEGROUP_FOUND = ('\nMake sure you\'ve launched MoveGroup ' +
00065 '(e.g. by launching ' +
00066 'moveit_planning_execution.launch)')
00067
00068 def __init__(self, jointgroups=None):
00069 '''
00070 @type jointgroups: [str]
00071 '''
00072 rospy.init_node('hironx_ros_client')
00073 if jointgroups:
00074 self._set_groupnames(jointgroups)
00075 self._init_action_clients()
00076
00077 self._movegr_larm = self._movegr_rarm = None
00078 try:
00079 self._init_moveit_commanders()
00080 except RuntimeError as e:
00081 rospy.logerr(str(e) + self._MSG_NO_MOVEGROUP_FOUND)
00082
00083 def _init_moveit_commanders(self):
00084 '''
00085 @raise RuntimeError: When MoveGroup is not running.
00086 '''
00087
00088
00089 try:
00090 self._movegr_larm = MoveGroupCommander(Constant.GRNAME_LEFT_ARM_MOVEGROUP)
00091 self._movegr_rarm = MoveGroupCommander(Constant.GRNAME_RIGHT_ARM_MOVEGROUP)
00092 except RuntimeError as e:
00093 raise e
00094
00095 def _init_action_clients(self):
00096 self._aclient_larm = actionlib.SimpleActionClient(
00097 '/larm_controller/joint_trajectory_action', JointTrajectoryAction)
00098 self._aclient_rarm = actionlib.SimpleActionClient(
00099 '/rarm_controller/joint_trajectory_action', JointTrajectoryAction)
00100 self._aclient_head = actionlib.SimpleActionClient(
00101 '/head_controller/joint_trajectory_action', JointTrajectoryAction)
00102 self._aclient_torso = actionlib.SimpleActionClient(
00103 '/torso_controller/joint_trajectory_action', JointTrajectoryAction)
00104
00105 self._aclient_larm.wait_for_server()
00106 rospy.loginfo('ros_client; 1')
00107 self._goal_larm = JointTrajectoryGoal()
00108 rospy.loginfo('ros_client; 2')
00109 self._goal_larm.trajectory.joint_names.append("LARM_JOINT0")
00110 self._goal_larm.trajectory.joint_names.append("LARM_JOINT1")
00111 self._goal_larm.trajectory.joint_names.append("LARM_JOINT2")
00112 self._goal_larm.trajectory.joint_names.append("LARM_JOINT3")
00113 self._goal_larm.trajectory.joint_names.append("LARM_JOINT4")
00114 self._goal_larm.trajectory.joint_names.append("LARM_JOINT5")
00115 rospy.loginfo('ros_client; 3')
00116
00117 self._aclient_rarm.wait_for_server()
00118 self._goal_rarm = JointTrajectoryGoal()
00119 self._goal_rarm.trajectory.joint_names.append("RARM_JOINT0")
00120 self._goal_rarm.trajectory.joint_names.append("RARM_JOINT1")
00121 self._goal_rarm.trajectory.joint_names.append("RARM_JOINT2")
00122 self._goal_rarm.trajectory.joint_names.append("RARM_JOINT3")
00123 self._goal_rarm.trajectory.joint_names.append("RARM_JOINT4")
00124 self._goal_rarm.trajectory.joint_names.append("RARM_JOINT5")
00125
00126 self._aclient_head.wait_for_server()
00127 self._goal_head = JointTrajectoryGoal()
00128 self._goal_head.trajectory.joint_names.append('HEAD_JOINT0')
00129 self._goal_head.trajectory.joint_names.append('HEAD_JOINT1')
00130
00131 self._aclient_torso.wait_for_server()
00132 self._goal_torso = JointTrajectoryGoal()
00133 self._goal_torso.trajectory.joint_names.append('CHEST_JOINT0')
00134
00135 rospy.loginfo('Joint names; ' +
00136 'Torso: {}\n\tHead: {}\n\tL-Arm: {}\n\tR-Arm: {}'.format(
00137 self._goal_torso.trajectory.joint_names,
00138 self._goal_head.trajectory.joint_names,
00139 self._goal_larm.trajectory.joint_names,
00140 self._goal_rarm.trajectory.joint_names))
00141
00142 def _set_groupnames(self, groupnames):
00143 '''
00144 @type groupnames: [str]
00145 @param groupnames: List of the joint group names. Assumes to be in the
00146 following order:
00147 torso, head, right arm, left arm.
00148 This current setting is derived from the order of
00149 Groups argument in HIRONX class. If other groups
00150 need to be defined in the future, this method may
00151 need to be modified.
00152 '''
00153 rospy.loginfo('_set_groupnames; groupnames={}'.format(groupnames))
00154 self._GR_TORSO = groupnames[0]
00155 self._GR_HEAD = groupnames[1]
00156 self._GR_RARM = groupnames[2]
00157 self._GR_LARM = groupnames[3]
00158
00159 def go_init(self, task_duration=7.0):
00160 '''
00161 Init positions are taken from HIRONX.
00162 TODO: Need to add factory position too that's so convenient when
00163 working with the manufacturer.
00164 @type task_duration: float
00165 '''
00166 rospy.loginfo('*** go_init begins ***')
00167 POSITIONS_TORSO_DEG = [0.0]
00168 self.set_joint_angles_deg(Constant.GRNAME_TORSO, POSITIONS_TORSO_DEG, task_duration)
00169 POSITIONS_HEAD_DEG = [0.0, 0.0]
00170 self.set_joint_angles_deg(Constant.GRNAME_HEAD, POSITIONS_HEAD_DEG, task_duration)
00171 POSITIONS_LARM_DEG = [0.6, 0, -100, -15.2, 9.4, -3.2]
00172 self.set_joint_angles_deg(Constant.GRNAME_LEFT_ARM, POSITIONS_LARM_DEG, task_duration)
00173 POSITIONS_RARM_DEG = [-0.6, 0, -100, 15.2, 9.4, 3.2]
00174 self.set_joint_angles_deg(Constant.GRNAME_RIGHT_ARM, POSITIONS_RARM_DEG,
00175 task_duration, wait=True)
00176 rospy.loginfo(self._goal_larm.trajectory.points)
00177
00178 def set_joint_angles_rad(self, groupname, positions_radian, duration=7.0,
00179 wait=False):
00180 '''
00181 @type groupname: str
00182 @param groupname: This should exist in self.groupnames.
00183 @type positions_radian: [float]
00184 @type duration: float
00185 @type wait: bool
00186 '''
00187 if groupname == Constant.GRNAME_TORSO:
00188 action_client = self._aclient_torso
00189 goal = self._goal_torso
00190 elif groupname == Constant.GRNAME_HEAD:
00191 action_client = self._aclient_head
00192 goal = self._goal_head
00193 elif groupname == Constant.GRNAME_LEFT_ARM:
00194 action_client = self._aclient_larm
00195 goal = self._goal_larm
00196 elif groupname == Constant.GRNAME_RIGHT_ARM:
00197 action_client = self._aclient_rarm
00198 goal = self._goal_rarm
00199 else:
00200
00201 rospy.logerr('groupname {} not assigned'.format(groupname))
00202
00203 try:
00204 pt = JointTrajectoryPoint()
00205 pt.positions = positions_radian
00206 pt.time_from_start = rospy.Duration(duration)
00207 goal.trajectory.points = [pt]
00208 goal.trajectory.header.stamp = \
00209 rospy.Time.now() + rospy.Duration(duration)
00210
00211 action_client.send_goal(goal)
00212 if wait:
00213 rospy.loginfo('wait_for_result for the joint group {} = {}'.format(
00214 groupname, action_client.wait_for_result()))
00215 except rospy.ROSInterruptException as e:
00216 rospy.loginfo(e.str())
00217
00218 def set_joint_angles_deg(self, groupname, positions_deg, duration=7.0,
00219 wait=False):
00220 '''
00221 @type groupname: str
00222 @param groupname: This should exist in self.groupnames.
00223 @type positions_deg: [float]
00224 @type duration: float
00225 @type wait: bool
00226 '''
00227 self.set_joint_angles_rad(groupname, self._to_rad_list(positions_deg),
00228 duration, wait)
00229
00230 def _to_rad_list(self, list_degree):
00231 '''
00232 @TODO Needs to be replaced by something more common, or at least moved
00233 somewhere more common.
00234
00235 @type list_degree: [float]
00236 @param list_degree: A list length of the number of joints.
00237 '''
00238 list_rad = []
00239 for deg in list_degree:
00240 rad = math.radians(deg)
00241 list_rad.append(rad)
00242 rospy.logdebug('Position deg={} rad={}'.format(deg, rad))
00243 return list_rad
00244
00245 def set_pose(self, joint_group, position, rpy=None, task_duration=7.0,
00246 do_wait=True, ref_frame_name=None):
00247 '''
00248 Accept pose defined by position and RPY in Cartesian format.
00249
00250 @type joint_group: str
00251 @type position: [float]
00252 @param position: x, y, z.
00253 @type rpy: [float]
00254 @param rpy: If None, keep the current orientation by using
00255 MoveGroupCommander.set_position_target. See:
00256 http://moveit.ros.org/doxygen/classmoveit__commander_1_1move__group_1_1MoveGroupCommander.html#acfe2220fd85eeb0a971c51353e437753
00257 @param ref_frame_name: TODO: Not utilized yet. Need to be implemented.
00258 '''
00259
00260 if not self._movegr_larm or not self._movegr_rarm:
00261 try:
00262 self._init_moveit_commanders()
00263 except RuntimeError as e:
00264 rospy.logerr(self._MSG_NO_MOVEGROUP_FOUND)
00265 raise e
00266
00267
00268 movegr = None
00269 rospy.loginfo('Constant.GRNAME_LEFT_ARM={}'.format(Constant.GRNAME_LEFT_ARM))
00270 if Constant.GRNAME_LEFT_ARM == joint_group:
00271 rospy.loginfo('222')
00272 movegr = self._movegr_larm
00273 elif Constant.GRNAME_RIGHT_ARM == joint_group:
00274 movegr = self._movegr_rarm
00275 rospy.loginfo('333')
00276 else:
00277 rospy.loginfo('444')
00278
00279
00280 if not rpy:
00281 try:
00282 movegr.set_position_target(position)
00283 except MoveItCommanderException as e:
00284 rospy.logerr(str(e))
00285 return
00286
00287
00288
00289
00290 pose = copy.deepcopy(position)
00291 pose.extend(rpy)
00292 rospy.loginfo('ROS set_pose joint_group={} movegroup={} pose={} position={} rpy={}'.format(
00293 joint_group, movegr, pose, position, rpy))
00294 try:
00295 movegr.set_pose_target(pose)
00296 except MoveItCommanderException as e:
00297 rospy.logerr(str(e))
00298 except Exception as e:
00299 rospy.logerr(str(e))
00300
00301 movegr.go(do_wait) or movegr.go(do_wait) or rospy.logerr(
00302 'MoveGroup.go fails; jointgr={}'.format(joint_group))