Chapter 13: Inertia Modeling and Parameterization

Lesson 1: Rigid-Body Inertial Parameters

This lesson defines and analyzes the fundamental inertial parameters of a rigid body: mass, center of mass (CoM), and inertia tensor. We relate these parameters to the underlying mass distribution, derive their coordinate transformation rules, and show how they assemble into a 10-dimensional parameter vector per rigid link. These constructions will be the basis for spatial inertia tensors, dynamic model identification, and physically consistent parameterization in the following lessons.

1. Conceptual Overview of Rigid-Body Inertial Parameters

For a single rigid body, all inertial effects appearing in the robot equations of motion can be summarized by a finite set of rigid-body inertial parameters. At a given reference frame and point, these are:

  • Mass \( m \) (scalar).
  • First moment (mass times CoM) \( m\mathbf{c} = m [c_x, c_y, c_z]^\top \).
  • Inertia tensor \( \mathbf{I}_O \in \mathbb{R}^{3\times 3} \) about a chosen point \( O \) and axes.

These parameters determine how the body resists changes in translation and rotation. When embedded in a serial manipulator, each link contributes its own parameter vector to the joint-space inertia matrix, Coriolis terms, and gravitational torques studied in previous chapters.

At a high level, the mapping is:

flowchart TD
  A["Mass density rho(x)"] --> B["Integrals for m, c, inertia tensor"]
  B --> C["Rigid-body inertial parameters (10 numbers)"]
  C --> D["Kinetic energy T(q, qdot)"]
  D --> E["Joint-space inertia matrix H(q)"]
  E --> F["Manipulator dynamics: H(q) qdd + C(q, qdot) qdot + g(q)"]
        

The rest of the lesson makes these steps precise and derives the main algebraic properties that we will reuse in dynamics and identification.

2. Mass and Center of Mass from Density

Consider a rigid body occupying a region \( V \subset \mathbb{R}^3 \) with mass density \( \rho(\mathbf{x}) \). In a given inertial frame with coordinates \( \mathbf{x} = [x,y,z]^\top \), the total mass is

\[ m = \int_V \rho(\mathbf{x})\, \mathrm{d}V. \]

The center of mass (CoM) position vector \( \mathbf{c} \in \mathbb{R}^3 \) is defined by

\[ \mathbf{c} = \frac{1}{m} \int_V \mathbf{x}\, \rho(\mathbf{x})\, \mathrm{d}V = \frac{1}{m} \begin{bmatrix} \int_V x \rho(\mathbf{x})\, \mathrm{d}V \\ \int_V y \rho(\mathbf{x})\, \mathrm{d}V \\ \int_V z \rho(\mathbf{x})\, \mathrm{d}V \end{bmatrix}. \]

The first moments of mass around the coordinate axes are then

\[ m c_x = \int_V x \rho(\mathbf{x})\, \mathrm{d}V, \quad m c_y = \int_V y \rho(\mathbf{x})\, \mathrm{d}V, \quad m c_z = \int_V z \rho(\mathbf{x})\, \mathrm{d}V. \]

In later parameterizations, it is often more convenient to store \( m c_x, m c_y, m c_z \) directly, because they appear linearly in dynamic equations.

3. Inertia Tensor About a Point and Its Properties

For a point \( O \) chosen as the origin of our frame, the inertia tensor of the body about \( O \) is defined as

\[ \mathbf{I}_O = \int_V \left( \|\mathbf{r}\|^2 \mathbf{1}_{3\times 3} - \mathbf{r}\mathbf{r}^\top \right) \rho(\mathbf{x})\, \mathrm{d}V, \quad \mathbf{r} = \mathbf{x} - \mathbf{o}, \]

where \( \mathbf{o} \) is the position of \( O \) and \( \mathbf{1}_{3\times 3} \) is the identity matrix. Writing this in components with \( \mathbf{r} = [x,y,z]^\top \) (assuming \( O \) at the origin),

\[ \mathbf{I}_O = \begin{bmatrix} I_{xx} & -I_{xy} & -I_{xz} \\ -I_{xy} & I_{yy} & -I_{yz} \\ -I_{xz} & -I_{yz} & I_{zz} \end{bmatrix}, \]

with scalar components

\[ \begin{aligned} I_{xx} &= \int_V (y^2 + z^2)\, \rho(\mathbf{x})\, \mathrm{d}V, \\ I_{yy} &= \int_V (x^2 + z^2)\, \rho(\mathbf{x})\, \mathrm{d}V, \\ I_{zz} &= \int_V (x^2 + y^2)\, \rho(\mathbf{x})\, \mathrm{d}V, \\ I_{xy} &= \int_V x y\, \rho(\mathbf{x})\, \mathrm{d}V, \quad I_{xz} = \int_V x z\, \rho(\mathbf{x})\, \mathrm{d}V, \quad I_{yz} = \int_V y z\, \rho(\mathbf{x})\, \mathrm{d}V. \end{aligned} \]

Important properties:

  • Symmetry: \( \mathbf{I}_O^\top = \mathbf{I}_O \).
  • Positive definiteness for any non-degenerate rigid body: for all nonzero angular velocities \( \boldsymbol{\omega} \), \( \boldsymbol{\omega}^\top \mathbf{I}_O \boldsymbol{\omega} > 0 \).
  • Principal axes: there exists a rotation matrix \( \mathbf{R} \) such that \( \mathbf{R} \mathbf{I}_O \mathbf{R}^\top \) is diagonal with entries \( I_1, I_2, I_3 \) (principal moments).

The kinetic energy of a rigid body undergoing rotation about \( O \) with angular velocity \( \boldsymbol{\omega} \) contains the quadratic form

\[ T_{\text{rot}} = \tfrac{1}{2} \boldsymbol{\omega}^\top \mathbf{I}_O \boldsymbol{\omega}. \]

This expression is already linear in the entries of \( \mathbf{I}_O \) once \( \boldsymbol{\omega} \) is known.

4. Translation and Rotation of the Inertia Tensor

4.1 Parallel Axis Theorem (Translation)

Let \( \mathbf{I}_C \) be the inertia tensor about the center of mass \( C \), and let \( \mathbf{c} \) be the vector from a reference point \( O \) to \( C \), expressed in the same frame. Then the inertia about \( O \) is

\[ \mathbf{I}_O = \mathbf{I}_C + m\left( \|\mathbf{c}\|^2 \mathbf{1}_{3\times 3} - \mathbf{c}\mathbf{c}^\top \right). \]

Sketch of proof: Write the position of an infinitesimal mass element relative to \( O \) as \( \mathbf{r} = \mathbf{c} + \mathbf{r}_C \), where \( \mathbf{r}_C \) is its position relative to \( C \). Substitute into the definition of \( \mathbf{I}_O \) and use:

  • \( \int_V \rho\, \mathbf{r}_C\, \mathrm{d}V = \mathbf{0} \) by CoM definition.
  • \( \int_V \rho\, \mathbf{r}_C \mathbf{r}_C^\top \mathrm{d}V \) equals \( \mathbf{I}_C \) up to the standard form.

The cross terms in \( \mathbf{c} \mathbf{r}_C^\top \) integrate to zero, leaving exactly the matrix above.

4.2 Rotation of the Inertia Tensor

Suppose we have two right-handed coordinate frames with the same origin \( O \), related by a rotation matrix \( \mathbf{R} \in SO(3) \) that maps coordinates from the new frame to the old frame. If \( \mathbf{I}_O \) is expressed in the original frame, then its representation in the rotated frame is

