Troubleshooting Simulation Stability and Constraint Violations in Newton

Newton physics simulations become unstable or violate constraints when velocity limits, angular damping, and substep counts are misconfigured for the chosen solver backend, which can be fixed by tuning angular_damping, friction_smoothing, and substeps parameters based on the specific integration method used.

Newton is an open-source physics engine that provides multiple solver back-ends for simulating particles and rigid bodies. When troubleshooting simulation stability and constraint violations in Newton, developers must understand how the specific solver implementation—whether Featherstone, Semi-Implicit, or MuJoCo—handles numerical integration, contact resolution, and constraint enforcement.

Common Causes of Instability and Constraint Violations

Newton’s simulation pipeline is built around solver back-ends that integrate particles and rigid bodies, resolve contacts, and enforce constraints. Numerical instability or constraint violations usually stem from specific architectural areas within the integration and constraint resolution systems.

Particle Integration and Velocity Clipping

The integrate_particles function in newton/_src/solvers/solver.py limits particle velocities to v_max to prevent numerical blow-up. Missing or insufficient velocity clipping allows velocities to grow unbounded, producing NaN or infinite values that propagate through the simulation.


# From newton/_src/solvers/solver.py lines 53-56

# v1 is clamped to v_max to maintain stability

v1 = wp.clamp(v1, -v_max, v_max)

Rigid-Body Integration and Angular Damping

Rotational energy can diverge rapidly without proper damping. The integrate_rigid_body function applies angular damping to dampen rotational velocity each step, preventing jittery rotations and constraint drift.


# From newton/_src/solvers/solver.py lines 101-103

# w1 is the angular velocity, damped by angular_damping * dt

w1 *= 1.0 - angular_damping * dt

Joint Force-Torque Computation

Joint stability depends on careful scaling of angular damping stiffness. In newton/_src/solvers/semi_implicit/kernels_body.py, the angular_damping_scale parameter is set to 0.01 by default to keep torque damping gentle and prevent oscillations from over-stiff joints.

// From newton/_src/solvers/semi_implicit/kernels_body.py lines 59-62
float angular_damping_scale = 0.01f;
t_total += wp::transform_vector(X_wp, ang_err) * joint_attach_ke
          + w_err * joint_attach_kd * angular_damping_scale;

Contact Handling and Sub-stepping

High-frequency contact chatter and interpenetration occur when time steps are too coarse or friction models are too aggressive. The test suite in newton/tests/test_rigid_contact.py demonstrates recommended stability parameters: angular_damping=0.15, friction_smoothing=2.0, and substeps=30.


# From newton/tests/test_rigid_contact.py lines 62-78 and 86-89

solver = newton.solvers.SolverSemiImplicit(
    model,
    angular_damping=0.15,      # Higher damping for stability

    friction_smoothing=2.0,      # Regularizes Coulomb friction

)
substeps = 30                  # Finer time resolution

Constraint Enforcement Limitations

Only the MuJoCo solver backend implements equality and mimic constraints. Other solvers treat these constraints as unavailable, leading to "constraint not found" errors if used improperly. The solver support table in newton/solvers.py documents these capability flags.


# From newton/solvers.py lines 31-45

# Solver capability matrix showing MuJoCo supports equality constraints

# while Featherstone and Semi-Implicit do not

Identifying Root Causes in Your Simulation

When troubleshooting simulation stability and constraint violations in Newton, inspect these four typical failure patterns:

  1. Insufficient damping or velocity limits – The default angular_damping=0.05 and implicit v_max work for modest scenes but fail during high-speed impacts or tall contact stacks. Increase angular_damping to 0.15 or higher for unstable rotations.

  2. Too coarse time step – A single step of dt = 1/60 s with complex contact networks causes interpenetration. Increasing the substep count effectively halves the per-substep dt, improving contact resolution without changing the scene definition.

  3. Unsupported constraints – Attempting to use equality constraints (CONNECT, WELD) with Featherstone or Semi-Implicit solvers triggers errors. Switch to SolverMuJoCo or remove the unsupported constraints.

  4. Extreme joint stiffness parameters – Large joint_attach_ke or joint_attach_kd values without corresponding damping cause explosive joint forces. Reduce stiffness or increase the damping scale factor in custom kernels.

