use crate::linear_algebra::Vector;
use crate::scalar::Numeric;
use crate::spatial::{Quaternion, SE3, SO3, Twist};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FreeJointState<T: Numeric = f64> {
pose: SE3<T>,
velocity: Twist<T>,
}
impl<T: Numeric> FreeJointState<T> {
pub const GENERALIZED_POSITION_DIMENSION: usize = 7;
pub const GENERALIZED_VELOCITY_DIMENSION: usize = 6;
#[inline]
#[must_use]
pub fn new(pose: SE3<T>, velocity: Twist<T>) -> Self {
FreeJointState { pose, velocity }
}
#[inline]
#[must_use]
pub fn identity() -> Self {
FreeJointState {
pose: SE3::identity(),
velocity: Twist::zeros(),
}
}
#[inline]
#[must_use]
pub fn pose(self) -> SE3<T> {
self.pose
}
#[inline]
#[must_use]
pub fn velocity(self) -> Twist<T> {
self.velocity
}
#[must_use]
pub fn from_generalized_vectors(position: [T; 7], velocity: [T; 6]) -> Option<Self> {
let [x, y, z, w, qx, qy, qz] = position;
let orientation = Quaternion::new(w, qx, qy, qz).try_normalized()?;
Some(FreeJointState {
pose: SE3::from_parts(SO3::from_quaternion(orientation), Vector::new([x, y, z])),
velocity: Twist::from_array(velocity),
})
}
#[inline]
#[must_use]
pub fn generalized_position(self) -> [T; 7] {
let [x, y, z] = *self.pose.translation().as_array();
let [w, qx, qy, qz] = self.pose.rotation().quaternion().as_array();
[x, y, z, w, qx, qy, qz]
}
#[inline]
#[must_use]
pub fn generalized_velocity(self) -> [T; 6] {
self.velocity.as_array()
}
}