Skip to content

Commit 3a8cb03

Browse files
authored
Created internal quaternion conversion function for SO3 (bdaiinstitute#119)
1 parent b16b34f commit 3a8cb03

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

spatialmath/pose3d.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434

3535
from spatialmath.twist import Twist3
3636

37+
from typing import TYPE_CHECKING
38+
if TYPE_CHECKING:
39+
from spatialmath.quaternion import UnitQuaternion
3740

3841
# ============================== SO3 =====================================#
3942

@@ -834,6 +837,29 @@ def Exp(
834837
else:
835838
return cls(smb.trexp(cast(R3, S), check=check), check=False)
836839

840+
def UnitQuaternion(self) -> UnitQuaternion:
841+
"""
842+
SO3 as a unit quaternion instance
843+
844+
:return: a unit quaternion representation
845+
:rtype: UnitQuaternion instance
846+
847+
``R.UnitQuaternion()`` is an ``UnitQuaternion`` instance representing the same rotation
848+
as the SO3 rotation ``R``.
849+
850+
Example:
851+
852+
.. runblock:: pycon
853+
854+
>>> from spatialmath import SO3
855+
>>> SO3.Rz(0.3).UnitQuaternion()
856+
857+
"""
858+
# Function level import to avoid circular dependencies
859+
from spatialmath import UnitQuaternion
860+
861+
return UnitQuaternion(smb.r2q(self.R), check=False)
862+
837863
def angdist(self, other: SO3, metric: int = 6) -> Union[float, ndarray]:
838864
r"""
839865
Angular distance metric between rotations

tests/test_pose3d.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
we will assume that the primitives rotx,trotx, etc. all work
99
"""
1010
from math import pi
11-
from spatialmath import SE3, SO3, SE2
11+
from spatialmath import SE3, SO3, SE2, UnitQuaternion
1212
import numpy as np
1313
from spatialmath.base import *
1414
from spatialmath.baseposematrix import BasePoseMatrix
@@ -233,6 +233,20 @@ def test_constructor_TwoVec(self):
233233
# x axis should equal normalized x vector
234234
nt.assert_almost_equal(R.R[:, 0], v3 / np.linalg.norm(v3), 5)
235235

236+
def test_conversion(self):
237+
R = SO3.AngleAxis(0.7, [1,2,3])
238+
q = UnitQuaternion([11,7,3,-6])
239+
240+
R_from_q = SO3(q.R)
241+
q_from_R = UnitQuaternion(R)
242+
243+
nt.assert_array_almost_equal(R.UnitQuaternion(), q_from_R)
244+
nt.assert_array_almost_equal(R.UnitQuaternion().SO3(), R)
245+
246+
nt.assert_array_almost_equal(q.SO3(), R_from_q)
247+
nt.assert_array_almost_equal(q.SO3().UnitQuaternion(), q)
248+
249+
236250
def test_shape(self):
237251
a = SO3()
238252
self.assertEqual(a._A.shape, a.shape)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy