Mass and Inertia#
Every dynamic rigid body in Newton needs positive mass and a physically meaningful inertia tensor for stable simulation. Newton provides three ways to assign these properties:
Direct specification on the body via
add_link().Density-based inference from collision shapes added with
ShapeConfig.File import (USD, MJCF, URDF), where mass properties are parsed from the source format and mapped to Newton’s internal representation.
For the distinction between static, kinematic, and dynamic bodies see Articulations.
Best practices#
Tip
Dynamic bodies should have positive mass.
If a body has no shapes with density, set mass and inertia
explicitly on add_link().
Tip
Use is_kinematic=True for prescribed motion — do not rely on
zero mass to make a body immovable. See Articulations for details.
Tip
Prefer density-based inference when possible. Letting Newton compute mass and inertia from shape geometry keeps mass properties consistent with collision geometry and avoids manual bookkeeping.
Tip
Use lock_inertia=True to protect hand-specified mass properties
from subsequent shape additions. This is the mechanism the MJCF importer
uses when an <inertial> element is present.
Tip
Check finalize warnings. Set validate_inertia_detailed=True on
ModelBuilder during development to get per-body warnings
for any mass or inertia values that were corrected.
Specifying mass and inertia#
Direct specification on the body#
add_link() accepts the following inertial
parameters:
mass— body mass [kg]. Defaults to0.0.inertia— 3x3 inertia tensor [kg m2] relative to the center of mass. Defaults to the zero matrix.com— center-of-mass offset [m] from the body origin. Defaults to the origin.armature— artificial scalar inertia [kg m2] added to the diagonal of the inertia tensor. Useful for regularization.
These values serve as the initial mass properties of the body. If shapes with positive density are subsequently added, their contributions are accumulated on top of these initial values (see below).
Automatic inference from shape density#
When a shape is added via one of the add_shape_*() methods with
ShapeConfig.density > 0, Newton
automatically computes mass, center of mass, and inertia tensor from the shape
geometry and accumulates the result onto the parent body.
The accumulation follows three steps:
Mass: the shape’s mass is added to the body’s total mass.
Center of mass: the body COM is recomputed as the mass-weighted average of the existing body COM and the shape’s COM (transformed to body frame).
Inertia: both the existing body inertia and the shape inertia are shifted to the new COM using the parallel-axis theorem (Steiner’s theorem), then summed.
This means multiple shapes on the same body compose additively.
import numpy as np
import warp as wp
import newton
builder = newton.ModelBuilder()
# Body with initial mass 2.0 kg
body = builder.add_link(mass=2.0)
# Shape adds mass from density: a 1m-radius sphere at 1000 kg/m^3
builder.add_shape_sphere(body, radius=1.0, cfg=builder.ShapeConfig(density=1000.0))
sphere_mass = 4.0 / 3.0 * np.pi * 1000.0 # ~4189 kg
assert abs(builder.body_mass[body] - (2.0 + sphere_mass)) < 1.0
Special cases:
Planes and heightfields never contribute mass, regardless of density.
Sites enforce
density=0and never contribute mass.lock_inertia=Trueonadd_link()prevents subsequent shape additions from modifying the body’s mass, COM, or inertia.Hollow shapes (
ShapeConfig.is_solid=False) compute shell inertia by subtracting the inner volume’s contribution from the outer, usingShapeConfig.marginas shell thickness.
Mass resolution during file import#
When importing from USD, MJCF, or URDF, each format has its own rules for how mass properties are authored, inferred, or overridden. Regardless of format, shape-derived contributions all flow through the same accumulation logic described above.
The common pattern across formats is:
Explicit inertial data takes precedence when present (
UsdPhysics.MassAPIfor USD,<inertial>for MJCF/URDF).Shape-based inference is the fallback when explicit data is missing — mass and inertia are computed from collision geometry and density.
Both MJCF and URDF importers accept
ignore_inertial_definitions=Trueto skip explicit inertial data and always infer from shapes.
For format-specific details, see:
USD: USD Parsing and Schema Resolver System — covers the
MassAPIprecedence cascade,ComputeMassPropertiescallback, and collider density priority.MJCF:
add_mjcf()— follows MuJoCo semantics where<inertial>fully overrides geom-derived mass (vialock_inertia), and geoms contribute via density when<inertial>is absent.URDF:
add_urdf()— uses<inertial>directly when present; falls back to collision geometry with default density otherwise. By default visual shapes do not contribute mass; however,parse_visuals_as_colliders=Truepromotes visual geometry into the collider set, making it mass-contributing atdefault_shape_density.
Validation and correction at finalize#
During finalize(), Newton validates and optionally
corrects mass and inertia properties for all bodies.
Compiler settings#
The following attributes on ModelBuilder control validation
behavior:
Setting |
Default |
Description |
|---|---|---|
|
Fix triangle-inequality violations on principal moments by shifting eigenvalues uniformly. |
|
|
Minimum mass value. If set, clamps small masses up to this value. |
|
|
Minimum inertia eigenvalue. If set, ensures all principal moments are at least this value. |
|
|
When |
Checks performed#
The detailed (validate_inertia_detailed=True) and fast (default) validation
paths apply the same conceptual checks, but the detailed path emits per-body
warnings. Work is underway to unify the two implementations.
The following checks are applied in order:
Negative mass — set to zero.
Small positive mass below
bound_mass— clamped (ifbound_massis set).Zero mass with non-zero inertia — inertia zeroed.
Inertia symmetry — enforced via \((I + I^T) / 2\).
Positive definiteness — negative eigenvalues adjusted.
Eigenvalue bounds — all eigenvalues clamped to at least
bound_inertia(if set).Triangle inequality — principal moments must satisfy \(I_1 + I_2 \geq I_3\). If violated and
balance_inertiaisTrue, eigenvalues are shifted uniformly to satisfy the inequality.
Note
collapse_fixed_joints() merges mass and inertia
across collapsed bodies before validation runs.
Shape inertia reference#
The table below summarizes the mass formula for each shape type when density
is positive. For the full inertia tensor expressions, see
compute_inertia_shape().
Shape |
Mass |
Notes |
|---|---|---|
Sphere |
\(\tfrac{4}{3} \pi r^3 \rho\) |
Hollow: shell inertia (outer minus inner). |
Box |
\(8\, h_x h_y h_z\, \rho\) |
Half-extents. |
Capsule |
hemisphere caps + cylinder |
\((\tfrac{4}{3}\pi r^3 + 2\pi r^2 h)\,\rho\) |
Cylinder |
\(\pi r^2 h\, \rho\) |
|
Cone |
\(\tfrac{1}{3} \pi r^2 h\, \rho\) |
Center of mass offset from base. |
Ellipsoid |
\(\tfrac{4}{3} \pi a\,b\,c\, \rho\) |
Semi-axes. |
Mesh |
Integrated from triangles |
Cached on |
Plane |
Always 0 |
Regardless of density. |
Heightfield |
Always 0 |
Regardless of density. |
Hollow shapes (ShapeConfig.is_solid=False) compute shell inertia by
subtracting the inner volume’s contribution, using
ShapeConfig.margin as shell thickness.