Inverse kinematic update to account for base rotation
This commit is contained in:
parent
6921d5c4b4
commit
56451d3e5c
File diff suppressed because one or more lines are too long
@ -216,35 +216,65 @@ def normalize_degree(theta):
|
|||||||
# Return angle
|
# Return angle
|
||||||
return normalized_theta
|
return normalized_theta
|
||||||
|
|
||||||
def get_joints_from_xyz_rel(x, y, z, initial_guess = (math.pi/2, math.pi/2, 0), limbs=(.422864, .359041, .092124)):
|
|
||||||
# Get polar coordinates of x,y pair
|
def get_joints_from_xyz_rel(x, y, z, rx=0, ry=-math.pi/2, rz=0, initial_guess = (math.pi/2, math.pi/2, 0)):
|
||||||
r, theta = cartesian_to_polar(x, y)
|
# Get limbs and offsets
|
||||||
|
offset_x, offset_y, offset_z = (0, 0, 0.14) # Tool offset
|
||||||
|
l_bs, l1, l2, l3, l_wt = (0.1333, .425, .39225, .1267, .0997) # Limb lengths
|
||||||
|
#l3=0.15
|
||||||
|
|
||||||
# Get length of each limb
|
# Calculate base angle and r relative to shoulder joint
|
||||||
l1, l2, l3 = limbs
|
def calculate_theta(x, y, a):
|
||||||
|
# Calculate if we need the + or - in our equations
|
||||||
|
if (x>-a and y>=0) or (x>a and y<0):
|
||||||
|
flip = 1
|
||||||
|
elif (x<-a and y>=0) or (x<a and y<0):
|
||||||
|
flip = -1
|
||||||
|
else:
|
||||||
|
# Critical section (x=a, or x=-a). Infinite slope
|
||||||
|
# Return 0 or 180 depending on sign
|
||||||
|
return math.atan2(y, 0)
|
||||||
|
|
||||||
|
# Calculate tangent line y = mx + b
|
||||||
|
m = (x*y - math.sqrt(x*x*y*y-(x*x-a*a)*(y*y-a*a)))/(x*x-a*a)
|
||||||
|
b = flip * a * math.sqrt(1+m*m)
|
||||||
|
|
||||||
|
# Calculate equivalent tangent point on circle
|
||||||
|
cx = (-flip*m*b)/(1+m*m)
|
||||||
|
cy = m*cx + flip*b
|
||||||
|
|
||||||
|
# Calculate base angle, make angle negative if flip=1
|
||||||
|
theta = math.atan2(cy, cx) + (-math.pi if flip==1 else 0)
|
||||||
|
|
||||||
|
return theta
|
||||||
|
|
||||||
|
base_theta = calculate_theta(x, y, l_bs)
|
||||||
|
cx, cy = l_bs*math.cos(base_theta), l_bs*math.sin(l_bs)
|
||||||
|
r = math.sqrt((x-cx)**2 + (y-cy)**2)
|
||||||
|
|
||||||
|
|
||||||
# Formulas to find out joint positions for (r, z)
|
# Formulas to find out joint positions for (r, z)
|
||||||
def inv_kin_r_z(p):
|
def inv_kin_r_z(p):
|
||||||
a, b, c = p
|
a, b, c = p
|
||||||
|
|
||||||
return (l1*math.cos(a) + l2*math.cos(a-b) + l3*math.cos(a-b-c) - r, # r
|
return (l1*math.cos(a) + l2*math.cos(a-b) + l3*math.cos(a-b-c) - r, # r
|
||||||
l1*math.sin(a) + l2*math.sin(a-b) - l3*math.sin(a-b-c) - z, # z
|
l1*math.sin(a) + l2*math.sin(a-b) - l3*math.sin(a-b-c) - (l3*math.sin(a-b-c)) - (z + offset_z), # z
|
||||||
a-b-c) # wrist angle
|
a-b-c) # wrist angle
|
||||||
|
|
||||||
|
|
||||||
# Normalize angles
|
# Normalize angles
|
||||||
base, shoulder, elbow, wrist = [normalize_degree(deg) for deg in [theta, *fsolve(inv_kin_r_z, initial_guess)]]
|
base, shoulder, elbow, wrist1 = [normalize_degree(deg) for deg in [base_theta, *fsolve(inv_kin_r_z, initial_guess)]]
|
||||||
|
|
||||||
# Return result
|
# Return result
|
||||||
return base, shoulder, elbow, wrist
|
return base, shoulder, elbow, wrist1, ry, rz
|
||||||
|
|
||||||
def get_joints_from_xyz_abs(x, y, z):
|
def get_joints_from_xyz_abs(x, y, z, rx=0, ry=-math.pi/2, rz=math.pi/2):
|
||||||
joints = get_joints_from_xyz_rel(x, y, z)
|
joints = get_joints_from_xyz_rel(x, y, z, rx, ry, rz)
|
||||||
|
|
||||||
# Joint offsets
|
# Joint offsets
|
||||||
# Base, Shoulder, Elbow, Wrist
|
# Base, Shoulder, Elbow, Wrist
|
||||||
inverse = [1, -1, 1, 1]
|
inverse = [1, -1, 1, 1, 1, 1]
|
||||||
offsets = [0, 0, 0, -math.pi/2]
|
offsets = [-math.pi/2, 0, 0, -math.pi/2, 0, 0]
|
||||||
|
|
||||||
# Return adjusted joint positions
|
# Return adjusted joint positions
|
||||||
return [o+j*i for j, o, i in zip(joints, offsets, inverse)]
|
return [o+j*i for j, o, i in zip(joints, offsets, inverse)]
|
||||||
@ -262,7 +292,7 @@ if __name__ == "__main__":
|
|||||||
0.40002172976662786,
|
0.40002172976662786,
|
||||||
0,
|
0,
|
||||||
-3.14152741295329,
|
-3.14152741295329,
|
||||||
0]
|
math.radians(62)]
|
||||||
|
|
||||||
# time.sleep(.5)
|
# time.sleep(.5)
|
||||||
|
|
||||||
@ -290,14 +320,21 @@ if __name__ == "__main__":
|
|||||||
# set_pos_abs(*home_pose)
|
# set_pos_abs(*home_pose)
|
||||||
|
|
||||||
|
|
||||||
angles = get_joints_from_xyz_abs(0.3, 0.3, 0.3)
|
|
||||||
rob.movej([*angles, *rob.getj()[4:]], acc=1, vel=1)
|
|
||||||
|
|
||||||
angles = get_joints_from_xyz_abs(-0.3, -0.3, 0.7)
|
angles = get_joints_from_xyz_abs(-0.7, 0, 0)
|
||||||
rob.movej([*angles, *rob.getj()[4:]], acc=1, vel=1)
|
rob.movej(angles, acc=2, vel=2)
|
||||||
|
|
||||||
|
# joints = []
|
||||||
|
# for i in np.linspace(-0.3, -0.7, 50):
|
||||||
|
# joints.append(get_joints_from_xyz_abs(i, 0, 0))
|
||||||
|
# rob.movejs(joints, acc=2, vel=2)
|
||||||
|
|
||||||
|
# time.sleep(5)
|
||||||
|
|
||||||
|
|
||||||
|
# angles = get_joints_from_xyz_abs(0, -0.6, 0)
|
||||||
|
# rob.movej(angles, acc=2, vel=2)
|
||||||
|
|
||||||
angles = get_joints_from_xyz_abs(-0.3, 0.4, 0.2)
|
|
||||||
rob.movej([*angles, *rob.getj()[4:]], acc=1, vel=1)
|
|
||||||
|
|
||||||
|
|
||||||
# set_pos_abs(*p1)
|
# set_pos_abs(*p1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user