move_group.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 # Copyright (c) 2012, Willow Garage, Inc.
00004 # All rights reserved.
00005 #
00006 # Redistribution and use in source and binary forms, with or without
00007 # modification, are permitted provided that the following conditions
00008 # are met:
00009 #
00010 #  * Redistributions of source code must retain the above copyright
00011 #    notice, this list of conditions and the following disclaimer.
00012 #  * Redistributions in binary form must reproduce the above
00013 #    copyright notice, this list of conditions and the following
00014 #    disclaimer in the documentation and/or other materials provided
00015 #    with the distribution.
00016 #  * Neither the name of Willow Garage, Inc. nor the names of its
00017 #    contributors may be used to endorse or promote products derived
00018 #    from this software without specific prior written permission.
00019 #
00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 # POSSIBILITY OF SUCH DAMAGE.
00032 #
00033 # Author: Ioan Sucan
00034 
00035 from geometry_msgs.msg import Pose, PoseStamped
00036 from sensor_msgs.msg import JointState
00037 import rospy
00038 import tf
00039 from moveit_ros_planning_interface import _moveit_move_group_interface
00040 from exception import MoveItCommanderException
00041 import conversions
00042 
00043 class MoveGroupCommander(object):
00044     """
00045     Execution of simple commands for a particular group
00046     """
00047 
00048     def __init__(self, name):
00049         """ Specify the group name for which to construct this commander instance. Throws an exception if there is an initialization error. """
00050         self._g = _moveit_move_group_interface.MoveGroup(name, "robot_description")
00051 
00052     def get_name(self):
00053         """ Get the name of the group this instance was initialized for """
00054         return self._g.get_name()
00055 
00056     def stop(self):
00057         """ Stop the current execution, if any """
00058         self._g.stop()
00059 
00060     def get_joints(self):
00061         """ Get the joints of this group """
00062         return self._g.get_joints()
00063 
00064     def get_variable_count(self):
00065         """ Return the number of variables used to parameterize a state in this group (larger or equal to number of DOF)"""
00066         return self._g.get_variable_count()
00067 
00068     def has_end_effector_link(self):
00069         """ Check if this group has a link that is considered to be an end effector """
00070         return len(self._g.get_end_effector_link()) > 0
00071 
00072     def get_end_effector_link(self):
00073         """ Get the name of the link that is considered to be an end-effector. Return an empty string if there is no end-effector. """
00074         return self._g.get_end_effector_link()
00075 
00076     def set_end_effector_link(self, link_name):
00077         """ Set the name of the link to be considered as an end effector """
00078         if not self._g.set_end_effector_link(link_name):
00079             raise MoveItCommanderException("Unable to set end efector link")
00080 
00081     def get_pose_reference_frame(self):
00082         """ Get the reference frame assumed for poses of end-effectors """
00083         return self._g.get_pose_reference_frame()
00084 
00085     def set_pose_reference_frame(self, reference_frame):
00086         """ Set the reference frame to assume for poses of end-effectors """
00087         self._g.set_pose_reference_frame(reference_frame)
00088     
00089     def get_planning_frame(self):
00090         """ Get the name of the frame where all planning is performed """
00091         return self._g.get_planning_frame()
00092 
00093     def get_current_joint_values(self):
00094         """ Get the current configuration of the group (as published on JointState) """
00095         return self._g.get_current_joint_values()
00096 
00097     def get_current_pose(self, end_effector_link = ""):
00098         """ Get the current pose of the end-effector of the group. Throws an exception if there is not end-effector. """
00099         if len(end_effector_link) > 0 or self.has_end_effector_link():
00100             return conversions.list_to_pose_stamped(self._g.get_current_pose(end_effector_link), self.get_planning_frame())
00101         else:
00102             raise MoveItCommanderException("There is no end effector to get the pose of")
00103 
00104     def get_current_rpy(self, end_effector_link = ""):
00105         """ Get a list of 3 elements defining the [roll, pitch, yaw] of the end-effector. Throws an exception if there is not end-effector. """
00106         if len(end_effector_link) > 0 or self.has_end_effector_link():
00107             return self._g.get_current_rpy(end_effector_link)
00108         else:
00109             raise MoveItCommanderException("There is no end effector to get the rpy of")
00110 
00111     def get_random_joint_values(self):
00112         return self._g.get_random_joint_values()
00113 
00114     def get_random_pose(self, end_effector_link = ""):
00115         if len(end_effector_link) > 0 or self.has_end_effector_link():
00116             return conversions.list_to_pose_stamped(self._g.get_random_pose(end_effector_link), self.get_planning_frame())
00117         else:
00118             raise MoveItCommanderException("There is no end effector to get the pose of")
00119 
00120     def set_joint_value_target(self, name, value = None):
00121         """ Specify a target joint configuration for the group."""
00122         if value == None:
00123             value = name
00124             if not self._g.set_joint_value_target(value):
00125                 raise MoveItCommanderException("Error setting joint target. Is the target within bounds?")
00126         else:
00127             if not self._g.set_joint_value_target(name, value):
00128                 raise MoveItCommanderException("Error setting joint target. Is the target within bounds?")
00129 
00130     def set_rpy_target(self, rpy, end_effector_link = ""):
00131         """ Specify a target orientation for the end-effector. Any position of the end-effector is acceptable."""
00132         if len(end_effector_link) > 0 or self.has_end_effector_link():
00133             if len(rpy) == 3:
00134                 if not self._g.set_rpy_target(rpy[0], rpy[1], rpy[2], end_effector_link):
00135                     raise MoveItCommanderException("Unable to set orientation target")
00136             else:
00137                 raise MoveItCommanderException("Expected [roll, pitch, yaw]")
00138         else:
00139             raise MoveItCommanderException("There is no end effector to set the pose for")
00140 
00141     def set_orientation_target(self, q, end_effector_link = ""):
00142         """ Specify a target orientation for the end-effector. Any position of the end-effector is acceptable."""
00143         if len(end_effector_link) > 0 or self.has_end_effector_link():
00144             if len(q) == 4:
00145                 if not self._g.set_orientation_target(q[0], q[1], q[2], q[3], end_effector_link):
00146                     raise MoveItCommanderException("Unable to set orientation target")
00147             else:
00148                 raise MoveItCommanderException("Expected [qx, qy, qz, qw]")
00149         else:
00150             raise MoveItCommanderException("There is no end effector to set the pose for")
00151 
00152     def set_position_target(self, xyz, end_effector_link = ""):
00153         """ Specify a target position for the end-effector. Any orientation of the end-effector is acceptable."""
00154         if len(end_effector_link) > 0 or self.has_end_effector_link():
00155             if not self._g.set_position_target(xyz[0], xyz[1], xyz[2], end_effector_link):
00156                 raise MoveItCommanderException("Unable to set position target")
00157         else:
00158             raise MoveItCommanderException("There is no end effector to set the pose for")
00159 
00160     def set_pose_target(self, pose, end_effector_link = ""):
00161         """ Set the pose of the end-effector, if one is available. The expected input is a Pose message, a PoseStamped message or a list of 6 floats:"""
00162         """ [x, y, z, rot_x, rot_y, rot_z] or a list of 7 floats [x, y, z, qx, qy, qz, qw] """
00163         if len(end_effector_link) > 0 or self.has_end_effector_link():
00164             ok = False
00165             if type(pose) is PoseStamped:
00166                 old = self.get_pose_reference_frame()
00167                 self.set_pose_reference_frame(pose.header.frame_id)
00168                 ok = self._g.set_pose_target(conversions.pose_to_list(pose.pose), end_effector_link)
00169                 self.set_pose_reference_frame(old)
00170             elif type(pose) is Pose:
00171                 ok = self._g.set_pose_target(conversions.pose_to_list(pose), end_effector_link)
00172             else:
00173                 ok = self._g.set_pose_target(pose, end_effector_link)
00174             if not ok:
00175                 raise MoveItCommanderException("Unable to set target pose")
00176         else:
00177             raise MoveItCommanderException("There is no end effector to set the pose for")
00178 
00179     def set_pose_targets(self, poses, end_effector_link = ""):
00180         """ Set the pose of the end-effector, if one is available. The expected input is a list of poses. Each pose can be a Pose message, a list of 6 floats: [x, y, z, rot_x, rot_y, rot_z] or a list of 7 floats [x, y, z, qx, qy, qz, qw] """
00181         if len(end_effector_link) > 0 or self.has_end_effector_link():
00182             if not self._g.set_pose_targets([conversions.pose_to_list(p) if type(p) is Pose else p for p in poses], end_effector_link):
00183                 raise MoveItCommanderException("Unable to set target poses")
00184         else:
00185             raise MoveItCommanderException("There is no end effector to set poses for")
00186 
00187     def shift_pose_target(self, axis, value, end_effector_link = ""):
00188         """ Get the current pose of the end effector, add value to the corresponding axis (0..5: X, Y, Z, R, P, Y) and set the new pose as the pose target """
00189         if len(end_effector_link) > 0 or self.has_end_effector_link():
00190             pose = self._g.get_current_pose(end_effector_link)
00191             # by default we get orientation as a quaternion list
00192             # if we are updating a rotation axis however, we convert the orientation to RPY
00193             if axis > 2:
00194                 (r, p, y) = tf.transformations.euler_from_quaternion(pose[3:])
00195                 pose = [pose[0], pose[1], pose[2], r, p, y]
00196             if axis >= 0 and axis < 6:
00197                 pose[axis] = pose[axis] + value
00198                 self.set_pose_target(pose, end_effector_link)
00199             else:
00200                 raise MoveItCommanderException("An axis value between 0 and 5 expected")
00201         else:
00202             raise MoveItCommanderException("There is no end effector to set poses for")
00203 
00204     def clear_pose_target(self, end_effector_link):
00205         """ Clear the pose target for a particular end-effector """
00206         self._g.clear_pose_target(end_effector_link)
00207         
00208     def clear_pose_targets(self):
00209         """ Clear all known pose targets """
00210         self._g.clear_pose_targets()
00211 
00212     def set_random_target(self):
00213         """ Set a random joint configuration target """
00214         self._g.set_random_target()
00215 
00216     def set_named_target(self, name):
00217         """ Set a joint configuration by name. The name can be a name previlusy remembered with remember_joint_values() or a configuration specified in the SRDF. """
00218         if not self._g.set_named_target(name):
00219             raise MoveItCommanderException("Unable to set target %s. Is the target within bounds?" % name)
00220 
00221     def remember_joint_values(self, name, values = None):
00222         """ Record the specified joint configuration of the group under the specified name. If no values are specified, the current state of the group is recorded. """
00223         if values == None:
00224             values = self.get_current_joint_values()
00225         self._g.remember_joint_values(name, values)
00226 
00227     def get_remembered_joint_values(self):
00228         """ Get a dictionary that maps names to joint configurations for the group """
00229         return self._g.get_remembered_joint_values()
00230     
00231     def forget_joint_values(self, name):
00232         """ Forget a stored joint configuration """
00233         self._g.forget_joint_values(name)
00234 
00235     def get_goal_tolerance(self):
00236         """ Return a tuple of goal tolerances: joint, position and orientation. """
00237         return (self.get_goal_joint_tolerance(), self.get_goal_position_tolerance(), self.get_goal_orientation_tolerance())
00238 
00239     def get_goal_joint_tolerance(self):
00240         """ Get the tolerance for achieving a joint goal (distance for each joint variable) """
00241         return self._g.get_goal_joint_tolerance()
00242 
00243     def get_goal_position_tolerance(self):
00244         """ When moving to a position goal or to a pose goal, the tolerance for the goal position is specified as the radius a sphere around the target origin of the end-effector """
00245         return self._g.get_goal_position_tolerance()
00246 
00247     def get_goal_orientation_tolerance(self):
00248         """ When moving to an orientation goal or to a pose goal, the tolerance for the goal orientation is specified as the distance (roll, pitch, yaw) to the target origin of the end-effector """
00249         return self._g.get_goal_orientation_tolerance()
00250 
00251     def set_goal_tolerance(self, value):
00252         """ Set the joint, position and orientation goal tolerances simultaneously """
00253         self._g.set_goal_tolerance(value)
00254 
00255     def set_goal_joint_tolerance(self, value):
00256         """ Set the tolerance for a target joint configuration """
00257         self._g.set_goal_joint_tolerance(value)
00258 
00259     def set_goal_position_tolerance(self, value):
00260         """ Set the tolerance for a target end-effector position """
00261         self._g.set_goal_position_tolerance(value)
00262 
00263     def set_goal_orientation_tolerance(self, value):
00264         """ Set the tolerance for a target end-effector orientation """
00265         self._g.set_goal_orientation_tolerance(value)
00266 
00267     def allow_looking(self, value):
00268         """ Enable/disable looking around for motion planning """
00269         self._g.allow_looking(value)
00270 
00271     def allow_replanning(self, value):
00272         """ Enable/disable replanning """
00273         self._g.allow_replanning(value)
00274         
00275     def get_known_constraints(self):
00276         """ Get a list of names for the constraints specific for this group, as read from the warehouse """
00277         return self._g.get_known_constraints()
00278 
00279     def set_path_constraints(self, value):
00280         """ Specify the path constraints to be used (as read from the database) """
00281         if value == None:
00282             self.clear_path_constraints()
00283         else:
00284             if not self._g.set_path_constraints(value):
00285                 raise MoveItCommanderException("Unable to set path constraints " + value)
00286 
00287     def clear_path_constraints(self):
00288         """ Specify that no path constraints are to be used during motion planning """
00289         self._g.clear_path_constraints()
00290 
00291     def set_constraints_database(self, host, port):
00292         """ Specify which database to connect to for loading possible path constraints """
00293         self._g.set_constraints_database(host, port)
00294 
00295     def set_planning_time(self, seconds):
00296         """ Specify the amount of time to be used for motion planning. """
00297         self._g.set_planning_time(seconds)
00298 
00299     def get_planning_time(self):
00300         """ Specify the amount of time to be used for motion planning. """
00301         return self._g.get_planning_time()
00302 
00303     def set_planner_id(self, planner_id):
00304         """ Specify which planner to use when motion planning """
00305         self._g.set_planner_id(planner_id)
00306 
00307     def set_workspace(self, ws):
00308         """ Set the workspace for the robot as either [], [minX, minY, maxX, maxY] or [minX, minY, minZ, maxX, maxY, maxZ] """
00309         if len(ws) == 0:
00310             self._g.set_workspace(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
00311         else:
00312             if len(ws) == 4:
00313                 self._g.set_workspace(ws[0], ws[1], 0.0, ws[2], ws[3], 0.0)
00314             else:
00315                 if len(ws) == 6:
00316                     self._g.set_workspace(ws[0], ws[1], ws[2], ws[3], ws[4], ws[5])
00317                 else:
00318                     raise MoveItCommanderException("Expected 0, 4 or 6 values in list specifying workspace")
00319 
00320     def go(self, joints = None, wait = True):
00321         """ Set the target of the group and then move the group to the specified target """
00322         if type(joints) is bool:
00323             wait = joints
00324             joints = None
00325 
00326         elif type(joints) is JointState:
00327             self.set_joint_value_target(joints.position)
00328 
00329         elif type(joints) is Pose:
00330             self.set_pose_target(joints)
00331 
00332         elif not joints == None:
00333             try:
00334                 self.set_joint_value_target(self.get_remembered_joint_values()[joints])
00335             except:
00336                 self.set_joint_value_target(joints)
00337         if wait:
00338             return self._g.move()
00339         else:
00340             return self._g.async_move()
00341 
00342     def plan(self, joints = None):
00343         """ Return a motion plan (a RobotTrajectory) to the set goal state (or specified by the joints argument) """
00344         if type(joints) is JointState:
00345             self.set_joint_value_target(joints.position)
00346 
00347         elif type(joints) is Pose:
00348             self.set_pose_target(joints)
00349 
00350         elif not joints == None:
00351             try:
00352                 self.set_joint_value_target(self.get_remembered_joint_values()[joints])
00353             except:
00354                 self.set_joint_value_target(joints)
00355         plan = self._g.compute_plan()
00356         return conversions.dict_to_trajectory(plan)
00357 
00358     def compute_cartesian_path(self, waypoints, eef_step, jump_threshold, avoid_collisions = True):
00359         """ Compute a sequence of waypoints that make the end-effector move in straight line segments that follow the poses specified as waypoints. Configurations are computed for every eef_step meters; The jump_threshold specifies the maximum distance in configuration space between consecutive points in the resultingpath. The return value is a tuple: a fraction of how much of the path was followed, the actual RobotTrajectory. """
00360         (dpath, fraction) = self._g.compute_cartesian_path([conversions.pose_to_list(p) for p in waypoints], eef_step, jump_threshold, avoid_collisions)
00361         return (conversions.dict_to_trajectory(dpath), fraction)
00362 
00363     def execute(self, plan_msg):
00364         """Execute a previously planned path"""
00365         return self._g.execute(conversions.trajectory_to_dict(plan_msg))
00366 
00367     def pick(self, object_name):
00368         """Pick the named object"""
00369         return self._g.pick(object_name)
00370 
00371     def place(self, object_name, pose):
00372         """Place the named object at a particular location in the environment"""
00373         result = False
00374         if type(pose) is PoseStamped:
00375             old = self.get_pose_reference_frame()
00376             self.set_pose_reference_frame(pose.header.frame_id)
00377             result = self._g.place(object_name, conversions.pose_to_list(pose.pose))
00378             self.set_pose_reference_frame(old)
00379         else:
00380             result = self._g.place(object_name, conversions.pose_to_list(pose))
00381         return result


moveit_commander
Author(s): Ioan Sucan
autogenerated on Mon Oct 6 2014 02:24:45