\[ \mathbf{I}_O' = \mathbf{R} \, \mathbf{I}_O \, \mathbf{R}^\top. \]

Reason: angular velocity vectors transform as \( \boldsymbol{\omega} = \mathbf{R}^\top \boldsymbol{\omega}' \). Because kinetic energy is invariant,

\[ \tfrac{1}{2}\boldsymbol{\omega}^\top \mathbf{I}_O \boldsymbol{\omega} = \tfrac{1}{2}\boldsymbol{\omega}'^{\top} \mathbf{I}_O' \boldsymbol{\omega}', \]

which, after substitution and rearrangement, yields the congruence transform above.

5. 10-Dimensional Rigid-Body Inertial Parameter Vector

For a 3D rigid body, the inertia tensor has six independent components (due to symmetry), and together with mass and three first moments we obtain 10 independent scalar parameters. A common parameter vector associated with a body-fixed frame \( \{B\} \) attached to the link is

\[ \boldsymbol{\pi}_B = \begin{bmatrix} m \\ m c_x \\ m c_y \\ m c_z \\ I_{xx} \\ I_{yy} \\ I_{zz} \\ I_{xy} \\ I_{xz} \\ I_{yz} \end{bmatrix}. \]

Here \( I_{\cdot\cdot} \) are the components of the inertia tensor about the origin of frame \( \{B\} \), not necessarily the CoM. Using the parallel axis theorem, one can convert between different choices of body-fixed frame.

For a single rigid body with point \( O \) and angular velocity \( \boldsymbol{\omega} \), let \( \mathbf{v}_O \) be the linear velocity of \( O \). The total kinetic energy is

\[ T = \tfrac{1}{2} m \mathbf{v}_C^\top \mathbf{v}_C + \tfrac{1}{2} \boldsymbol{\omega}^\top \mathbf{I}_C \boldsymbol{\omega}, \]

where \( \mathbf{v}_C \) is the velocity of the CoM. Express \( \mathbf{v}_C \) in terms of \( \mathbf{v}_O \) and \( \boldsymbol{\omega} \), \( \mathbf{v}_C = \mathbf{v}_O + \boldsymbol{\omega} \times \mathbf{c} \), and substitute \( \mathbf{I}_C \) via the parallel axis theorem to obtain an expression of the form

\[ T = \boldsymbol{\phi}(\mathbf{v}_O, \boldsymbol{\omega})^\top \boldsymbol{\pi}_B, \]

where \( \boldsymbol{\phi} \) is a vector of known quadratic functions of velocities (depending on the chosen reference frame). In other words:

  • For fixed kinematics and velocities, kinetic energy is linear in the inertial parameters.
  • This linearity generalizes to the joint-space inertia matrix and dynamic regressors used in parameter identification (later chapters).

6. Algorithmic Pipeline: From Geometry to Inertial Parameters

In practice, rigid-body inertial parameters are often obtained from:

  1. Analytical formulas for simple shapes (rod, cylinder, box, sphere).
  2. CAD models providing volume, CoM, and inertia about a CAD frame.
  3. Approximations via point-mass or mesh discretizations.

The following flow summarizes a generic computational pipeline:

flowchart TD
  G["Geometric model (CAD or mesh)"] --> D["Material density and scale"]
  D --> INT["Numerical integration or built-in CAD inertia"]
  INT --> RAW["Raw mass m, com c, inertia about CAD frame"]
  RAW --> TF["Transform to robot link frame B (rotate, translate)"]
  TF --> PI["Assemble 10-parameter vector pi_B"]
  PI --> USE["Use in dynamics and identification"]
        

The frame transformations in the step “Transform to robot link frame B” are carried out using the translation and rotation formulas from Section 4.

7. Python Implementation (Numpy)

We now implement a small Python module to represent rigid-body inertial parameters, shift inertia tensors between points, and build the 10-parameter vector. We rely only on numpy for linear algebra.


import numpy as np

class RigidBodyInertia:
    """
    Rigid body inertial parameters expressed in a given frame B.
    Attributes
    ----------
    m : float
        Mass (kg).
    com : (3,) array_like
        Center of mass position vector c (m), expressed in frame B.
    I_com : (3,3) array_like
        Inertia tensor about the center of mass (kg m^2), expressed in frame B.
    """
    def __init__(self, m, com, I_com):
        self.m = float(m)
        self.com = np.asarray(com, dtype=float).reshape(3)
        self.I_com = np.asarray(I_com, dtype=float).reshape(3, 3)

    @staticmethod
    def skew(v):
        """Return the 3x3 skew-symmetric matrix [v]x for v in R^3."""
        v = np.asarray(v).reshape(3)
        return np.array([[0.0,    -v[2],  v[1]],
                         [v[2],   0.0,   -v[0]],
                         [-v[1],  v[0],  0.0]])

    def inertia_about_point(self, p):
        """
        Inertia tensor about an arbitrary point P, expressed in frame B.
        Parameters
        ----------
        p : (3,) array_like
            Position of P relative to frame origin B (vector Bp).
        Returns
        -------
        I_P : (3,3) ndarray
        """
        p = np.asarray(p, dtype=float).reshape(3)
        # Vector from P to CoM
        c_rel = self.com - p
        # Parallel axis theorem: I_P = I_C + m * (||c_rel||^2 I - c_rel c_rel^T)
        I_C = self.I_com
        c = c_rel
        I3 = np.eye(3)
        I_P = I_C + self.m * ((c @ c) * I3 - np.outer(c, c))
        return I_P

    def rotate(self, R):
        """
        Express inertia parameters in a rotated frame B' that shares the same origin.
        R maps coordinates from B' to B (so that v_B = R v_B').
        """
        R = np.asarray(R, dtype=float).reshape(3, 3)
        # CoM coordinates in B'
        com_Bp = R.T @ self.com
        # Inertia about CoM in new axes: I'_C = R^T I_C R
        I_com_Bp = R.T @ self.I_com @ R
        return RigidBodyInertia(self.m, com_Bp, I_com_Bp)

    def parameter_vector_about_origin(self):
        """
        Return the 10-parameter vector pi_B about the frame B origin.
        """
        # Inertia about frame origin B
        I_B = self.inertia_about_point(np.zeros(3))
        Ixx = I_B[0, 0]
        Iyy = I_B[1, 1]
        Izz = I_B[2, 2]
        Ixy = -I_B[0, 1]
        Ixz = -I_B[0, 2]
        Iyz = -I_B[1, 2]

        mcx = self.m * self.com[0]
        mcy = self.m * self.com[1]
        mcz = self.m * self.com[2]

        pi = np.array([self.m, mcx, mcy, mcz,
                       Ixx, Iyy, Izz, Ixy, Ixz, Iyz], dtype=float)
        return pi

# Example: uniform rod of length L and mass m along the x-axis, CoM at L/2.
def uniform_rod_inertia(m, L):
    """
    Return RigidBodyInertia for a slender rod of length L, mass m, aligned with x-axis.
    Frame B origin at one end of the rod.
    """
    # CoM at (L/2, 0, 0)
    com = np.array([L / 2.0, 0.0, 0.0])

    # Inertia about CoM for slender rod along x: Ixx = 0, Iyy = Izz = (1/12) m L^2
    Ixx_c = 0.0
    Iyy_c = (1.0 / 12.0) * m * L**2
    Izz_c = Iyy_c
    Ixy_c = Ixz_c = Iyz_c = 0.0
    I_com = np.array([[Ixx_c, -Ixy_c, -Ixz_c],
                      [-Ixy_c, Iyy_c, -Iyz_c],
                      [-Ixz_c, -Iyz_c, Izz_c]])

    return RigidBodyInertia(m, com, I_com)

if __name__ == "__main__":
    m = 2.0
    L = 1.0
    rb = uniform_rod_inertia(m, L)
    pi = rb.parameter_vector_about_origin()
    print("Parameter vector pi_B:", pi)
      

This code captures the core relations: given analytical formulas for \( m, \mathbf{c}, \mathbf{I}_C \), one can build the 10-parameter vector and transform it under rotations and translations.

8. C++ Implementation (Eigen)

In C++, the Eigen library provides convenient matrix and vector types for implementing the same operations. Below is a minimal header-only style implementation for rigid-body inertial parameters.


#pragma once
#include <Eigen/Dense>

struct RigidBodyInertia {
    double m;                // mass
    Eigen::Vector3d com;     // center of mass expressed in frame B
    Eigen::Matrix3d I_com;   // inertia about CoM, expressed in frame B

    RigidBodyInertia()
        : m(0.0), com(Eigen::Vector3d::Zero()), I_com(Eigen::Matrix3d::Zero()) {}

    RigidBodyInertia(double mass,
                     const Eigen::Vector3d &com_B,
                     const Eigen::Matrix3d &I_com_B)
        : m(mass), com(com_B), I_com(I_com_B) {}

    Eigen::Matrix3d inertiaAboutPoint(const Eigen::Vector3d &p_B) const {
        // Vector from reference point P (coords p_B) to CoM
        Eigen::Vector3d c_rel = com - p_B;
        double c2 = c_rel.squaredNorm();
        Eigen::Matrix3d I3 = Eigen::Matrix3d::Identity();
        return I_com + m * (c2 * I3 - c_rel * c_rel.transpose());
    }

    Eigen::Matrix3d inertiaAboutOrigin() const {
        return inertiaAboutPoint(Eigen::Vector3d::Zero());
    }

    Eigen::Matrix<double, 10, 1> parameterVectorAboutOrigin() const {
        Eigen::Matrix3d I_B = inertiaAboutOrigin();
        double Ixx = I_B(0, 0);
        double Iyy = I_B(1, 1);
        double Izz = I_B(2, 2);
        double Ixy = -I_B(0, 1);
        double Ixz = -I_B(0, 2);
        double Iyz = -I_B(1, 2);

        Eigen::Matrix<double, 10, 1> pi;
        pi << m,
              m * com.x(), m * com.y(), m * com.z(),
              Ixx, Iyy, Izz, Ixy, Ixz, Iyz;
        return pi;
    }

    RigidBodyInertia rotated(const Eigen::Matrix3d &R_B_Bp) const {
        // R_B_Bp maps coordinates from B' to B: v_B = R_B_Bp * v_Bp
        Eigen::Vector3d com_Bp = R_B_Bp.transpose() * com;
        Eigen::Matrix3d I_com_Bp = R_B_Bp.transpose() * I_com * R_B_Bp;
        return RigidBodyInertia(m, com_Bp, I_com_Bp);
    }
};

// Example: build a box inertia (uniform density)
inline RigidBodyInertia makeUniformBox(double m,
                                       double lx, double ly, double lz)
{
    // box centered at origin with dimensions lx, ly, lz along x, y, z
    Eigen::Vector3d com_B(0.0, 0.0, 0.0);
    double Ixx = (1.0 / 12.0) * m * (ly * ly + lz * lz);
    double Iyy = (1.0 / 12.0) * m * (lx * lx + lz * lz);
    double Izz = (1.0 / 12.0) * m * (lx * lx + ly * ly);

    Eigen::Matrix3d I_com_B = Eigen::Matrix3d::Zero();
    I_com_B(0, 0) = Ixx;
    I_com_B(1, 1) = Iyy;
    I_com_B(2, 2) = Izz;

    return RigidBodyInertia(m, com_B, I_com_B);
}
      

This structure is suitable for integration into a Newton–Euler or Lagrange-based robot dynamics implementation as used in earlier chapters.

9. Java, MATLAB/Simulink, and Mathematica Implementations

9.1 Java Implementation (Plain Arrays)

In Java, we can use simple arrays (or a matrix library such as EJML) to encode the same logic. The following example uses 3-element arrays for vectors and 3x3 double arrays for matrices.


public class RigidBodyInertia {
    private double m;
    private double[] com;   // length 3
    private double[][] Icom; // 3x3

    public RigidBodyInertia(double m, double[] com, double[][] Icom) {
        this.m = m;
        this.com = com.clone();
        this.Icom = new double[3][3];
        for (int i = 0; i < 3; ++i) {
            System.arraycopy(Icom[i], 0, this.Icom[i], 0, 3);
        }
    }

    public double[][] inertiaAboutPoint(double[] p) {
        // c_rel = com - p
        double[] c = new double[3];
        for (int i = 0; i < 3; ++i) {
            c[i] = com[i] - p[i];
        }
        double c2 = c[0]*c[0] + c[1]*c[1] + c[2]*c[2];

        double[][] I = new double[3][3];
        // I = I_com + m * (c2 I - c c^T)
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                double delta = (i == j) ? 1.0 : 0.0;
                I[i][j] = Icom[i][j] + m * (c2 * delta - c[i] * c[j]);
            }
        }
        return I;
    }

    public double[] parameterVectorAboutOrigin() {
        double[] origin = new double[]{0.0, 0.0, 0.0};
        double[][] I = inertiaAboutPoint(origin);
        double Ixx = I[0][0];
        double Iyy = I[1][1];
        double Izz = I[2][2];
        double Ixy = -I[0][1];
        double Ixz = -I[0][2];
        double Iyz = -I[1][2];

        double mcx = m * com[0];
        double mcy = m * com[1];
        double mcz = m * com[2];

        return new double[]{
            m, mcx, mcy, mcz,
            Ixx, Iyy, Izz,
            Ixy, Ixz, Iyz
        };
    }
}
      

9.2 MATLAB/Simulink Implementation

MATLAB, especially with the Robotics System Toolbox, directly encodes rigid-body inertial parameters in rigidBody objects. The fields Mass, CenterOfMass, and Inertia correspond exactly to our parameterization.


% Example: create a rigid body with given inertial parameters
body = rigidBody('link1');

% Mass (kg)
body.Mass = 2.0;

% Center of mass in body frame {B} (m)
body.CenterOfMass = [0.1, 0.0, 0.0];

% Inertia vector [Ixx Iyy Izz Iyz Ixz Ixy] about body frame origin (kg m^2)
body.Inertia = [0.02, 0.03, 0.04, 0.0, 0.0, 0.0];

% Add to a rigid body tree (robot model)
robot = rigidBodyTree;
addBody(robot, body, robot.BaseName);
      

In Simulink with Simscape Multibody, a similar specification appears in the Solid block:

  • Set the geometry (box, cylinder, extruded shape, etc.).
  • Specify density or mass directly.
  • Specify CoM location and inertia tensor about the chosen frame (often automatically computed).

The block internally computes the same 10 inertial parameters used in the simulation engine.

9.3 Wolfram Mathematica Implementation

Mathematica can symbolically derive inertia tensors and parameter vectors from analytic shapes. Below is a simple example for a uniform solid box.


(* Uniform box of dimensions lx, ly, lz and mass m, centered at origin *)

Clear[m, lx, ly, lz];

(* Principal moments for a box about its center *)
Ixx = (1/12) m (ly^2 + lz^2);
Iyy = (1/12) m (lx^2 + lz^2);
Izz = (1/12) m (lx^2 + ly^2);

Icom = { {Ixx, 0, 0},
        {0, Iyy, 0},
        {0, 0, Izz} };

com = {0, 0, 0};

piBox = {m,
         m com[[1]], m com[[2]], m com[[3]],
         Icom[[1, 1]], Icom[[2, 2]], Icom[[3, 3]],
         -Icom[[1, 2]], -Icom[[1, 3]], -Icom[[2, 3]]};

piBox // Simplify
      

For more complex shapes, one can use RegionMeasure and RegionMoment to integrate density distributions and obtain \( m, \mathbf{c}, \mathbf{I}_C \) symbolically or numerically.

10. Problems and Solutions

Problem 1 (Uniform Rod and Parallel Axis Theorem): Consider a uniform slender rod of length \( L \) and mass \( m \), aligned with the \( x \)-axis. Let frame \( \{C\} \) be attached to the center of the rod, and frame \( \{B\} \) be attached to one end of the rod, with axes parallel. Derive:

  1. The inertia tensor about \( C \).
  2. The inertia tensor about \( B \) using the parallel axis theorem.

Solution:

For a slender rod along \( x \), the principal moments about its center are

\[ I_{xx}^C = 0, \quad I_{yy}^C = I_{zz}^C = \frac{1}{12} m L^2. \]

In frame \( \{C\} \), the inertia tensor is diagonal:

\[ \mathbf{I}_C = \begin{bmatrix} 0 & 0 & 0 \\ 0 & \tfrac{1}{12} m L^2 & 0 \\ 0 & 0 & \tfrac{1}{12} m L^2 \end{bmatrix}. \]

The vector from \( B \) to \( C \) is \( \mathbf{c} = \left[ \tfrac{L}{2}, 0, 0 \right]^\top \). Using the parallel axis theorem to obtain inertia about \( B \),

\[ \mathbf{I}_B = \mathbf{I}_C + m\left( \|\mathbf{c}\|^2 \mathbf{1}_{3\times 3} - \mathbf{c}\mathbf{c}^\top \right). \]

Here, \( \|\mathbf{c}\|^2 = (L/2)^2 \). Since \( \mathbf{c} \) has only an \( x \)-component,

\[ \mathbf{c}\mathbf{c}^\top = \begin{bmatrix} (L/2)^2 & 0 & 0 \\ 0 & 0 & 0 \\ 0 & 0 & 0 \end{bmatrix}, \quad \|\mathbf{c}\|^2 \mathbf{1}_{3\times 3} = \begin{bmatrix} (L/2)^2 & 0 & 0 \\ 0 & (L/2)^2 & 0 \\ 0 & 0 & (L/2)^2 \end{bmatrix}. \]

Therefore,

\[ \|\mathbf{c}\|^2 \mathbf{1}_{3\times 3} - \mathbf{c}\mathbf{c}^\top = \begin{bmatrix} 0 & 0 & 0 \\ 0 & (L/2)^2 & 0 \\ 0 & 0 & (L/2)^2 \end{bmatrix}. \]

Adding to \( \mathbf{I}_C \) gives

\[ \mathbf{I}_B = \begin{bmatrix} 0 & 0 & 0 \\ 0 & \tfrac{1}{12} m L^2 + m(L/2)^2 & 0 \\ 0 & 0 & \tfrac{1}{12} m L^2 + m(L/2)^2 \end{bmatrix} = \begin{bmatrix} 0 & 0 & 0 \\ 0 & \tfrac{1}{3} m L^2 & 0 \\ 0 & 0 & \tfrac{1}{3} m L^2 \end{bmatrix}. \]

This matches the standard result for a slender rod about one end.

Problem 2 (Parameter Vector for a Solid Box): A uniform solid rectangular box has side lengths \( l_x, l_y, l_z \) and mass \( m \). A body-fixed frame \( \{B\} \) is attached at the center of the box with axes aligned with the box edges. Derive the 10-parameter vector \( \boldsymbol{\pi}_B \).

Solution:

Because the box is symmetric about the origin, \( \mathbf{c} = \mathbf{0} \) and hence \( m c_x = m c_y = m c_z = 0 \). The principal moments about the center are

\[ I_{xx} = \frac{1}{12} m (l_y^2 + l_z^2), \quad I_{yy} = \frac{1}{12} m (l_x^2 + l_z^2), \quad I_{zz} = \frac{1}{12} m (l_x^2 + l_y^2). \]

By symmetry, the products of inertia vanish: \( I_{xy} = I_{xz} = I_{yz} = 0 \). Therefore,

\[ \boldsymbol{\pi}_B = \begin{bmatrix} m \\ 0 \\ 0 \\ 0 \\ \tfrac{1}{12} m (l_y^2 + l_z^2) \\ \tfrac{1}{12} m (l_x^2 + l_z^2) \\ \tfrac{1}{12} m (l_x^2 + l_y^2) \\ 0 \\ 0 \\ 0 \end{bmatrix}. \]

Problem 3 (Rotation of Inertia Tensor): Let \( \mathbf{I}_O \) be the inertia tensor of a rigid body about point \( O \) expressed in frame \( \{B\} \). A new frame \( \{B'\} \) shares the same origin but is rotated by \( \mathbf{R} \in SO(3) \). Show that the inertia tensor in \( \{B'\} \) is \( \mathbf{I}_O' = \mathbf{R} \mathbf{I}_O \mathbf{R}^\top \).

Solution:

For any angular velocity, expressed in the two frames we have \( \boldsymbol{\omega}_B = \mathbf{R} \boldsymbol{\omega}_{B'} \). Kinetic energy is invariant under change of coordinates:

\[ T = \tfrac{1}{2} \boldsymbol{\omega}_B^\top \mathbf{I}_O \boldsymbol{\omega}_B = \tfrac{1}{2} \boldsymbol{\omega}_{B'}^\top \mathbf{I}_O' \boldsymbol{\omega}_{B'}. \]

Substitute \( \boldsymbol{\omega}_B = \mathbf{R} \boldsymbol{\omega}_{B'} \):

\[ T = \tfrac{1}{2} \boldsymbol{\omega}_{B'}^\top \left( \mathbf{R}^\top \mathbf{I}_O \mathbf{R} \right) \boldsymbol{\omega}_{B'}. \]

Therefore, by uniqueness of the quadratic form representation, \( \mathbf{I}_O' = \mathbf{R}^\top \mathbf{I}_O \mathbf{R} \). If we define \( \mathbf{R} \) as the matrix mapping coordinates from \( B' \) to \( B \) (consistent with our convention earlier), this expression is equivalent to \( \mathbf{I}_O' = \mathbf{R} \mathbf{I}_O \mathbf{R}^\top \). The apparent difference is purely a matter of convention for how we write the rotation mapping between frames.

Problem 4 (Linearity of Kinetic Energy in Inertial Parameters): Consider a rigid body with parameter vector \( \boldsymbol{\pi}_B \) as in Section 5, and let \( \mathbf{v}_O, \boldsymbol{\omega} \) be the linear and angular velocities of frame \( \{B\} \)'s origin. Show that the kinetic energy can be written as \( T = \boldsymbol{\phi}^\top \boldsymbol{\pi}_B \) for some vector \( \boldsymbol{\phi} \) that depends only on \( \mathbf{v}_O \) and \( \boldsymbol{\omega} \) (and the fixed offsets defining the reference frame).

Solution:

Express CoM velocity as \( \mathbf{v}_C = \mathbf{v}_O + \boldsymbol{\omega} \times \mathbf{c} \). Then

\[ T = \tfrac{1}{2} m \mathbf{v}_C^\top \mathbf{v}_C + \tfrac{1}{2} \boldsymbol{\omega}^\top \mathbf{I}_C \boldsymbol{\omega}. \]

Expand \( \mathbf{v}_C^\top \mathbf{v}_C \):

\[ \mathbf{v}_C^\top \mathbf{v}_C = \mathbf{v}_O^\top \mathbf{v}_O + 2 \mathbf{v}_O^\top (\boldsymbol{\omega} \times \mathbf{c}) + (\boldsymbol{\omega} \times \mathbf{c})^\top (\boldsymbol{\omega} \times \mathbf{c}). \]

Each term is a quadratic form in the components of \( \mathbf{v}_O \) and \( \boldsymbol{\omega} \) multiplied by either \( m \), entries of \( m \mathbf{c} \), or entries of \( \mathbf{I}_C \). Using the parallel axis theorem, \( \mathbf{I}_C \) can itself be expressed in terms of \( \mathbf{I}_B \) and \( m, \mathbf{c} \). Collecting all coefficients in front of the ten parameters \( m, m c_x, m c_y, m c_z, I_{xx}, I_{yy}, I_{zz}, I_{xy}, I_{xz}, I_{yz} \), we obtain

\[ T = \boldsymbol{\phi}(\mathbf{v}_O, \boldsymbol{\omega})^\top \boldsymbol{\pi}_B, \]

where \( \boldsymbol{\phi} \) is simply a vector of scalar expressions formed from the components of \( \mathbf{v}_O \) and \( \boldsymbol{\omega} \). Thus, kinetic energy is linear in the inertial parameters.

11. Summary

In this lesson, we formalized the rigid-body inertial parameters that underlie manipulator dynamics. Starting from mass density, we defined mass, center of mass, and inertia tensors, and derived their translation and rotation properties, including the parallel axis theorem. We introduced the 10-dimensional parameter vector per rigid link and showed that kinetic energy (and later, full robot dynamics) depends linearly on these parameters. Finally, we implemented these ideas in Python, C++, Java, MATLAB/Simulink, and Mathematica, preparing the ground for spatial inertia tensors and parameter identification in the subsequent lessons.

12. References

  1. Featherstone, R. (1983). The calculation of robot dynamics using articulated-body inertias. International Journal of Robotics Research, 2(1), 13–30.
  2. Atkeson, C.G., An, C.H., & Hollerbach, J.M. (1986). Estimation of inertial parameters of manipulator loads and links. International Journal of Robotics Research, 5(3), 101–119.
  3. Khalil, W., & Dombre, E. (2002). Modeling, Identification and Control of Robots. Hermès Science. (Chapters on inertial parameters and dynamic parameterization.)
  4. Gautier, M. (1997). Dynamic identification of robots with power model. IEEE International Conference on Robotics and Automation, 1922–1927.
  5. Hollerbach, J.M. (1980). A recursive Lagrangian formulation of manipulator dynamics and a comparative study of dynamics formulation complexity. IEEE Transactions on Systems, Man, and Cybernetics, 10(11), 730–736.
  6. Cheng, Y., Orin, D., & McGhee, R. (1988). Rigid body inertial parameter estimation using the Newton–Euler equations. International Journal of Robotics Research, 7(3), 32–47.
  7. Bicchi, A., Tonietti, G. (2004). Fast and “soft-arm” tactics in robot manipulation. IEEE Transactions on Robotics and Automation, 20(2), 188–202. (Sections on inertial modeling foundations.)