35 from geometry_msgs.msg
import Pose, PoseStamped
36 from moveit_msgs.msg
import RobotTrajectory, Grasp, PlaceLocation, Constraints, RobotState
37 from moveit_msgs.msg
import MoveItErrorCodes, TrajectoryConstraints, PlannerInterfaceDescription
38 from sensor_msgs.msg
import JointState
41 from moveit_ros_planning_interface
import _moveit_move_group_interface
42 from .exception
import MoveItCommanderException
48 Execution of simple commands for a particular group
51 def __init__(self, name, robot_description="robot_description", ns="", wait_for_servers=5.0):
52 """ Specify the group name for which to construct this commander instance. Throws an exception if there is an initialization error. """
53 self.
_g = _moveit_move_group_interface.MoveGroupInterface(name, robot_description, ns, wait_for_servers)
56 """ Get the name of the group this instance was initialized for """
60 """ Stop the current execution, if any """
64 """ Get the active joints of this group """
68 """ Get the joints of this group """
72 """ Return the number of variables used to parameterize a state in this group (larger or equal to number of DOF)"""
76 """ Check if this group has a link that is considered to be an end effector """
80 """ Get the name of the link that is considered to be an end-effector. Return an empty string if there is no end-effector. """
84 """ Set the name of the link to be considered as an end effector """
89 """ Get the description of the planner interface (list of planner ids) """
90 desc = PlannerInterfaceDescription()
95 """ Get the reference frame assumed for poses of end-effectors """
99 """ Set the reference frame to assume for poses of end-effectors """
103 """ Get the name of the frame where all planning is performed """
107 """ Get the current configuration of the group as a list (these are values published on /joint_states) """
111 """ Get the current pose of the end-effector of the group. Throws an exception if there is not end-effector. """
118 """ Get a list of 3 elements defining the [roll, pitch, yaw] of the end-effector. Throws an exception if there is not end-effector. """
138 Specify a start state for the group.
142 msg : moveit_msgs/RobotState
146 >>> from moveit_msgs.msg import RobotState
147 >>> from sensor_msgs.msg import JointState
148 >>> joint_state = JointState()
149 >>> joint_state.header = Header()
150 >>> joint_state.header.stamp = rospy.Time.now()
151 >>> joint_state.name = ['joint_a', 'joint_b']
152 >>> joint_state.position = [0.17, 0.34]
153 >>> moveit_robot_state = RobotState()
154 >>> moveit_robot_state.joint_state = joint_state
155 >>> group.set_start_state(moveit_robot_state)
160 """ Get the current state of the robot bounded."""
163 conversions.msg_from_string(s, c_str)
167 """ Get the current state of the robot."""
170 conversions.msg_from_string(s, c_str)
178 Specify a target joint configuration for the group.
179 - if the type of arg1 is one of the following: dict, list, JointState message, then no other arguments should be provided.
180 The dict should specify pairs of joint variable names and their target values, the list should specify all the variable values
181 for the group. The JointState message specifies the positions of some single-dof joints.
182 - if the type of arg1 is string, then arg2 is expected to be defined and be either a real value or a list of real values. This is
183 interpreted as setting a particular joint to a particular value.
184 - if the type of arg1 is Pose or PoseStamped, both arg2 and arg3 could be defined. If arg2 or arg3 are defined, their types must
185 be either string or bool. The string type argument is interpreted as the end-effector the pose is specified for (default is to use
186 the default end-effector), and the bool is used to decide whether the pose specified is approximate (default is false). This situation
187 allows setting the joint target of the group by calling IK. This does not send a pose to the planner and the planner will do no IK.
188 Instead, one IK solution will be computed first, and that will be sent to the planner.
190 if isinstance(arg1, RobotState):
191 if not self.
_g.set_state_value_target(conversions.msg_to_string(arg1)):
194 elif isinstance(arg1, JointState):
195 if (arg2
is not None or arg3
is not None):
197 if not self.
_g.set_joint_value_target_from_joint_state_message(conversions.msg_to_string(arg1)):
200 elif isinstance(arg1, str):
203 if (arg3
is not None):
208 elif isinstance(arg1, (Pose, PoseStamped)):
211 if (arg2
is not None):
212 if type(arg2)
is str:
215 if type(arg2)
is bool:
219 if (arg3
is not None):
220 if type(arg3)
is str:
223 if type(arg3)
is bool:
228 if type(arg1)
is PoseStamped:
229 r = self.
_g.set_joint_value_target_from_pose_stamped(conversions.msg_to_string(arg1), eef, approx)
231 r = self.
_g.set_joint_value_target_from_pose(conversions.msg_to_string(arg1), eef, approx)
238 elif (hasattr(arg1,
'__iter__')):
239 if (arg2
is not None or arg3
is not None):
248 """ Specify a target orientation for the end-effector. Any position of the end-effector is acceptable."""
259 """ Specify a target orientation for the end-effector. Any position of the end-effector is acceptable."""
270 """ Specify a target position for the end-effector. Any orientation of the end-effector is acceptable."""
278 """ 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:"""
279 """ [x, y, z, rot_x, rot_y, rot_z] or a list of 7 floats [x, y, z, qx, qy, qz, qw] """
282 if type(pose)
is PoseStamped:
285 ok = self.
_g.
set_pose_target(conversions.pose_to_list(pose.pose), end_effector_link)
287 elif type(pose)
is Pose:
297 """ 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] """
299 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):
305 """ 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 """
311 (r, p, y) = tf.transformations.euler_from_quaternion(pose[3:])
312 pose = [pose[0], pose[1], pose[2], r, p, y]
313 if axis >= 0
and axis < 6:
314 pose[axis] = pose[axis] + value
322 """ Clear the pose target for a particular end-effector """
326 """ Clear all known pose targets """
330 """ Set a random joint configuration target """
334 """ Get a list of all the names of joint configurations."""
338 """ 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. """
343 """Get a dictionary of joint values of a named target"""
347 """ 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. """
353 """ Get a dictionary that maps names to joint configurations for the group """
357 """ Forget a stored joint configuration """
361 """ Return a tuple of goal tolerances: joint, position and orientation. """
365 """ Get the tolerance for achieving a joint goal (distance for each joint variable) """
369 """ 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 """
373 """ 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 """
377 """ Set the joint, position and orientation goal tolerances simultaneously """
381 """ Set the tolerance for a target joint configuration """
385 """ Set the tolerance for a target end-effector position """
389 """ Set the tolerance for a target end-effector orientation """
393 """ Enable/disable looking around for motion planning """
397 """ Enable/disable replanning """
401 """ Get a list of names for the constraints specific for this group, as read from the warehouse """
405 """ Get the acutal path constraints in form of a moveit_msgs.msgs.Constraints """
408 conversions.msg_from_string(c, c_str)
412 """ Specify the path constraints to be used (as read from the database) """
416 if type(value)
is Constraints:
417 self.
_g.set_path_constraints_from_msg(conversions.msg_to_string(value))
422 """ Specify that no path constraints are to be used during motion planning """
426 """ Get the actual trajectory constraints in form of a moveit_msgs.msgs.Constraints """
429 conversions.msg_from_string(c, c_str)
433 """ Specify the trajectory constraints to be used """
437 if type(value)
is TrajectoryConstraints:
438 self.
_g.set_trajectory_constraints_from_msg(conversions.msg_to_string(value))
443 """ Specify that no trajectory constraints are to be used during motion planning """
447 """ Specify which database to connect to for loading possible path constraints """
451 """ Specify the amount of time to be used for motion planning. """
455 """ Specify the amount of time to be used for motion planning. """
459 """ Specify which planner to use when motion planning """
463 """ Get the current planner_id """
467 """ Set the number of times the motion plan is to be computed from scratch before the shortest solution is returned. The default value is 1. """
471 """ Set the workspace for the robot as either [], [minX, minY, maxX, maxY] or [minX, minY, minZ, maxX, maxY, maxZ] """
484 """ Set a scaling factor to reduce the maximum joint velocities. Allowed values are in (0,1].
485 The default value is set in the joint_limits.yaml of the moveit_config package. """
486 if value > 0
and value <= 1:
492 """ Set a scaling factor to reduce the maximum joint accelerations. Allowed values are in (0,1].
493 The default value is set in the joint_limits.yaml of the moveit_config package. """
494 if value > 0
and value <= 1:
499 def go(self, joints=None, wait=True):
500 """ Set the target of the group and then move the group to the specified target """
501 if type(joints)
is bool:
505 elif type(joints)
is JointState:
508 elif type(joints)
is Pose:
511 elif joints
is not None:
517 return self.
_g.move()
519 return self.
_g.async_move()
522 """ Return a tuple of the motion planning results such as
523 (success flag : boolean, trajectory message : RobotTrajectory,
524 planning time : float, error code : MoveitErrorCodes) """
525 if type(joints)
is JointState:
528 elif type(joints)
is Pose:
531 elif joints
is not None:
534 except MoveItCommanderException:
537 (error_code_msg, trajectory_msg, planning_time) = self.
_g.
plan()
539 error_code = MoveItErrorCodes()
540 error_code.deserialize(error_code_msg)
541 plan = RobotTrajectory()
542 return (error_code.val == MoveItErrorCodes.SUCCESS,
543 plan.deserialize(trajectory_msg),
548 """ 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; Kinematic constraints for the path given by path_constraints will be met for every point along the trajectory, if they are not met, a partial solution will be returned. The return value is a tuple: a fraction of how much of the path was followed, the actual RobotTrajectory. """
550 if type(path_constraints)
is Constraints:
551 constraints_str = conversions.msg_to_string(path_constraints)
554 (ser_path, fraction) = self.
_g.
compute_cartesian_path([conversions.pose_to_list(p)
for p
in waypoints], eef_step, jump_threshold, avoid_collisions, constraints_str)
556 (ser_path, fraction) = self.
_g.
compute_cartesian_path([conversions.pose_to_list(p)
for p
in waypoints], eef_step, jump_threshold, avoid_collisions)
558 path = RobotTrajectory()
559 path.deserialize(ser_path)
560 return (path, fraction)
563 """Execute a previously planned path"""
565 return self.
_g.
execute(conversions.msg_to_string(plan_msg))
567 return self.
_g.async_execute(conversions.msg_to_string(plan_msg))
570 """ Given the name of an object existing in the planning scene, attach it to a link. The link used is specified by the second argument. If left unspecified, the end-effector link is used, if one is known. If there is no end-effector link, the first link in the group is used. If no link is identified, failure is reported. True is returned if an attach request was succesfully sent to the move_group node. This does not verify that the attach request also was successfuly applied by move_group."""
574 """ Given the name of a link, detach the object(s) from that link. If no such link exists, the name is interpreted as an object name. If there is no name specified, an attempt is made to detach all objects attached to any link in the group."""
577 def pick(self, object_name, grasp=[], plan_only=False):
578 """Pick the named object. A grasp message, or a list of Grasp messages can also be specified as argument."""
579 if type(grasp)
is Grasp:
580 return self.
_g.
pick(object_name, conversions.msg_to_string(grasp), plan_only)
582 return self.
_g.
pick(object_name, [conversions.msg_to_string(x)
for x
in grasp], plan_only)
584 def place(self, object_name, location=None, plan_only=False):
585 """Place the named object at a particular location in the environment or somewhere safe in the world if location is not provided"""
588 result = self.
_g.
place(object_name, plan_only)
589 elif type(location)
is PoseStamped:
592 result = self.
_g.
place(object_name, conversions.pose_to_list(location.pose), plan_only)
594 elif type(location)
is Pose:
595 result = self.
_g.
place(object_name, conversions.pose_to_list(location), plan_only)
596 elif type(location)
is PlaceLocation:
597 result = self.
_g.
place(object_name, conversions.msg_to_string(location), plan_only)
598 elif type(location)
is list:
600 if type(location[0])
is PlaceLocation:
601 result = self.
_g.place_locations_list(object_name, [conversions.msg_to_string(x)
for x
in location], plan_only)
602 elif type(location[0])
is PoseStamped:
603 result = self.
_g.place_poses_list(object_name, [conversions.msg_to_string(x)
for x
in location], plan_only)
605 raise MoveItCommanderException(
"Parameter location must be a Pose, PoseStamped, PlaceLocation, list of PoseStamped or list of PlaceLocation object")
607 raise MoveItCommanderException(
"Parameter location must be a Pose, PoseStamped, PlaceLocation, list of PoseStamped or list of PlaceLocation object")
611 """ Set the support surface name for a place operation """
614 def retime_trajectory(self, ref_state_in, traj_in, velocity_scaling_factor=1.0, acceleration_scaling_factor=1.0, algorithm="iterative_time_parameterization"):
615 ser_ref_state_in = conversions.msg_to_string(ref_state_in)
616 ser_traj_in = conversions.msg_to_string(traj_in)
617 ser_traj_out = self.
_g.
retime_trajectory(ser_ref_state_in, ser_traj_in, velocity_scaling_factor, acceleration_scaling_factor, algorithm)
618 traj_out = RobotTrajectory()
619 traj_out.deserialize(ser_traj_out)
623 """ Get the jacobian matrix of the group as a list"""
624 return self.
_g.
get_jacobian_matrix(joint_values, [0.0, 0.0, 0.0]
if reference_point
is None else reference_point)
627 """ Takes a moveit_msgs RobotState and enforces the state bounds, based on the C++ RobotState enforceBounds() """
630 conversions.msg_from_string(s, c_str)