Skip to content

Commit

Permalink
the util
Browse files Browse the repository at this point in the history
  • Loading branch information
Ipuch committed Aug 16, 2023
1 parent 8d9dda8 commit 85a87c2
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 124 deletions.
8 changes: 1 addition & 7 deletions bionc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,7 @@
from .bionc_numpy.homogenous_transform import HomogeneousTransform

from .utils.enums import NaturalAxis, CartesianAxis, EulerSequence

from casadi.casadi import MX as MX_type
from numpy import ndarray

# global variable to store the type of the math interface
casadi_type = MX_type
numpy_type = ndarray
from .utils.transformation_matrix import TransformationMatrixUtil

from .vizualization import Viz
from .bionc_numpy import InverseKinematics
58 changes: 0 additions & 58 deletions bionc/bionc_casadi/transformation_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,61 +144,3 @@ def _transformation_matrix_Bvw(length: float, alpha: float, beta: float, gamma:
def _transformation_matrix_Bwv(length: float, alpha: float, beta: float, gamma: float) -> MX:
raise NotImplementedError("The transformation matrix Bwv is not implemented yet.")


def from_plane_and_axis_to_keep(plane: tuple[NaturalAxis, NaturalAxis], axis_to_keep: NaturalAxis):
"""
Create a transformation matrix from a plane and an axis to keep
Parameters
----------
plane: tuple[NaturalAxis, NaturalAxis]
The plane to define the cross product of the orthogonal axis (axis[0] x axis[1])
axis_to_keep:
The axis to keep in the plane
Returns
-------
"""
check_plane(plane)
check_axis_to_keep(axis_to_keep)

if NaturalAxis.U in plane and NaturalAxis.V in plane:
if axis_to_keep == NaturalAxis.U:
return transformation_matrix(TransformationMatrixType.Buv)
elif axis_to_keep == NaturalAxis.V:
return transformation_matrix(TransformationMatrixType.Bvu)

elif NaturalAxis.U in plane and NaturalAxis.W in plane:
if axis_to_keep == NaturalAxis.U:
raise NotImplementedError("The transformation matrix Buw is not implemented yet.")
elif axis_to_keep == NaturalAxis.W:
return transformation_matrix(TransformationMatrixType.Bwu)

elif NaturalAxis.V in plane and NaturalAxis.W in plane:
if axis_to_keep == NaturalAxis.V:
raise NotImplementedError("The transformation matrix Bvw is not implemented yet.")
elif axis_to_keep == NaturalAxis.W:
raise NotImplementedError("The transformation matrix Bwv is not implemented yet.")


def check_plane(plane: tuple[NaturalAxis, NaturalAxis]):
"""Check if the plane is valid"""
if len(plane) != 2:
raise ValueError(f"Plane must be a tuple of length 2, got {len(plane)}")
if not all(isinstance(axis, NaturalAxis) for axis in plane):
raise ValueError(f"Plane must be a tuple of NaturalAxis, got {plane}")
if plane[0] == plane[1]:
raise ValueError(f"Plane must be a tuple of different axis, got {plane}")
if (
(plane[0] == NaturalAxis.V and plane[1] == NaturalAxis.U)
or (plane[0] == NaturalAxis.U and plane[1] == NaturalAxis.W)
or (plane[0] == NaturalAxis.W and plane[1] == NaturalAxis.V)
):
raise ValueError(f"Invert Axis in plane, because it would lead to an indirect frame, got {plane}")


def check_axis_to_keep(axis_to_keep: NaturalAxis):
"""Check if the axis to keep is valid"""
if not isinstance(axis_to_keep, NaturalAxis):
raise ValueError(f"Axis to keep must be of type NaturalAxis, got {axis_to_keep}")
58 changes: 0 additions & 58 deletions bionc/bionc_numpy/transformation_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,61 +142,3 @@ def _transformation_matrix_Bvw(length: float, alpha: float, beta: float, gamma:
def _transformation_matrix_Bwv(length: float, alpha: float, beta: float, gamma: float) -> np.ndarray:
raise NotImplementedError("The transformation matrix Bwv is not implemented yet.")


def from_plane_and_axis_to_keep(plane: tuple[NaturalAxis, NaturalAxis], axis_to_keep: NaturalAxis):
"""
Create a transformation matrix from a plane and an axis to keep
Parameters
----------
plane: tuple[NaturalAxis, NaturalAxis]
The plane to define the cross product of the orthogonal axis (axis[0] x axis[1])
axis_to_keep:
The axis to keep in the plane
Returns
-------
"""
check_plane(plane)
check_axis_to_keep(axis_to_keep)

if NaturalAxis.U in plane and NaturalAxis.V in plane:
if axis_to_keep == NaturalAxis.U:
return transformation_matrix(TransformationMatrixType.Buv)
elif axis_to_keep == NaturalAxis.V:
return transformation_matrix(TransformationMatrixType.Bvu)

elif NaturalAxis.U in plane and NaturalAxis.W in plane:
if axis_to_keep == NaturalAxis.U:
raise NotImplementedError("The transformation matrix Buw is not implemented yet.")
elif axis_to_keep == NaturalAxis.W:
return transformation_matrix(TransformationMatrixType.Bwu)

elif NaturalAxis.V in plane and NaturalAxis.W in plane:
if axis_to_keep == NaturalAxis.V:
raise NotImplementedError("The transformation matrix Bvw is not implemented yet.")
elif axis_to_keep == NaturalAxis.W:
raise NotImplementedError("The transformation matrix Bwv is not implemented yet.")


def check_plane(plane: tuple[NaturalAxis, NaturalAxis]):
"""Check if the plane is valid"""
if len(plane) != 2:
raise ValueError(f"Plane must be a tuple of length 2, got {len(plane)}")
if not all(isinstance(axis, NaturalAxis) for axis in plane):
raise ValueError(f"Plane must be a tuple of NaturalAxis, got {plane}")
if plane[0] == plane[1]:
raise ValueError(f"Plane must be a tuple of different axis, got {plane}")
if (
(plane[0] == NaturalAxis.V and plane[1] == NaturalAxis.U)
or (plane[0] == NaturalAxis.U and plane[1] == NaturalAxis.W)
or (plane[0] == NaturalAxis.W and plane[1] == NaturalAxis.V)
):
raise ValueError(f"Invert Axis in plane, because it would lead to an indirect frame, got {plane}")


def check_axis_to_keep(axis_to_keep: NaturalAxis):
"""Check if the axis to keep is valid"""
if not isinstance(axis_to_keep, NaturalAxis):
raise ValueError(f"Axis to keep must be of type NaturalAxis, got {axis_to_keep}")
81 changes: 81 additions & 0 deletions bionc/utils/transformation_matrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from .enums import NaturalAxis, TransformationMatrixType


class TransformationMatrixUtil:
"""
A utility class to get the corresponding TransformationMatrixType from a plane and an axis to keep
to build the orthogonal segment coordinate system.
It requires a plane (tuple of NaturalAxis) and an axis to keep (NaturalAxis).
The two axes of the plane are used to perform a cross product to get the third axis.
The kept axis is equivalent in the orthogonal segment coordinate system and the natural coordinate system.
For example, if the plane is (NaturalAxis.U, NaturalAxis.V) and the axis to keep is NaturalAxis.U,
the corresponding TransformationMatrixType is Buv.
Methods
-------
to_enum()
Get the corresponding TransformationMatrixType from the plane and the axis to keep.
"""
def __init__(self,
plane: tuple[NaturalAxis, NaturalAxis],
axis_to_keep: NaturalAxis
):
check_plane(plane)
check_axis_to_keep(axis_to_keep)

self.plane = plane
self.axis_to_keep = axis_to_keep
"""
Set the plane and the axis to keep.
Parameters
----------
plane : tuple[NaturalAxis, NaturalAxis]
The plane to use to build the orthogonal segment coordinate system.
axis_to_keep : NaturalAxis
The axis to keep in the orthogonal segment coordinate system.
"""

def to_enum(self) -> TransformationMatrixType:
if NaturalAxis.U in self.plane and NaturalAxis.V in self.plane:
if self.axis_to_keep == NaturalAxis.U:
return TransformationMatrixType.Buv
elif self.axis_to_keep == NaturalAxis.V:
return TransformationMatrixType.Bvu

elif NaturalAxis.U in self.plane and NaturalAxis.W in self.plane:
if self.axis_to_keep == NaturalAxis.U:
return TransformationMatrixType.Buw
elif self.axis_to_keep == NaturalAxis.W:
return TransformationMatrixType.Bwu

elif NaturalAxis.V in self.plane and NaturalAxis.W in self.plane:
if self.axis_to_keep == NaturalAxis.V:
return TransformationMatrixType.Bvw
elif self.axis_to_keep == NaturalAxis.W:
return TransformationMatrixType.Bwv


def check_plane(plane: tuple[NaturalAxis, NaturalAxis]):
"""Check if the plane is valid"""
if len(plane) != 2:
raise ValueError(f"Plane must be a tuple of length 2, got {len(plane)}")
if not all(isinstance(axis, NaturalAxis) for axis in plane):
raise ValueError(f"Plane must be a tuple of NaturalAxis, got {plane}")
if plane[0] == plane[1]:
raise ValueError(f"Plane must be a tuple of different axis, got {plane}")
if (
(plane[0] == NaturalAxis.V and plane[1] == NaturalAxis.U)
or (plane[0] == NaturalAxis.U and plane[1] == NaturalAxis.W)
or (plane[0] == NaturalAxis.W and plane[1] == NaturalAxis.V)
):
raise ValueError(f"Invert Axis in plane, because it would lead to an indirect frame, got {plane}")


def check_axis_to_keep(axis_to_keep: NaturalAxis):
"""Check if the axis to keep is valid"""
if not isinstance(axis_to_keep, NaturalAxis):
raise ValueError(f"Axis to keep must be of type NaturalAxis, got {axis_to_keep}")
39 changes: 38 additions & 1 deletion tests/test_transformation_matrix.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from bionc.bionc_numpy.transformation_matrix import check_plane, transformation_matrix
from bionc.bionc_numpy.transformation_matrix import transformation_matrix
from bionc.utils.enums import TransformationMatrixType
from bionc import NaturalAxis
from bionc.utils.transformation_matrix import check_plane, TransformationMatrixUtil, check_axis_to_keep
import numpy as np
import pytest
from .utils import TestUtils
Expand Down Expand Up @@ -142,3 +143,39 @@ def test_segment_transformation_matrix(bionc_type):

with pytest.raises(ValueError):
bbox.transformation_matrix(matrix_type="INVALID_TYPE")


def test_transformation_matrix_util():
tm = TransformationMatrixUtil((NaturalAxis.U, NaturalAxis.V), NaturalAxis.U)
assert tm.to_enum() == TransformationMatrixType.Buv

tm = TransformationMatrixUtil((NaturalAxis.W, NaturalAxis.U), NaturalAxis.W)
assert tm.to_enum() == TransformationMatrixType.Bwu

tm = TransformationMatrixUtil((NaturalAxis.V, NaturalAxis.W), NaturalAxis.V)
assert tm.to_enum() == TransformationMatrixType.Bvw

tm = TransformationMatrixUtil((NaturalAxis.U, NaturalAxis.V), NaturalAxis.V)
assert tm.to_enum() == TransformationMatrixType.Bvu

tm = TransformationMatrixUtil((NaturalAxis.W, NaturalAxis.U), NaturalAxis.U)
assert tm.to_enum() == TransformationMatrixType.Buw

tm = TransformationMatrixUtil((NaturalAxis.V, NaturalAxis.W), NaturalAxis.W)
assert tm.to_enum() == TransformationMatrixType.Bwv


def test_check_plane_invalid_input():
with pytest.raises(ValueError):
check_plane((NaturalAxis.U, NaturalAxis.U))

with pytest.raises(ValueError):
check_plane((NaturalAxis.V, NaturalAxis.U))

with pytest.raises(ValueError):
check_plane((NaturalAxis.U, NaturalAxis.W, NaturalAxis.V))


def test_check_axis_to_keep_invalid_input():
with pytest.raises(ValueError):
check_axis_to_keep('X')

0 comments on commit 85a87c2

Please sign in to comment.