def rpy_mat(r, p, y):
cr, sr, cp, sp, cy, sy = np.cos(r), np.sin(r), np.cos(p), np.sin(p), np.cos(y), np.sin(y)
return np.array([[cy*cp, cy*sp*sr - sy*cr, cy*sp*cr + sy*sr],
[sy*cp, sy*sp*sr + cy*cr, sy*sp*cr - cy*sr],
[-sp, cp*sr, cp*cr]])
def axis_mat(a, q):
"Rodrigues rotation about unit axis a by angle q."
a = a / np.linalg.norm(a)
x, y, z = a
c, s = np.cos(q), np.sin(q)
C = 1 - c
return np.array([[x*x*C + c, x*y*C - z*s, x*z*C + y*s],
[y*x*C + z*s, y*y*C + c, y*z*C - x*s],
[z*x*C - y*s, z*y*C + x*s, z*z*C + c]])
def T_of(R, p):
T = np.eye(4); T[:3, :3] = R; T[:3, 3] = p
return T
def fk(q_arm, target_link, jaw=0.0):
"Pose (4x4) of `target_link` in the base frame for arm joint vector q_arm (rad)."
T = np.eye(4)
for jn in chain_to(target_link):
j = joints[jn]
T = T @ T_of(rpy_mat(*j["rpy"]), j["xyz"])
if j["type"] == "revolute" and jn in ARM_JOINTS:
T = T @ T_of(axis_mat(j["axis"], q_arm[ARM_JOINTS.index(jn)]), [0, 0, 0])
elif j["type"] == "prismatic":
T = T @ T_of(np.eye(3), j["axis"] * jaw)
return T
def grasp_center(q_arm, jaw=0.014):
"Midpoint between the two gripper jaws, the natural 'tool center point'."
pts = [fk(q_arm, joints[jj]["child"], jaw)[:3, 3] for jj in JAWS]
return np.mean(pts, axis=0)
HOME = np.array([0.0, -0.3, 0.5, 0.0, 1.2, 0.0]) # the project's home pose
print("link_6 position at home: ", fk(HOME, "link_6")[:3, 3])
print("grasp center (jaw midpoint): ", grasp_center(HOME))