Skip to content

Commit 6b759e0

Browse files
committed
Normalize twist poles by squared angular magnitude
1 parent 2de7801 commit 6b759e0

2 files changed

Lines changed: 37 additions & 2 deletions

File tree

‎spatialmath/twist.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ def pole(self):
986986
>>> S = Twist3(T)
987987
>>> S.pole
988988
"""
989-
return np.cross(self.w, self.v) / self.theta
989+
return np.cross(self.w, self.v) / np.dot(self.w, self.w)
990990

991991
def SE3(self, theta=1, unit="rad"):
992992
"""
@@ -1500,7 +1500,7 @@ def pole(self):
15001500
>>> S.pole()
15011501
15021502
"""
1503-
p = np.cross(np.r_[0, 0, self.w], np.r_[self.v, 0]) / self.theta
1503+
p = np.cross(np.r_[0, 0, self.w], np.r_[self.v, 0]) / self.w**2
15041504
return p[:2]
15051505

15061506
# ------------------------- methods -------------------------------#

‎tests/test_twist_pole.py‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import numpy as np
2+
import pytest
3+
from scipy.linalg import expm
4+
5+
from spatialmath import Twist2, Twist3
6+
7+
8+
@pytest.mark.parametrize("speed", [-2.0, -0.3, 0.3, 1.0, 2.0])
9+
def test_twist2_pole_is_rotation_center(speed):
10+
"""A change in angular speed must not move the center of rotation."""
11+
center = np.array([3.0, -2.0])
12+
twist = Twist2(speed * np.r_[center[1], -center[0], 1])
13+
np.testing.assert_allclose(twist.pole, center)
14+
transform = expm(twist.skewa() * 0.7)
15+
np.testing.assert_allclose(
16+
transform @ np.r_[twist.pole, 1], np.r_[center, 1], atol=1e-14
17+
)
18+
19+
20+
@pytest.mark.parametrize("speed", [-2.0, -0.3, 0.3, 1.0, 2.0])
21+
@pytest.mark.parametrize("pitch", [0, 0.4])
22+
def test_twist3_pole_is_on_screw_axis(speed, pitch):
23+
"""The closest axis point is fixed except for translation along the axis."""
24+
axis = np.array([1.0, 2.0, -2.0]) / 3
25+
center = np.array([3.0, -2.0, 1.0])
26+
center -= (center @ axis) * axis
27+
angular = speed * axis
28+
linear = -np.cross(angular, center) + pitch * angular
29+
twist = Twist3(linear, angular)
30+
np.testing.assert_allclose(twist.pole, center)
31+
transform = expm(twist.skewa() * 0.7)
32+
expected = center + pitch * angular * 0.7
33+
np.testing.assert_allclose(
34+
(transform @ np.r_[twist.pole, 1])[:3], expected, atol=1e-14
35+
)

0 commit comments

Comments
 (0)