@@ -446,9 +446,57 @@ def midpoint(p, a, b):
446446 return a + (b - a ) * p
447447
448448
449+ def interpolate_rotation_matrices (p , r1 , r2 ):
450+ """Interpolate between two rotation matrices.
451+
452+ Performs spherical linear interpolation (SLERP) between two rotation
453+ matrices. This gives a smooth rotation path from r1 to r2.
454+
455+ Parameters
456+ ----------
457+ p : float
458+ Interpolation parameter in [0, 1]. When p=0, returns r1.
459+ When p=1, returns r2. When p=0.5, returns the midpoint rotation.
460+ r1 : numpy.ndarray
461+ Starting 3x3 rotation matrix
462+ r2 : numpy.ndarray
463+ Ending 3x3 rotation matrix
464+
465+ Returns
466+ -------
467+ r : numpy.ndarray
468+ Interpolated 3x3 rotation matrix
469+
470+ Examples
471+ --------
472+ >>> import numpy as np
473+ >>> from skrobot.coordinates.math import interpolate_rotation_matrices
474+ >>> interpolate_rotation_matrices(0.5,
475+ np.eye(3),
476+ np.array([[0, 0, 1], [0, 1, 0], [-1, 0, 0]]))
477+ array([[ 0.70710678, 0. , 0.70710678],
478+ [ 0. , 1. , 0. ],
479+ [-0.70710678, 0. , 0.70710678]])
480+ >>> from skrobot.coordinates.math import matrix2ypr
481+ >>> np.rad2deg(matrix2ypr(interpolate_rotation_matrices(0.5,
482+ np.eye(3),
483+ np.array([[0, 0, 1], [0, 1, 0], [-1, 0, 0]]))))
484+ array([ 0., 45., 0.])
485+ """
486+ r1 = _check_valid_rotation (r1 )
487+ r2 = _check_valid_rotation (r2 )
488+ r = np .matmul (r1 .T , r2 )
489+ omega = rotation_matrix_to_axis_angle_vector (r )
490+ r = axis_angle_vector_to_rotation_matrix (omega , p )
491+ return np .matmul (r1 , r )
492+
493+
449494def midrot (p , r1 , r2 ):
450495 """Returns mid (or p) rotation matrix of given two matrix r1 and r2.
451496
497+ .. deprecated::
498+ This function is deprecated. Use `interpolate_rotation_matrices` instead.
499+
452500 Parameters
453501 ----------
454502 p : float
@@ -479,12 +527,12 @@ def midrot(p, r1, r2):
479527 np.array([[0, 0, 1], [0, 1, 0], [-1, 0, 0]])))[0])
480528 array([ 0., 45., 0.])
481529 """
482- r1 = _check_valid_rotation ( r1 )
483- r2 = _check_valid_rotation ( r2 )
484- r = np . matmul ( r1 . T , r2 )
485- omega = matrix_log ( r )
486- r = matrix_exponent ( omega , p )
487- return np . matmul ( r1 , r )
530+ warnings . warn (
531+ 'Function `midrot` is deprecated. '
532+ 'Please use `interpolate_rotation_matrices` instead' ,
533+ DeprecationWarning ,
534+ stacklevel = 2 )
535+ return interpolate_rotation_matrices ( p , r1 , r2 )
488536
489537
490538def transform (m , v ):
@@ -1050,8 +1098,11 @@ def quaternion2matrix(q, normalize=False):
10501098 return m
10511099
10521100
1053- def matrix_log (m ):
1054- """Returns matrix log of given rotation matrix, it returns [-pi, pi]
1101+ def rotation_matrix_to_axis_angle_vector (m ):
1102+ """Convert rotation matrix to axis-angle representation as a vector.
1103+
1104+ The magnitude of the returned vector represents the rotation angle,
1105+ and its direction represents the rotation axis.
10551106
10561107 Parameters
10571108 ----------
@@ -1060,14 +1111,16 @@ def matrix_log(m):
10601111
10611112 Returns
10621113 -------
1063- matrixlog : numpy.ndarray
1064- vector of shape (3, )
1114+ axis_angle_vector : numpy.ndarray
1115+ Axis-angle representation as a vector of shape (3,).
1116+ The vector's magnitude is the rotation angle in radians [-pi, pi],
1117+ and its direction is the rotation axis.
10651118
10661119 Examples
10671120 --------
10681121 >>> import numpy as np
1069- >>> from skrobot.coordinates.math import matrix_log
1070- >>> matrix_log (np.eye(3))
1122+ >>> from skrobot.coordinates.math import rotation_matrix_to_axis_angle_vector
1123+ >>> rotation_matrix_to_axis_angle_vector (np.eye(3))
10711124 array([0., 0., 0.])
10721125 """
10731126 # calc logarithm of quaternion
@@ -1082,9 +1135,84 @@ def matrix_log(m):
10821135 return theta * normalize_vector (q_xyz )
10831136
10841137
1138+ def matrix_log (m ):
1139+ """Returns matrix log of given rotation matrix, it returns [-pi, pi]
1140+
1141+ .. deprecated::
1142+ This function is deprecated. Use `rotation_matrix_to_axis_angle_vector` instead.
1143+
1144+ Parameters
1145+ ----------
1146+ m : list or numpy.ndarray
1147+ 3x3 rotation matrix
1148+
1149+ Returns
1150+ -------
1151+ matrixlog : numpy.ndarray
1152+ vector of shape (3, )
1153+
1154+ Examples
1155+ --------
1156+ >>> import numpy as np
1157+ >>> from skrobot.coordinates.math import matrix_log
1158+ >>> matrix_log(np.eye(3))
1159+ array([0., 0., 0.])
1160+ """
1161+ warnings .warn (
1162+ 'Function `matrix_log` is deprecated. '
1163+ 'Please use `rotation_matrix_to_axis_angle_vector` instead' ,
1164+ DeprecationWarning ,
1165+ stacklevel = 2 )
1166+ return rotation_matrix_to_axis_angle_vector (m )
1167+
1168+
1169+ def axis_angle_vector_to_rotation_matrix (omega , p = 1.0 ):
1170+ """Convert axis-angle vector representation to rotation matrix.
1171+
1172+ Converts an axis-angle representation (where the vector direction
1173+ is the rotation axis and magnitude is the rotation angle) to a
1174+ rotation matrix using Rodrigues' formula.
1175+
1176+ Parameters
1177+ ----------
1178+ omega : list or numpy.ndarray
1179+ Axis-angle vector of shape (3,). The direction represents
1180+ the rotation axis and the magnitude represents the rotation
1181+ angle in radians.
1182+ p : float, optional
1183+ Interpolation parameter (default: 1.0). When p=1.0, returns
1184+ the full rotation. When 0<p<1, returns partial rotation.
1185+
1186+ Returns
1187+ -------
1188+ rot : numpy.ndarray
1189+ 3x3 rotation matrix
1190+
1191+ Examples
1192+ --------
1193+ >>> import numpy as np
1194+ >>> from skrobot.coordinates.math import axis_angle_vector_to_rotation_matrix
1195+ >>> axis_angle_vector_to_rotation_matrix([1, 1, 1])
1196+ array([[ 0.22629564, -0.18300792, 0.95671228],
1197+ [ 0.95671228, 0.22629564, -0.18300792],
1198+ [-0.18300792, 0.95671228, 0.22629564]])
1199+ >>> axis_angle_vector_to_rotation_matrix([1, 0, 0])
1200+ array([[ 1. , 0. , 0. ],
1201+ [ 0. , 0.54030231, -0.84147098],
1202+ [ 0. , 0.84147098, 0.54030231]])
1203+ """
1204+ w = np .linalg .norm (omega )
1205+ amat = skew_symmetric_matrix (normalize_vector (omega ))
1206+ return np .eye (3 ) + np .sin (w * p ) * amat + \
1207+ (1.0 - np .cos (w * p )) * np .matmul (amat , amat )
1208+
1209+
10851210def matrix_exponent (omega , p = 1.0 ):
10861211 """Returns exponent of given omega.
10871212
1213+ .. deprecated::
1214+ This function is deprecated. Use `axis_angle_vector_to_rotation_matrix` instead.
1215+
10881216 This function is similar to cv2.Rodrigues.
10891217 Convert rvec (which is log quaternion) to rotation matrix.
10901218
@@ -1111,10 +1239,12 @@ def matrix_exponent(omega, p=1.0):
11111239 [ 0. , 0.54030231, -0.84147098],
11121240 [ 0. , 0.84147098, 0.54030231]])
11131241 """
1114- w = np .linalg .norm (omega )
1115- amat = skew_symmetric_matrix (normalize_vector (omega ))
1116- return np .eye (3 ) + np .sin (w * p ) * amat + \
1117- (1.0 - np .cos (w * p )) * np .matmul (amat , amat )
1242+ warnings .warn (
1243+ 'Function `matrix_exponent` is deprecated. '
1244+ 'Please use `axis_angle_vector_to_rotation_matrix` instead' ,
1245+ DeprecationWarning ,
1246+ stacklevel = 2 )
1247+ return axis_angle_vector_to_rotation_matrix (omega , p )
11181248
11191249
11201250def skew_symmetric_matrix (v ):
0 commit comments