Skip to content

Commit

Permalink
Add slerp function (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnwason authored Jul 18, 2023
1 parent 98e04ef commit d0f94aa
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/general_robotics_toolbox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .general_robotics_toolbox import hat, invhat, rot, R2rot, screw_matrix, q2R, R2q, q2rot, rot2q, quatcomplement, \
quatproduct, quatjacobian, rpy2R, R2rpy, Robot, Transform, fwdkin, robotjacobian, subproblem0, subproblem1, \
subproblem2, subproblem3, subproblem4, apply_robot_aux_transforms, unapply_robot_aux_transforms, \
identity_transform, random_R, random_p, random_transform
identity_transform, random_R, random_p, random_transform, slerp

from .general_robotics_toolbox_invkin import robot6_sphericalwrist_invkin, ur_invkin, equivalent_configurations, \
iterative_invkin
Expand All @@ -12,5 +12,5 @@
'quatproduct', 'quatjacobian', 'rpy2R', 'R2rpy', 'Robot', 'Transform', 'fwdkin', 'robotjacobian', 'subproblem0',
'subproblem1', 'subproblem2', 'subproblem3', 'subproblem4', 'apply_robot_aux_transforms',
'unapply_robot_aux_transforms', 'identity_transform', 'random_R', 'random_p', 'random_transform',
'robot6_sphericalwrist_invkin', 'ur_invkin', 'equivalent_configurations', 'iterative_invkin']
'robot6_sphericalwrist_invkin', 'ur_invkin', 'equivalent_configurations', 'iterative_invkin', 'slerp']

32 changes: 32 additions & 0 deletions src/general_robotics_toolbox/general_robotics_toolbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,38 @@ def R2rpy(R):

return (r,p,y)

# Add slerp function using [w,x,y,z] quaternion representation (github copilot)
def slerp(q0, q1, t):
"""
Spherical linear interpolation between two quaternions
:type q0: numpy.array
:param q0: 4 x 1 vector representation of a quaternion q = [q0;qv]
:type q1: numpy.array
:param q1: 4 x 1 vector representation of a quaternion q = [q0;qv]
:type t: number
:param t: interpolation parameter in the range [0,1]
:rtype: numpy.array
:returns: the 4 x 1 interpolated quaternion
"""

assert (t >= 0 and t <= 1), "t must be in the range [0,1]"

q0 = q0/np.linalg.norm(q0)
q1 = q1/np.linalg.norm(q1)

if (np.dot(q0,q1) < 0):
q0 = -q0

theta = np.arccos(np.dot(q0,q1))

if (np.abs(theta) < 1e-6):
return q0

q = (np.sin((1-t)*theta)*q0 + np.sin(t*theta)*q1)/np.sin(theta)

return q/np.linalg.norm(q)

class Robot(object):
"""
Holds the kinematic information for a single chain robot
Expand Down
29 changes: 29 additions & 0 deletions test/test_general_robotics_toolbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,35 @@ def test_rpy2R():
rox.R2rpy(R3)


def _test_slerp_params(k1,theta1,k2,theta2,t):
R1 = rox.rot(k1, theta1)
R2 = rox.rot(k2, theta2)

q1 = rox.R2q(R1)
q2 = rox.R2q(R2)

R1_2 = R1.T @ R2
k,theta = rox.R2rot(R1_2)

R_t = R1 @ rox.rot(k, theta*t)
q_t = rox.slerp(q1, q2, t)
R_qt = rox.q2R(q_t)

np.testing.assert_allclose(R_t, R_qt)

q_t2 = rox.slerp(q1, -q2, t)
R_qt2 = rox.q2R(q_t2)

np.testing.assert_allclose(R_t, R_qt2)

def test_slerp():
_test_slerp_params([0.53436371, 0.24406035, 0.80925273], -4.643,
[-0.71076104, 0.57683297, 0.40259467], 0.25945178, 0.72)
_test_slerp_params([0,0,1],0,[0,0,1],1e-7,0.5)
_test_slerp_params([0,0,1],1.82,[1,0,0],18.7,0.76)



def test_fwdkin():

#TODO: other joint types
Expand Down

0 comments on commit d0f94aa

Please sign in to comment.