2 # -*- coding: iso-8859-15 -*-
7 import moveit_commander
11 from geometry_msgs.msg import PoseStamped
12 from moveit_msgs.msg import PlanningScene, ObjectColor
13 from moveit_msgs.msg import Grasp, GripperTranslation
14 from moveit_msgs.msg import MoveItErrorCodes
15 from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
16 from tf.transformations import quaternion_from_euler
20 # Initialize the move_group API
21 moveit_commander.roscpp_initialize(sys.argv)
23 rospack = rospkg.RosPack()
24 rospy.init_node('moveit_demo')
26 self.tflistener = tf.TransformListener()
27 scene = moveit_commander.PlanningSceneInterface()
28 # Create a scene publisher to push changes to the scene
29 self.scene_pub = rospy.Publisher('planning_scene', PlanningScene, queue_size=16)
30 self.gripper_pose_pub = rospy.Publisher('gripper_pose', PoseStamped)
31 self.arm = moveit_commander.MoveGroupCommander("arm")
32 self.arm.set_planner_id("RRTkConfigDefault");
33 self.gripper = moveit_commander.MoveGroupCommander("gripper")
35 scene.remove_world_object("tube1")
36 scene.remove_attached_object("gripper_center", "tube1")
37 self.arm.set_goal_position_tolerance(0.04)
38 self.arm.set_goal_orientation_tolerance(5*pi/180)
41 self.arm.set_named_target('Home')
44 tube1_pose = PoseStamped()
45 tube1_pose.header.frame_id = "/arm_base"
46 tube1_pose.pose.position.x = 0.5
47 tube1_pose.pose.position.y = 0.0
48 tube1_pose.pose.position.z = 0.03
49 tube1_pose.pose.orientation.w = 1.0
50 scene.add_mesh("tube1", tube1_pose, rospack.get_path('arm_ros_conn') + "/meshes/vrohr.stl")
51 self.setColor("tube1", 1.0, 1.0, 0, 1.0)
53 place_pose = PoseStamped()
54 place_pose.header.frame_id = "/arm_base"
55 place_pose.pose.position.x = -0.5
56 place_pose.pose.position.y = 0.0
57 place_pose.pose.position.z = 0.03
58 place_pose.pose.orientation.w = 1.0
60 rospy.sleep(2) # Give the scene a chance to catch up
62 tube1_pose.pose.position.z += 0.02
63 if self.pick("tube1", tube1_pose):
64 rospy.sleep(2) # Give the scene a chance to catch up
65 self.place("tube1", place_pose)
66 rospy.sleep(2) # Give the scene a chance to catch up
68 self.arm.set_named_target('Home')
70 rospy.sleep(2) # Give the scene a chance to catch up
72 if self.pick("tube1", place_pose):
73 rospy.sleep(2) # Give the scene a chance to catch up
74 self.place("tube1", tube1_pose)
75 rospy.sleep(2) # Give the scene a chance to catch up
77 # Shut down MoveIt cleanly
78 moveit_commander.roscpp_shutdown()
81 moveit_commander.os._exit(0)
83 def pick(self, item, pose):
84 # Generate a list of grasps
85 grasps = self.make_grasps(pose, [item], [5*pi/180] * 2)
87 self.gripper_pose_pub.publish(grasp.grasp_pose)
89 # Repeat until we succeed or run out of attempts
91 rospy.loginfo("Pick attempt: " + str(i))
92 result = self.arm.pick(item, grasps)
93 if result == MoveItErrorCodes.SUCCESS:
94 rospy.loginfo("Pick succeeded")
96 rospy.loginfo("Pick failed")
101 def place(self, item, place_pose):
102 # Generate valid place poses
103 # Rotate the gripper around the z axis to let it point to the target, reference is the x axis
104 v = place_pose.pose.position.__getstate__()[:2] # x, y component of position
105 v /= np.linalg.norm(v) # unit vector
106 q = quaternion_from_euler(0, 0, acos(np.dot(v, [1, 0]))) # use the dot product to get the angle
107 place_pose.pose.orientation.x = q[0]
108 place_pose.pose.orientation.y = q[1]
109 place_pose.pose.orientation.z = q[2]
110 place_pose.pose.orientation.w = q[3]
112 # Publish the place pose so they it be viewed in RViz
113 self.gripper_pose_pub.publish(place_pose)
117 rospy.loginfo("Place attempt: " + str(i))
118 if self.arm.place(item, place_pose):
119 rospy.loginfo("Place succeeded")
123 def gripper_to(self, to):
124 self.gripper.set_joint_value_target([to, to])
127 def gripper_open(self):
128 self.gripper.set_named_target('open')
131 def grasp_tube(self):
132 self.gripper_to(0.05)
134 # See http://wiki.ros.org/turtlebot_arm_interactive_markers/Tutorials/UsingArmInteractiveMarkers?action=AttachFile&do=get&target=arm_markers_rviz6.jpgt the color of an object
135 def setColor(self, name, r, g, b, a=0.9):
136 # Initialize a MoveIt color object
137 color = ObjectColor()
139 # Set the id to the name given as an argument
142 # Set the rgb and alpha values given as input
148 # Initialize a planning scene object
150 # Need to publish a planning scene diff
152 p.object_colors.append(color)
153 # Publish the scene diff
154 self.scene_pub.publish(p)
156 # Get the gripper posture as a JointTrajectory
157 def make_gripper_posture(self, joint_positions):
158 # Initialize the joint trajectory for the gripper joints
159 t = JointTrajectory()
161 # Set the joint names to the gripper joint names
162 t.joint_names = ["left_gripper_joint", "right_gripper_joint"]
164 # Initialize a joint trajectory point to represent the goal
165 tp = JointTrajectoryPoint()
167 # Assign the trajectory joint positions to the input positions
168 tp.positions = joint_positions
170 # Set the gripper effort
171 tp.effort = [1.0, 1.0]
173 tp.time_from_start = rospy.Duration(2.0)
175 # Append the goal point to the trajectory points
178 # Return the joint trajectory
181 # Generate a gripper translation in the direction given by vector
182 def make_gripper_translation(self, min_dist, desired, vector):
183 # Initialize the gripper translation object
184 g = GripperTranslation()
186 # Set the direction vector components to the input
187 g.direction.vector.x = vector[0]
188 g.direction.vector.y = vector[1]
189 g.direction.vector.z = vector[2]
191 # The vector is relative to the gripper frame
192 g.direction.header.frame_id = "gripper_center"
194 # Assign the min and desired distances from the input
195 g.min_distance = min_dist
196 g.desired_distance = desired
200 # Generate a list of possible grasps
201 def make_grasps(self, initial_pose_stamped, allowed_touch_objects, grasp_opening=[0, 0]):
202 # Initialize the grasp object
205 # Set the pre-grasp and grasp postures appropriately;
206 # grasp_opening should be a bit smaller than target width
207 g.pre_grasp_posture = self.make_gripper_posture([0.35, 0.35])
208 g.grasp_posture = self.make_gripper_posture(grasp_opening)
210 # Set the approach and retreat parameters as desired
211 g.pre_grasp_approach = self.make_gripper_translation(0.05, 0.1, [1.0, 0.0, 0.0])
212 g.post_grasp_retreat = self.make_gripper_translation(0.05, 0.1, [0.0, 0.0, 1.0])
214 # Set the first grasp pose to the input pose
215 g.grasp_pose = initial_pose_stamped
217 # A list to hold the grasps
220 # Rotate the gripper around the z axis to let it point to the target, reference is the x axis
221 v = initial_pose_stamped.pose.position.__getstate__()[:2] # x, y component of position
222 v /= np.linalg.norm(v) # unit vector
223 q = quaternion_from_euler(0, 0, acos(np.dot(v, [1, 0]))) # use the dot product to get the angle
225 # Set the grasp pose orientation accordingly
226 g.grasp_pose.pose.orientation.x = q[0]
227 g.grasp_pose.pose.orientation.y = q[1]
228 g.grasp_pose.pose.orientation.z = q[2]
229 g.grasp_pose.pose.orientation.w = q[3]
231 # Set and id for this grasp (simply needs to be unique)
232 g.id = str(len(grasps))
234 # Set the allowed touch objects to the input list
235 g.allowed_touch_objects = allowed_touch_objects
237 # Don't restrict contact force
238 g.max_contact_force = 0
240 # Degrade grasp quality for increasing pitch angles
241 g.grasp_quality = 1.0
243 # Append the grasp to the list
249 if __name__ == "__main__":