Inverse kinematic update to account for base rotation
This commit is contained in:
		
										
											
												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 |  | ||||||
|     r, theta = cartesian_to_polar(x, y) |  | ||||||
|  |  | ||||||
|     # Get length of each limb | 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)): | ||||||
|     l1, l2, l3 = limbs |     # 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 | ||||||
|  |      | ||||||
|  |     # Calculate base angle and r relative to shoulder joint | ||||||
|  |     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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user