Skip to content

Commit 763d477

Browse files
authored
Improve function naming clarity and use skew_symmetric_matrix (#586)
- Replace outer_product_matrix with skew_symmetric_matrix - Rename matrix_log to rotation_matrix_to_axis_angle_vector - Rename matrix_exponent to axis_angle_vector_to_rotation_matrix - Rename midrot to interpolate_rotation_matrices - Add deprecation warnings for old function names - Update all internal usages to new function names - Update documentation to reflect changes The new names better describe what each function does, improving code readability and maintainability while preserving backward compatibility through deprecated aliases.
1 parent bcfcd21 commit 763d477

File tree

5 files changed

+171
-28
lines changed

5 files changed

+171
-28
lines changed

docs/source/reference/functions.rst

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,16 @@ Utilities functions
2020
random_rotation
2121
random_translation
2222
midpoint
23-
midrot
23+
interpolate_rotation_matrices
2424
transform
2525
rotation_matrix
2626
rotate_vector
2727
rotate_matrix
2828
rpy_matrix
2929
rpy_angle
3030
normalize_vector
31-
matrix_log
32-
matrix_exponent
33-
outer_product_matrix
31+
rotation_matrix_to_axis_angle_vector
32+
axis_angle_vector_to_rotation_matrix
3433
skew_symmetric_matrix
3534
rotation_matrix_from_rpy
3635
rotation_matrix_from_axis
@@ -97,3 +96,17 @@ Geometry functions
9796
:nosignatures:
9897

9998
rotate_points
99+
100+
101+
Deprecated Functions
102+
--------------------
103+
104+
These functions are deprecated and will be removed in future versions.
105+
Please use their replacements instead.
106+
107+
**Deprecated Functions:**
108+
109+
- :func:`~skrobot.coordinates.math.matrix_log` → Use :func:`~skrobot.coordinates.math.rotation_matrix_to_axis_angle_vector` instead
110+
- :func:`~skrobot.coordinates.math.matrix_exponent` → Use :func:`~skrobot.coordinates.math.axis_angle_vector_to_rotation_matrix` instead
111+
- :func:`~skrobot.coordinates.math.midrot` → Use :func:`~skrobot.coordinates.math.interpolate_rotation_matrices` instead
112+
- :func:`~skrobot.coordinates.math.outer_product_matrix` → Use :func:`~skrobot.coordinates.math.skew_symmetric_matrix` instead

skrobot/coordinates/base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from skrobot.coordinates.math import cross_product
1313
from skrobot.coordinates.math import matrix2quaternion
1414
from skrobot.coordinates.math import matrix2ypr
15-
from skrobot.coordinates.math import matrix_log
1615
from skrobot.coordinates.math import normalize_vector
1716
from skrobot.coordinates.math import quaternion2matrix
1817
from skrobot.coordinates.math import quaternion_multiply
@@ -21,6 +20,7 @@
2120
from skrobot.coordinates.math import rotate_matrix
2221
from skrobot.coordinates.math import rotation_angle
2322
from skrobot.coordinates.math import rotation_matrix
23+
from skrobot.coordinates.math import rotation_matrix_to_axis_angle_vector
2424
from skrobot.coordinates.math import rpy2quaternion
2525
from skrobot.coordinates.math import rpy_angle
2626
from skrobot.coordinates.math import wxyz2xyzw
@@ -969,13 +969,13 @@ def need_mirror_for_nearest_axis(coords0, coords1, ax):
969969
ax = rotation_axis[0]
970970
if not need_mirror_for_nearest_axis(self, coords, ax):
971971
rot = rotate_matrix(rot, np.pi, ax)
972-
dif_rot = matrix_log(np.matmul(self.worldrot().T, rot))
972+
dif_rot = rotation_matrix_to_axis_angle_vector(np.matmul(self.worldrot().T, rot))
973973
elif rotation_axis is False or rotation_axis is None:
974974
dif_rot = np.array([0, 0, 0])
975975
elif rotation_axis is True:
976976
dif_rotmatrix = np.matmul(self.worldrot().T,
977977
coords.worldrot())
978-
dif_rot = matrix_log(dif_rotmatrix)
978+
dif_rot = rotation_matrix_to_axis_angle_vector(dif_rotmatrix)
979979
else:
980980
raise ValueError
981981
return dif_rot

skrobot/coordinates/geo.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
from skrobot.coordinates import make_coords
44
from skrobot.coordinates.math import angle_between_vectors
55
from skrobot.coordinates.math import convert_to_axis_vector
6+
from skrobot.coordinates.math import interpolate_rotation_matrices
67
from skrobot.coordinates.math import midpoint
7-
from skrobot.coordinates.math import midrot
88
from skrobot.coordinates.math import normalize_vector
99

1010

@@ -36,7 +36,7 @@ def midcoords(p, c1, c2):
3636
array([0.05, 0. , 0. ])
3737
"""
3838
return make_coords(pos=midpoint(p, c1.worldpos(), c2.worldpos()),
39-
rot=midrot(p, c1.worldrot(), c2.worldrot()))
39+
rot=interpolate_rotation_matrices(p, c1.worldrot(), c2.worldrot()))
4040

4141

4242
def orient_coords_to_axis(target_coords, v, axis='z', eps=0.005):

skrobot/coordinates/math.py

Lines changed: 146 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
449494
def 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

490538
def 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+
10851210
def 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

11201250
def skew_symmetric_matrix(v):

skrobot/model/robot_model.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424
from skrobot.coordinates import rpy_angle
2525
from skrobot.coordinates.math import jacobian_inverse
2626
from skrobot.coordinates.math import matrix2quaternion
27-
from skrobot.coordinates.math import matrix_log
2827
from skrobot.coordinates.math import quaternion2matrix
2928
from skrobot.coordinates.math import quaternion2rpy
3029
from skrobot.coordinates.math import quaternion_inverse
3130
from skrobot.coordinates.math import quaternion_multiply
3231
from skrobot.coordinates.math import rodrigues
32+
from skrobot.coordinates.math import rotation_matrix_to_axis_angle_vector
3333
from skrobot.coordinates.math import rpy2quaternion
3434
from skrobot.model.joint import calc_dif_with_axis
3535
from skrobot.model.joint import calc_target_joint_dimension
@@ -2881,7 +2881,7 @@ def _batch_ik_step_with_constraints(
28812881

28822882
# Calculate error with original target
28832883
original_error_matrix = np.matmul(current_rot_matrix.T, target_rot_matrix)
2884-
original_error = matrix_log(original_error_matrix)
2884+
original_error = rotation_matrix_to_axis_angle_vector(original_error_matrix)
28852885
original_error_norm = np.linalg.norm(original_error)
28862886

28872887
# Calculate error with mirrored target (180° rotation around axis)
@@ -2894,7 +2894,7 @@ def _batch_ik_step_with_constraints(
28942894

28952895
mirrored_target_rot = np.matmul(target_rot_matrix, mirror_matrix)
28962896
mirrored_error_matrix = np.matmul(current_rot_matrix.T, mirrored_target_rot)
2897-
mirrored_error = matrix_log(mirrored_error_matrix)
2897+
mirrored_error = rotation_matrix_to_axis_angle_vector(mirrored_error_matrix)
28982898
mirrored_error_norm = np.linalg.norm(mirrored_error)
28992899

29002900
# Use the target orientation that gives smaller error

0 commit comments

Comments
 (0)