Skip to content

Commit 307fad9

Browse files
committed
Math function for rotation between two vectors
Signed-off-by: elian-WSL22H <elian.neppel@posteo.eu>
1 parent 2c0dd5b commit 307fad9

File tree

1 file changed

+49
-2
lines changed

1 file changed

+49
-2
lines changed

roboticstoolbox/tools/urdf/urdf.py

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
import copy
1111
import os
1212
import xml.etree.ElementTree as ETT
13-
from spatialmath import SE3
14-
from spatialmath.base import unitvec_norm, angvec2r, tr2rpy
13+
from spatialmath import SE3, SO3
14+
from spatialmath.base import ArrayLike3, getvector, unitvec, unitvec_norm, angvec2r, tr2rpy
1515

1616
from io import BytesIO
1717
from roboticstoolbox.tools.data import rtb_path_to_datafile
@@ -23,6 +23,53 @@
2323
# Global variable for the base path of the robot meshes
2424
_base_path = None
2525

26+
def rotation_fromVec_toVec(
27+
from_this_vector: ArrayLike3, to_this_vector: ArrayLike3
28+
) -> SO3:
29+
"""
30+
Computes the rotation matrix from the first to the second vector.
31+
32+
Attributes
33+
----------
34+
from_this_vector: ArrayLike3
35+
to_this_vector: ArrayLike3
36+
37+
Returns
38+
-------
39+
rotation_from_to: SO3
40+
Rotation matrix
41+
42+
Notes
43+
-----
44+
Vector length is irrelevant.
45+
"""
46+
from_this_vector = getvector(from_this_vector)
47+
to_this_vector = getvector(to_this_vector)
48+
49+
is_zero = np.all(np.isclose(from_this_vector, 0))
50+
if is_zero:
51+
target_axis = to_this_vector
52+
else:
53+
target_axis = unitvec(from_this_vector)
54+
55+
dt = np.dot(target_axis, to_this_vector)
56+
crss = np.cross(target_axis, to_this_vector)
57+
58+
is_parallel = np.all(np.isclose(crss, 0))
59+
if is_parallel:
60+
rotation_plane = unitvec(
61+
np.cross(target_axis, to_this_vector + np.array([1, 1, 1]))
62+
)
63+
else:
64+
rotation_plane = unitvec(crss)
65+
66+
x = dt
67+
y = np.linalg.norm(crss)
68+
rotation_angle = np.arctan2(y, x)
69+
70+
rotation_from_to = SO3.AngVec(rotation_angle, rotation_plane)
71+
return rotation_from_to
72+
2673
def _find_standard_joint(joint: "Joint") -> "rtb.ET | None":
2774
"""
2875
Finds a pure rtb.ET joint corresponding to the URDF joint axis.

0 commit comments

Comments
 (0)