Configuring Newton for Maximum Stability

Tuning Solver Parameters

Start by configuring your solver with stability-focused parameters demonstrated in newton/tests/test_rigid_contact.py. This example creates a Semi-Implicit solver with enhanced damping and friction smoothing:

import warp as wp
import newton

# Build a simple model (ground + a falling box)

builder = newton.ModelBuilder()
b = builder.add_body(xform=wp.transform(wp.vec3(0, 5, 0), wp.quat_identity()))
builder.add_shape_box(body=b, half_extents=wp.vec3(0.5, 0.5, 0.5))
builder.add_ground_plane()
model = builder.finalize()

# Choose a back-end and boost its stability settings

if False:  # replace with your solver choice

    solver = newton.solvers.SolverFeatherstone(
        model,
        angular_damping=0.15,          # stronger rotational damping

        friction_smoothing=2.0,        # smoother Coulomb friction

    )
else:
    solver = newton.solvers.SolverSemiImplicit(
        model,
        angular_damping=0.15,
        friction_smoothing=2.0,
    )

# Run the simulation with many substeps for extra robustness

state0, state1 = model.state(), model.state()
control = model.control()
contacts = model.contacts()
substeps = 30                # finer time resolution (default is 10)

dt = 1.0 / 60.0

for _ in range(120):
    newton.simulate(
        solver, model, state0, state1, control, contacts, dt, substeps
    )

Key parameters to adjust:

  • angular_damping: Controls rotational energy dissipation (default 0.05, stable scenes often need 0.15)
  • friction_smoothing: Regularizes the Coulomb friction model to prevent stick-slip artifacts (recommended 2.0)
  • substeps: Divides the simulation step into smaller increments (recommended 30 for contact-heavy scenes)

Detecting NaN Values Early

Newton’s test suite includes NaN guards that you should replicate in production code. After each simulation step, inspect the body states for numerical corruption:

import numpy as np

body_q = state0.body_q.numpy()
body_qd = state0.body_qd.numpy()

if np.any(np.isnan(body_q)) or np.any(np.isnan(body_qd)):
    raise RuntimeError(
        "NaNs detected – likely numerical instability. "
        "Try increasing angular_damping, friction_smoothing, or substeps."
    )

This pattern mirrors the validation logic in newton/tests/test_rigid_contact.py lines 9-16, surfacing instability before it propagates through long simulation batches.

Selecting the Appropriate Solver Backend

Constraint support varies by solver. If your scene requires equality constraints (CONNECT, WELD) or mimic joints, you must use the MuJoCo backend:


# Equality constraints are only implemented in MuJoCo

solver = newton.solvers.SolverMuJoCo(model)

Attempting to use these constraints with SolverFeatherstone or SolverSemiImplicit triggers a "constraint not found" error because the solver capability table in newton/solvers.py (lines 31-45) marks these features as unsupported for those backends.

Custom Kernel Tuning (Advanced)

If you are implementing custom joint kernels, follow the stability pattern from newton/_src/solvers/semi_implicit/kernels_body.py. Apply a small damping scale factor to prevent torque oscillations:

// From newton/_src/solvers/semi_implicit/kernels_body.py lines 59-62
float angular_damping_scale = 0.01f;  // keeps torque damping gentle
t_total += wp::transform_vector(X_wp, ang_err) * joint_attach_ke
          + w_err * joint_attach_kd * angular_damping_scale;

Adjust angular_damping_scale only after profiling; values too low create overly compliant joints, while values too high reintroduce oscillations.

