Skip to main content

dynamics_spatial/
inertia.rs

1//! Defines spatial **inertia** and related operations.
2
3use nalgebra::Matrix6;
4
5use crate::{motion::SpatialMotion, vector6d::Vector6D};
6use std::ops::Mul;
7
8#[derive(Debug, Clone, PartialEq, Default)]
9/// Spatial inertia matrix, represented as a 6x6 matrix.
10///
11/// The spatial inertia matrix is expressed as:
12/// $$\begin{bmatrix} `mI_3` & -mc_\times \\\\ mc_\times & `I_c` \end{bmatrix}$$
13/// where $m$ is the mass, $`I_3`$ is the 3x3 identity matrix,
14/// $c_\times=\[c\]_\times$ is the skew-symmetric matrix of the center
15/// of mass vector, and $`I_c`$ is the rotational inertia matrix about the center of mass.
16pub struct SpatialInertia(Matrix6<f64>);
17
18impl SpatialInertia {
19    /// Creates a new `SpatialInertia` object with the given elements.
20    ///
21    /// # Arguments
22    ///
23    /// * `ixx`, `iyy`, `izz` - Diagonal elements of the rotational inertia matrix.
24    /// * `ixy`, `ixz`, `iyz` - Off-diagonal elements of the rotational inertia matrix.
25    ///
26    /// # Returns
27    /// A new `SpatialInertia` object.
28    #[must_use]
29    pub fn new(ixx: f64, ixy: f64, ixz: f64, iyy: f64, iyz: f64, izz: f64) -> Self {
30        let mut mat = Matrix6::<f64>::zeros();
31        mat[(0, 0)] = ixx;
32        mat[(0, 1)] = ixy;
33        mat[(0, 2)] = ixz;
34        mat[(1, 0)] = ixy;
35        mat[(1, 1)] = iyy;
36        mat[(1, 2)] = iyz;
37        mat[(2, 0)] = ixz;
38        mat[(2, 1)] = iyz;
39        mat[(2, 2)] = izz;
40        Self(mat)
41    }
42
43    /// Creates a new `SpatialInertia` object with all elements set to zero.
44    #[must_use]
45    pub fn zeros() -> Self {
46        Self(Matrix6::<f64>::zeros())
47    }
48
49    /// Creates a new `SpatialInertia` object from a diagonal vector.
50    ///
51    /// # Arguments
52    ///
53    /// * `diag` - A 6D vector representing the diagonal elements of the spatial inertia matrix.
54    ///
55    /// # Returns
56    /// A new `SpatialInertia` object.
57    #[must_use]
58    pub fn from_diagonal(diag: &Vector6D) -> Self {
59        Self(diag.as_diagonal())
60    }
61}
62
63impl Mul<&SpatialMotion> for &SpatialInertia {
64    type Output = SpatialMotion;
65
66    fn mul(self, rhs: &SpatialMotion) -> Self::Output {
67        SpatialMotion(self.0 * rhs.0)
68    }
69}