|
| 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