Source code for jaxsim.math.adjoint
import jax.numpy as jnp
import jaxlie
import jaxsim.typing as jtp
from .skew import Skew
[docs]
class Adjoint:
[docs]
@staticmethod
def from_quaternion_and_translation(
quaternion: jtp.Vector = jnp.array([1.0, 0, 0, 0]),
translation: jtp.Vector = jnp.zeros(3),
inverse: bool = False,
normalize_quaternion: bool = False,
) -> jtp.Matrix:
"""
Create an adjoint matrix from a quaternion and a translation.
Args:
quaternion (jtp.Vector): A quaternion vector (4D) representing orientation.
translation (jtp.Vector): A translation vector (3D).
inverse (bool): Whether to compute the inverse adjoint. Default is False.
normalize_quaternion (bool): Whether to normalize the quaternion before creating the adjoint.
Default is False.
Returns:
jtp.Matrix: The adjoint matrix.
"""
assert quaternion.size == 4
assert translation.size == 3
Q_sixd = jaxlie.SO3(wxyz=quaternion)
Q_sixd = Q_sixd if not normalize_quaternion else Q_sixd.normalize()
return Adjoint.from_rotation_and_translation(
rotation=Q_sixd.as_matrix(), translation=translation, inverse=inverse
)
[docs]
@staticmethod
def from_rotation_and_translation(
rotation: jtp.Matrix = jnp.eye(3),
translation: jtp.Vector = jnp.zeros(3),
inverse: bool = False,
) -> jtp.Matrix:
"""
Create an adjoint matrix from a rotation matrix and a translation vector.
Args:
rotation (jtp.Matrix): A 3x3 rotation matrix.
translation (jtp.Vector): A translation vector (3D).
inverse (bool): Whether to compute the inverse adjoint. Default is False.
Returns:
jtp.Matrix: The adjoint matrix.
"""
assert rotation.shape == (3, 3)
assert translation.size == 3
A_R_B = rotation.squeeze()
A_o_B = translation.squeeze()
if not inverse:
X = A_X_B = jnp.vstack( # noqa: F841
[
jnp.block([A_R_B, Skew.wedge(A_o_B) @ A_R_B]),
jnp.block([jnp.zeros(shape=(3, 3)), A_R_B]),
]
)
else:
X = B_X_A = jnp.vstack( # noqa: F841
[
jnp.block([A_R_B.T, -A_R_B.T @ Skew.wedge(A_o_B)]),
jnp.block([jnp.zeros(shape=(3, 3)), A_R_B.T]),
]
)
return X
[docs]
@staticmethod
def inverse(adjoint: jtp.Matrix) -> jtp.Matrix:
"""
Compute the inverse of an adjoint matrix.
Args:
adjoint (jtp.Matrix): The adjoint matrix.
Returns:
jtp.Matrix: The inverse adjoint matrix.
"""
A_X_B = adjoint
A_H_B = Adjoint.to_transform(adjoint=A_X_B)
A_R_B = A_H_B[0:3, 0:3]
A_o_B = A_H_B[0:3, 3]
return Adjoint.from_rotation_and_translation(
rotation=A_R_B, translation=A_o_B, inverse=True
)