Key Source Files for Debugging

When troubleshooting simulation stability and constraint violations in Newton, inspect these specific files that govern the numerical pipeline:

File Why it matters for stability / constraints
newton/_src/solvers/solver.py Core particle & rigid-body integration, velocity clipping to v_max, and angular damping application in integrate_rigid_body.
newton/_src/solvers/semi_implicit/kernels_body.py Joint force computation with angular_damping_scale factor (set to 0.01 for stability).
newton/_src/solvers/vbd/particle_vbd_kernels.py Numerical-stability comments for VBD particle contacts.
newton/_src/solvers/kamino/_src/linalg/utils/matrix.py Tolerance settings that affect matrix solves in constraint projection.
newton/tests/test_rigid_contact.py Real-world example configuring solvers with angular_damping=0.15, friction_smoothing=2.0, and substeps=30.
newton/solvers.py Public API documenting which solvers support equality constraints (MuJoCo) versus unsupported configurations (Featherstone, Semi-Implicit).
newton/_src/geometry/contact_reduction.py Contact-subsampling strategy that caps contacts per pair to preserve stability.
newton/_src/solvers/solver_semi_implicit.py Implements the Semi-Implicit back-end used in most stability examples.

Summary

  • Velocity clipping in newton/_src/solvers/solver.py automatically caps particle speeds to v_max, but rigid-body stability requires manual tuning of angular_damping.
  • Increasing substeps (e.g., to 30) effectively reduces the integration time step without changing scene geometry, resolving interpenetration and high-frequency chatter.
  • Friction smoothing (friction_smoothing=2.0) regularizes the Coulomb model to prevent stick-slip artifacts that destabilize contact stacks.
  • Solver selection determines constraint support: only SolverMuJoCo handles equality constraints (CONNECT, WELD), while Featherstone and Semi-Implicit solvers reject these configurations.
  • NaN detection should be implemented using the pattern in newton/tests/test_rigid_contact.py to catch numerical instability before it corrupts long simulation runs.

Frequently Asked Questions

What causes Newton simulations to suddenly produce NaN values or explode?

NaN values typically originate from unbounded velocity growth when angular_damping is too low for the scene's energy levels or when contact impulses create high-frequency oscillations without sufficient friction_smoothing. The integrate_particles function in newton/_src/solvers/solver.py clips velocities to prevent particle blow-up, but rigid bodies require explicit damping tuning. Check for NaNs after each step using numpy.isnan() on state.body_q and state.body_qd to catch instability early.

How do I fix persistent constraint violations in Newton joint simulations?

Constraint violations occur when joint stiffness parameters (joint_attach_ke, joint_attach_kd) are set too high without corresponding damping, causing "explosive" force computations. In newton/_src/solvers/semi_implicit/kernels_body.py, the angular_damping_scale factor (default 0.01) scales torque damping to maintain stability. Reduce stiffness values or increase the damping scale factor, and ensure you are using a solver that supports your constraint type—equality constraints require SolverMuJoCo according to the capability table in newton/solvers.py.

Why does my rigid body simulation jitter or drift even at low speeds?

Jitter and drift typically indicate insufficient angular damping or inadequate contact substepping. The default angular_damping=0.05 may be insufficient for tall stacks or high-friction contacts. Increase to 0.15 as demonstrated in newton/tests/test_rigid_contact.py. Additionally, increase substeps from the default (often 10) to 30 to reduce the effective time step and improve contact resolution without modifying scene geometry.

Which Newton solver should I use for simulations with equality constraints?

Use SolverMuJoCo for any simulation requiring equality constraints such as CONNECT, WELD, or mimic joints. The solver capability matrix in newton/solvers.py (lines 31-45) explicitly marks Featherstone and Semi-Implicit solvers as lacking support for these constraint types. Attempting to use equality constraints with unsupported solvers will raise "constraint not found" errors during simulation initialization.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →