ros_client.py
Go to the documentation of this file.
00001 ## -*- coding: utf-8 -*-
00002 
00003 # Software License Agreement (BSD License)
00004 #
00005 # Copyright (c) 2014, Tokyo Opensource Robotics Kyokai Association (TORK)
00006 # All rights reserved.
00007 #
00008 # Redistribution and use in source and binary forms, with or without
00009 # modification, are permitted provided that the following conditions
00010 # are met:
00011 #
00012 #  * Redistributions of source code must retain the above copyright
00013 #    notice, this list of conditions and the following disclaimer.
00014 #  * Redistributions in binary form must reproduce the above
00015 #    copyright notice, this list of conditions and the following
00016 #    disclaimer in the documentation and/or other materials provided
00017 #    with the distribution.
00018 #  * Neither the name of Tokyo Opensource Robotics Kyokai Association. nor the
00019 #    names of its contributors may be used to endorse or promote products
00020 #    derived from this software without specific prior written permission.
00021 #
00022 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 # POSSIBILITY OF SUCH DAMAGE.
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         # left_arm, right_arm are fixed in nextage_moveit_config pkg.
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             #TODO: Throw exception; a valid group name isn't passed.
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         # Check if MoveGroup is instantiated.
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         # Locally assign the specified MoveGroup
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         # If no RPY specified, give position and return the method.
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         # Not necessary to convert from rpy to quaternion, since
00288         # MoveGroupCommander.set_pose_target can take rpy format too.
00289         # orientation_quaternion = quaternion_from_euler(rpy[0], rpy[1], rpy[2])
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))


hironx_ros_bridge
Author(s): Kei Okada
autogenerated on Mon Oct 6 2014 07:19:42