Skip to content

Commit 423b781

Browse files
authored
Bounds on acos usages; fix a couple of links in readme (#108)
1 parent f3e28f8 commit 423b781

File tree

3 files changed

+25
-10
lines changed

3 files changed

+25
-10
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@ t = 1, 2, 3; rpy/zyx = 30, 0, 0 deg
277277

278278
For more detail checkout the shipped Python notebooks:
279279

280-
* [gentle introduction](https://github.com/bdaiinstitute/spatialmath-python/blob/master/spatialmath/gentle-introduction.ipynb)
281-
* [deeper introduction](https://github.com/bdaiinstitute/spatialmath-python/blob/master/spatialmath/introduction.ipynb)
280+
* [gentle introduction](https://github.com/bdaiinstitute/spatialmath-python/blob/master/notebooks/gentle-introduction.ipynb)
281+
* [deeper introduction](https://github.com/bdaiinstitute/spatialmath-python/blob/master/notebooks/introduction.ipynb)
282282

283283

284284
You can browse it statically through the links above, or clone the toolbox and run them interactively using [Jupyter](https://jupyter.org) or [JupyterLab](https://jupyter.org).

spatialmath/quaternion.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ def log(self) -> Quaternion:
393393
"""
394394
norm = self.norm()
395395
s = math.log(norm)
396-
v = math.acos(self.s / norm) * smb.unitvec(self.v)
396+
v = math.acos(np.clip(self.s / norm, -1, 1)) * smb.unitvec(self.v)
397397
return Quaternion(s=s, v=v)
398398

399399
def exp(self, tol: float = 20) -> Quaternion:
@@ -2242,9 +2242,9 @@ def angdist(self, other: UnitQuaternion, metric: Optional[int] = 3) -> float:
22422242
if metric == 0:
22432243
measure = lambda p, q: 1 - abs(np.dot(p, q))
22442244
elif metric == 1:
2245-
measure = lambda p, q: math.acos(abs(np.dot(p, q)))
2245+
measure = lambda p, q: math.acos(min(1.0, abs(np.dot(p, q))))
22462246
elif metric == 2:
2247-
measure = lambda p, q: math.acos(abs(np.dot(p, q)))
2247+
measure = lambda p, q: math.acos(min(1.0, abs(np.dot(p, q))))
22482248
elif metric == 3:
22492249

22502250
def metric3(p, q):
@@ -2257,7 +2257,7 @@ def metric3(p, q):
22572257

22582258
measure = metric3
22592259
elif metric == 4:
2260-
measure = lambda p, q: math.acos(2 * np.dot(p, q) ** 2 - 1)
2260+
measure = lambda p, q: math.acos(min(1.0, 2 * np.dot(p, q) ** 2 - 1))
22612261

22622262
ad = self.binop(other, measure)
22632263
if len(ad) == 1:

tests/test_quaternion.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -497,8 +497,16 @@ def test_divide(self):
497497

498498
def test_angle(self):
499499
# angle between quaternions
500-
# pure
501-
v = [5, 6, 7]
500+
uq1 = UnitQuaternion.Rx(0.1)
501+
uq2 = UnitQuaternion.Ry(0.1)
502+
for metric in range(5):
503+
self.assertEqual(uq1.angdist(other=uq1, metric=metric), 0.0)
504+
self.assertEqual(uq2.angdist(other=uq2, metric=metric), 0.0)
505+
self.assertEqual(
506+
uq1.angdist(other=uq2, metric=metric),
507+
uq2.angdist(other=uq1, metric=metric),
508+
)
509+
self.assertTrue(uq1.angdist(other=uq2, metric=metric) > 0)
502510

503511
def test_conversions(self):
504512
# , 3 angle
@@ -793,8 +801,15 @@ def log_test_exp(self):
793801
nt.assert_array_almost_equal(exp(log(q1)), q1)
794802
nt.assert_array_almost_equal(exp(log(q2)), q2)
795803

796-
# nt.assert_array_almost_equal(log(exp(q1)), q1)
797-
# nt.assert_array_almost_equal(log(exp(q2)), q2)
804+
def test_log(self):
805+
q1 = Quaternion([4, 3, 2, 1])
806+
q2 = Quaternion([-1, 2, -3, 4])
807+
808+
self.assertTrue(isscalar(q1.log().s))
809+
self.assertTrue(isvector(q1.log().v, 3))
810+
811+
nt.assert_array_almost_equal(q1.log().exp(), q1)
812+
nt.assert_array_almost_equal(q2.log().exp(), q2)
798813

799814
def test_concat(self):
800815
u = Quaternion()

0 commit comments

Comments
 (0)