244 lines
8.5 KiB
Python
244 lines
8.5 KiB
Python
import argparse
|
|
import struct
|
|
import sys
|
|
import copy
|
|
|
|
import rospy
|
|
import rospkg
|
|
|
|
from gazebo_msgs.srv import (SpawnModel, DeleteModel)
|
|
from geometry_msgs.msg import (PoseStamped, Pose, Point, Quaternion)
|
|
from std_msgs.msg import (Header, Empty)
|
|
|
|
from baxter_core_msgs.srv import (SolvePositionIK, SolvePositionIKRequest)
|
|
|
|
import baxter_interface
|
|
|
|
import target_poses as tps
|
|
|
|
import tuck_arms
|
|
|
|
brickstuff = tps.brick_directions_notf
|
|
|
|
class PickAndPlace(object):
|
|
def __init__(self, limb, hover_distance = 0.10, verbose=True, speed=0.2, accuracy=baxter_interface.settings.JOINT_ANGLE_TOLERANCE):
|
|
# self._accuracy = accuracy
|
|
self._limb_name = limb # string
|
|
self._hover_distance = hover_distance # in meters
|
|
self._verbose = verbose # bool
|
|
self._limb = baxter_interface.Limb(limb)
|
|
self._gripper = baxter_interface.Gripper(limb)
|
|
ns = "ExternalTools/" + limb + "/PositionKinematicsNode/IKService"
|
|
self._iksvc = rospy.ServiceProxy(ns, SolvePositionIK)
|
|
rospy.wait_for_service(ns, 5.0)
|
|
# verify robot is enabled
|
|
print("Getting robot state... ")
|
|
self._rs = baxter_interface.RobotEnable(baxter_interface.CHECK_VERSION)
|
|
self._init_state = self._rs.state().enabled
|
|
print("Enabling robot... ")
|
|
self._rs.enable()
|
|
|
|
def move_to_start(self, start_angles=None):
|
|
print("Moving the {0} arm to start pose...".format(self._limb_name))
|
|
if not start_angles:
|
|
start_angles = dict(zip(self._joint_names, [0]*7))
|
|
self._guarded_move_to_joint_position(start_angles)
|
|
self.gripper_open()
|
|
rospy.sleep(0.2)
|
|
print("Running. Ctrl-c to quit")
|
|
|
|
def ik_request(self, pose):
|
|
hdr = Header(stamp=rospy.Time.now(), frame_id='base')
|
|
ikreq = SolvePositionIKRequest()
|
|
ikreq.pose_stamp.append(PoseStamped(header=hdr, pose=pose))
|
|
try:
|
|
resp = self._iksvc(ikreq)
|
|
except (rospy.ServiceException, rospy.ROSException), e:
|
|
rospy.logerr("Service call failed: %s" % (e,))
|
|
return False
|
|
# Check if result valid, and type of seed ultimately used to get solution
|
|
# convert rospy's string representation of uint8[]'s to int's
|
|
resp_seeds = struct.unpack('<%dB' % len(resp.result_type), resp.result_type)
|
|
limb_joints = {}
|
|
if (resp_seeds[0] != resp.RESULT_INVALID):
|
|
print()
|
|
print(ikreq.SEED_USER)
|
|
print()
|
|
seed_str = {
|
|
ikreq.SEED_USER: 'User Provided Seed',
|
|
ikreq.SEED_CURRENT: 'Current Joint Angles',
|
|
ikreq.SEED_NS_MAP: 'Nullspace Setpoints',
|
|
}.get(resp_seeds[0], 'None')
|
|
if self._verbose:
|
|
print("IK Solution SUCCESS - Valid Joint Solution Found from Seed Type: {0}".format(
|
|
(seed_str)))
|
|
# Format solution into Limb API-compatible dictionary
|
|
limb_joints = dict(zip(resp.joints[0].name, resp.joints[0].position))
|
|
if self._verbose:
|
|
print("IK Joint Solution:\n{0}".format(limb_joints))
|
|
print("------------------")
|
|
else:
|
|
rospy.logerr("INVALID POSE - No Valid Joint Solution Found.")
|
|
return False
|
|
return limb_joints
|
|
|
|
def _guarded_move_to_joint_position(self, joint_angles):
|
|
if joint_angles:
|
|
# self._limb.set_joint_position_speed(1.5)
|
|
self._limb.move_to_joint_positions(joint_angles)#, timeout=20.0, threshold=self._accuracy)
|
|
else:
|
|
rospy.logerr("No Joint Angles provided for move_to_joint_positions. Staying put.")
|
|
|
|
def gripper_open(self):
|
|
self._gripper.open()
|
|
rospy.sleep(0.2)
|
|
|
|
def gripper_close(self):
|
|
self._gripper.close()
|
|
rospy.sleep(0.2)
|
|
|
|
def _approach(self, pose):
|
|
approach = copy.deepcopy(pose)
|
|
# approach with a pose the hover-distance above the requested pose
|
|
approach.position.z = approach.position.z + self._hover_distance
|
|
joint_angles = self.ik_request(approach)
|
|
self._guarded_move_to_joint_position(joint_angles)
|
|
|
|
def _retract(self):
|
|
# retrieve current pose from endpoint
|
|
current_pose = self._limb.endpoint_pose()
|
|
ik_pose = Pose()
|
|
ik_pose.position.x = current_pose['position'].x
|
|
ik_pose.position.y = current_pose['position'].y
|
|
ik_pose.position.z = current_pose['position'].z + self._hover_distance
|
|
ik_pose.orientation.x = current_pose['orientation'].x
|
|
ik_pose.orientation.y = current_pose['orientation'].y
|
|
ik_pose.orientation.z = current_pose['orientation'].z
|
|
ik_pose.orientation.w = current_pose['orientation'].w
|
|
joint_angles = self.ik_request(ik_pose)
|
|
# servo up from current pose
|
|
self._guarded_move_to_joint_position(joint_angles)
|
|
|
|
def _servo_to_pose(self, pose):
|
|
# servo down to release
|
|
joint_angles = self.ik_request(pose)
|
|
self._guarded_move_to_joint_position(joint_angles)
|
|
|
|
def pick(self, pose):
|
|
# open the gripper
|
|
self.gripper_open()
|
|
# servo above pose
|
|
print('Approaching')
|
|
self._approach(pose)
|
|
# servo to pose
|
|
self._servo_to_pose(pose)
|
|
print('Ready to grip')
|
|
# close gripper
|
|
self.gripper_close()
|
|
print('grip')
|
|
# retract to clear object
|
|
self._retract()
|
|
|
|
def place(self, pose):
|
|
# servo above pose
|
|
self._approach(pose)
|
|
# servo to pose
|
|
self._servo_to_pose(pose)
|
|
# open the gripper
|
|
self.gripper_open()
|
|
# retract to clear object
|
|
self._retract()
|
|
|
|
|
|
brick_ids = ['b1','b2','b3','b4','b5','b6','b7','b8','b9']
|
|
|
|
with open ("brick/model.sdf", "r") as brick_file:brick_sdf=brick_file.read().replace('\n', '')
|
|
|
|
rospy.wait_for_service('/gazebo/spawn_sdf_model')
|
|
spawn_sdf = rospy.ServiceProxy('/gazebo/spawn_sdf_model', SpawnModel)
|
|
delete_model = rospy.ServiceProxy('/gazebo/delete_model', DeleteModel)
|
|
|
|
def cleanup():
|
|
for obj in brick_ids:
|
|
delete_model(obj)
|
|
|
|
|
|
# LET THE SHITSTORM BEGIN
|
|
import numpy as np
|
|
import time
|
|
|
|
def etq(roll, pitch, yaw):
|
|
qx = np.sin(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) - np.cos(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)
|
|
qy = np.cos(roll/2) * np.sin(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.cos(pitch/2) * np.sin(yaw/2)
|
|
qz = np.cos(roll/2) * np.cos(pitch/2) * np.sin(yaw/2) - np.sin(roll/2) * np.sin(pitch/2) * np.cos(yaw/2)
|
|
qw = np.cos(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)
|
|
return [qx, qy, qz, qw]
|
|
|
|
|
|
def spawn_v_brick():
|
|
brick_pose = Pose()
|
|
brick_pose.position.x = 0.475
|
|
brick_pose.position.y = 0.759
|
|
brick_pose.position.z = 0.818
|
|
QUATS = etq(0, 1.57, 1.57)
|
|
brick_pose.orientation.x = QUATS[0]
|
|
brick_pose.orientation.y = QUATS[1]
|
|
brick_pose.orientation.z = QUATS[2]
|
|
brick_pose.orientation.w = QUATS[3]
|
|
brick_reference_frame = 'world'
|
|
brick_id = brick_ids.pop()
|
|
spawn_sdf(brick_id, brick_sdf, "/", brick_pose, brick_reference_frame)
|
|
|
|
def spawn_h_brick():
|
|
brick_pose = Pose()
|
|
brick_pose.position.x = 0.4664
|
|
brick_pose.position.y = 0.8069
|
|
brick_pose.position.z = 0.7533
|
|
brick_pose.orientation.x = 0
|
|
brick_pose.orientation.y = 0
|
|
brick_pose.orientation.z = 0.707
|
|
brick_pose.orientation.w = 0.707
|
|
brick_reference_frame = 'world'
|
|
brick_id = brick_ids.pop()
|
|
spawn_sdf(brick_id, brick_sdf, "/", brick_pose, brick_reference_frame)
|
|
|
|
|
|
rospy.init_node("I_still_have_some_hope") # Am I wrong??
|
|
|
|
cleanup()
|
|
|
|
tuck_arms.init_arms()
|
|
|
|
hover_distance = 0.2
|
|
left_pnp = PickAndPlace('left', hover_distance)
|
|
|
|
## TODO: MAKE hover_distance higher for place part or solve IK collision error
|
|
|
|
spawn_v_brick()
|
|
left_pnp.pick(brickstuff[0]['pose'])
|
|
left_pnp.place(brickstuff[2]['pose'])
|
|
spawn_v_brick()
|
|
left_pnp.pick(brickstuff[0]['pose'])
|
|
left_pnp.place(brickstuff[3]['pose'])
|
|
spawn_v_brick()
|
|
left_pnp.pick(brickstuff[0]['pose'])
|
|
left_pnp.place(brickstuff[4]['pose'])
|
|
spawn_h_brick()
|
|
left_pnp.pick(brickstuff[1]['pose'])
|
|
left_pnp.place(brickstuff[5]['pose'])
|
|
spawn_h_brick()
|
|
left_pnp.pick(brickstuff[1]['pose'])
|
|
left_pnp.place(brickstuff[6]['pose'])
|
|
spawn_v_brick()
|
|
left_pnp.pick(brickstuff[0]['pose'])
|
|
left_pnp.place(brickstuff[7]['pose'])
|
|
spawn_v_brick()
|
|
left_pnp.pick(brickstuff[0]['pose'])
|
|
left_pnp.place(brickstuff[8]['pose'])
|
|
spawn_h_brick()
|
|
left_pnp.pick(brickstuff[1]['pose'])
|
|
left_pnp.place(brickstuff[9]['pose'])
|
|
spawn_v_brick()
|
|
# left_pnp.pick(brickstuff[0]['pose'])
|
|
# left_pnp.place(brickstuff[10]['pose'])
|