Core Types
types
Core data types for SE(3) trajectories and DHB invariants.
Classes
DHBMethod
Bases: Enum
DHB encoding method.
Source code in src/dhb_xr/core/types.py
| class DHBMethod(Enum):
"""DHB encoding method."""
ORIGINAL = "original" # 3 invariants per component (magnitude + 2 angles)
DOUBLE_REFLECTION = "double_reflection" # 4 invariants (magnitude + Euler XYZ)
QUATERNION = "quaternion" # 5 invariants (magnitude + unit quaternion)
|
EncodingMethod
Bases: Enum
Encoding method for initial frame computation.
Source code in src/dhb_xr/core/types.py
| class EncodingMethod(Enum):
"""Encoding method for initial frame computation."""
POSITION = "pos" # Position-based encoding: use initial position for frame origin
VELOCITY = "vel" # Velocity-based encoding: use first position difference for frame origin
|
InvariantSequence
dataclass
DHB invariant sequence (linear + angular).
Source code in src/dhb_xr/core/types.py
| @dataclass
class InvariantSequence:
"""DHB invariant sequence (linear + angular)."""
linear: np.ndarray # (N-1, k) k=3 original, k=4 DR, k=5 QR
angular: np.ndarray # (N-1, k)
method: Literal["dhb_dr", "dhb_qr", "original"]
initial_pose: Dict[str, np.ndarray]
linear_frame_initial: Optional[np.ndarray] = None # (4,4) if available
angular_frame_initial: Optional[np.ndarray] = None
def __post_init__(self) -> None:
self.linear = np.asarray(self.linear, dtype=np.float64)
self.angular = np.asarray(self.angular, dtype=np.float64)
assert self.linear.shape[0] == self.angular.shape[0]
assert self.linear.shape[1] == self.angular.shape[1]
@property
def length(self) -> int:
return self.linear.shape[0]
@property
def invariant_dim(self) -> int:
return self.linear.shape[1]
def concatenated(self) -> np.ndarray:
"""(N-1, 2*k) linear and angular stacked."""
return np.concatenate([self.linear, self.angular], axis=1)
|
Functions
concatenated
(N-1, 2*k) linear and angular stacked.
Source code in src/dhb_xr/core/types.py
| def concatenated(self) -> np.ndarray:
"""(N-1, 2*k) linear and angular stacked."""
return np.concatenate([self.linear, self.angular], axis=1)
|
SE3Pose
dataclass
Single SE(3) pose: position and quaternion (w, x, y, z).
Source code in src/dhb_xr/core/types.py
| @dataclass
class SE3Pose:
"""Single SE(3) pose: position and quaternion (w, x, y, z)."""
position: np.ndarray # (3,)
quaternion: np.ndarray # (4,) wxyz scalar-first
def __post_init__(self) -> None:
self.position = np.asarray(self.position, dtype=np.float64).reshape(3)
self.quaternion = np.asarray(self.quaternion, dtype=np.float64).reshape(4)
nq = np.linalg.norm(self.quaternion)
if nq > 1e-10:
self.quaternion = self.quaternion / nq
def to_dict(self) -> Dict[str, np.ndarray]:
return {"position": self.position.copy(), "quaternion": self.quaternion.copy()}
@classmethod
def from_dict(cls, d: Dict[str, np.ndarray]) -> SE3Pose:
return cls(position=d["position"], quaternion=d["quaternion"])
|
Trajectory
dataclass
SE(3) trajectory: sequence of poses and optional timestamps.
Source code in src/dhb_xr/core/types.py
| @dataclass
class Trajectory:
"""SE(3) trajectory: sequence of poses and optional timestamps."""
poses: List[SE3Pose]
timestamps: Optional[np.ndarray] = None
def __len__(self) -> int:
return len(self.poses)
@property
def positions(self) -> np.ndarray:
"""(N, 3) position array."""
return np.array([p.position for p in self.poses])
@property
def quaternions(self) -> np.ndarray:
"""(N, 4) quaternion array (wxyz)."""
return np.array([p.quaternion for p in self.poses])
@classmethod
def from_arrays(
cls,
positions: np.ndarray,
quaternions: np.ndarray,
timestamps: Optional[np.ndarray] = None,
) -> Trajectory:
"""Build from (N,3) positions and (N,4) quaternions (wxyz)."""
n = len(positions)
assert len(quaternions) == n
poses = [
SE3Pose(position=positions[i], quaternion=quaternions[i])
for i in range(n)
]
return cls(poses=poses, timestamps=timestamps)
|
Attributes
quaternions
property
(N, 4) quaternion array (wxyz).
Functions
from_arrays
classmethod
from_arrays(positions, quaternions, timestamps=None)
Build from (N,3) positions and (N,4) quaternions (wxyz).
Source code in src/dhb_xr/core/types.py
| @classmethod
def from_arrays(
cls,
positions: np.ndarray,
quaternions: np.ndarray,
timestamps: Optional[np.ndarray] = None,
) -> Trajectory:
"""Build from (N,3) positions and (N,4) quaternions (wxyz)."""
n = len(positions)
assert len(quaternions) == n
poses = [
SE3Pose(position=positions[i], quaternion=quaternions[i])
for i in range(n)
]
return cls(poses=poses, timestamps=timestamps)
|
Key Classes and Enums
DHBMethod
from dhb_xr.core.types import DHBMethod
class DHBMethod(Enum):
"""DHB encoding method variants."""
DOUBLE_REFLECTION = "double_reflection" # 4 values per component (Euler-based)
ORIGINAL = "original" # 3 values per component (original DHB)
EncodingMethod
from dhb_xr.core.types import EncodingMethod
class EncodingMethod(Enum):
"""Encoding method for initial frame computation."""
POSITION = "pos" # Position-based encoding: use initial position for frame origin
VELOCITY = "vel" # Velocity-based encoding: use first position difference for frame origin
Usage
from dhb_xr.core.types import DHBMethod, EncodingMethod
# Use in encoding functions
result = encode_dhb_dr(
positions, quaternions,
method=EncodingMethod.POSITION,
dhb_method=DHBMethod.DOUBLE_REFLECTION
)