Skip to content

[BUG] Incorrect center of mass calculation #251

@steinraf

Description

@steinraf

Bug Description

While debugging an issue related towp.sim.parse_urdf and its loading of warp.sim.Mesh instances , I noticed that the function in the constructor which gets called to compute the inertia if the compute_inertia flag is True (default behaviour), returns unexpected values.

When looking at the code, I found that the compute_mesh_inertia function in warp.sim.inertia.py does not return the center of mass, but the arithmetic mean of all vertices. These are not equal for most meshes.

warp/warp/sim/inertia.py

Lines 256 to 260 in 7de9179

def compute_mesh_inertia(
density: float, vertices: list, indices: list, is_solid: bool = True, thickness: Union[List[float], float] = 0.001
) -> tuple:
"""Computes mass, center of mass, 3x3 inertia matrix, and volume for a mesh."""
com = wp.vec3(np.mean(vertices, 0))

A short example showing the problem:

import warp as wp
import warp.render

from warp.sim.inertia import compute_mesh_inertia

# Unit Cube
vertices = [
    [1.0, 0.0, 0.0],
    [1.0, 0.0, 1.0],
    [0.0, 0.0, 1.0],
    [0.0, 0.0, 0.0],
    [1.0, 1.0, 0.0],
    [1.0, 1.0, 1.0],
    [0.0, 1.0, 1.0],
    [0.0, 1.0, 0.0],
]

indices = [
    1,
    2,
    3,
    7,
    6,
    5,
    4,
    5,
    1,
    5,
    6,
    2,
    2,
    6,
    7,
    0,
    3,
    7,
    0,
    1,
    3,
    4,
    7,
    5,
    0,
    4,
    1,
    1,
    5,
    2,
    3,
    2,
    7,
    4,
    0,
    7,
]


mass, com, I, volume = compute_mesh_inertia(
    density=1000, vertices=vertices, indices=indices, is_solid=True
)

print("Initial values", mass, com, I, volume, sep="\n")


# Add vertex between [0.0, 0.0, 0.0] and [1.0, 0.0, 0.0]
vertices.append([0.5, 0.0, 0.0])
last = 8
indices[15:18] = [0, 8, 7]
indices.extend([8, 3, 7])
indices[18:21] = [0, 1, 8]
indices.extend([8, 1, 3])


mass, com, I, volume = compute_mesh_inertia(
    density=1000, vertices=vertices, indices=indices, is_solid=True
)

# mass and volume stay the same (approx.)
# center of mass gets shifted by (0.0, -1/15, -1/15)
# Inertia is also impacted
print("Updated Values", mass, com, I, volume, sep="\n")


# Triangle split can be seen in wireframe mode (Press letter x)
renderer = wp.render.OpenGLRenderer()

for i in range(1000):
    print("FRAME", i)
    renderer.begin_frame(i * 0.01)
    renderer.render_mesh("Mesh", points=vertices, indices=indices)
    renderer.end_frame()
    renderer.paused = True
    renderer.update()

By splitting one triangle into two, the center of mass and inertia are unexpectedly changed.

System Information

Warp 1.2.2 initialized:
   CUDA Toolkit 11.8, Driver 12.2
   Devices:
     "cpu"      : "x86_64"
     "cuda:0"   : "NVIDIA GeForce RTX 4090" (24 GiB, sm_89, mempool enabled)

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions