Skip to content

novaphy.solvers.SolverXPBD

Extended Position-Based Dynamics (XPBD) solver in maximal coordinates. Resolves contacts and joints as position-level constraints with compliance, suitable for stiff stacks and welds where Sequential Impulse can drift.

XPBD does not inner-substep; the simulation loop is responsible for choosing dt. The Newton-strict wrapper pins settings.substeps = 1 so calls match Newton's effective dt 1:1.

Pipeline

graph LR
    A[Predict<br/>positions] --> B[Project<br/>contacts]
    B --> C[Project<br/>joints / welds]
    C --> D[Velocity<br/>update]

For each iteration:

  1. Predict positions via semi-implicit Euler.
  2. Project contact constraints with rigid_contact_relaxation.
  3. Project joint and weld constraints with per-joint relaxation / compliance values.
  4. Recover velocities from position deltas.

Constructor

novaphy.solvers.SolverXPBD(
    model, *,
    iterations: int = 2,
    soft_body_relaxation: float = 0.9,
    soft_contact_relaxation: float = 0.9,
    joint_linear_relaxation: float = 0.7,
    joint_angular_relaxation: float = 0.4,
    joint_linear_compliance: float = 0.0,
    joint_angular_compliance: float = 0.0,
    rigid_contact_relaxation: float = 0.8,
    rigid_contact_con_weighting: bool = True,
    angular_damping: float = 0.0,
    enable_restitution: bool = False,
)
Parameter Description
model Required.
iterations XPBD iteration count per step. Higher = stiffer constraints.
joint_linear_relaxation Per-iteration relaxation factor for prismatic / linear joint constraints.
joint_angular_relaxation Per-iteration relaxation factor for revolute / ball joint constraints.
joint_linear_compliance Linear compliance (Newton parity, not yet wired in NovaPhy).
joint_angular_compliance Angular compliance (Newton parity, not yet wired in NovaPhy).
rigid_contact_relaxation Per-iteration relaxation factor for rigid contacts.
rigid_contact_con_weighting Distribute corrections by contact count.
angular_damping Multiplicative angular damping per step.
enable_restitution Enable restitution in the position projection step.
soft_body_relaxation, soft_contact_relaxation Newton parity (soft body / soft contact paths not yet implemented in NovaPhy).

Post-Construction Tuning

Additional NovaPhy-specific XPBD knobs:

solver.settings.<field> Type Description
substeps int Inner substeps. Pinned to 1 by the Newton-strict wrapper; override only for legacy NovaPhy substepping behaviour.
iterations int Mirrors iterations ctor kwarg.
velocity_damping float NovaPhy-specific multiplicative velocity damping.
contact_relaxation float Lower-level contact relaxation knob.
friction_damping float Friction damping factor.
solver = novaphy.solvers.SolverXPBD(model, iterations=20)
solver.settings.velocity_damping = 0.99

Example

import numpy as np
import novaphy

builder = novaphy.ModelBuilder()
builder.add_ground_plane(y=0.0)
# ... add rigid bodies and shapes ...

solver = novaphy.solvers.SolverXPBD(
    builder.finalize(),
    iterations=20,
    rigid_contact_relaxation=0.8,
    enable_restitution=True,
)

model    = solver.model
state    = model.state()
control  = model.control()
pipeline = novaphy.CollisionPipeline(model)
contacts = pipeline.contacts()

for _ in range(1000):
    pipeline.collide(state, contacts)
    solver.step(state, state, control, contacts, 1.0 / 120.0)

When To Use

Scenario Recommendation
Stable stacks / piles where impulse drift is visible XPBD is robust.
Welds, distance constraints, tight joint constraints Position-level projection handles these well.
Real-time small scenes Comparable to SolverSemiImplicit; profile on your workload.
Articulated robots with reduced-coordinate semantics Use SolverFeatherstone (XPBD operates in maximal coordinates).

Demos

Demo What it shows
python/demos/xpbd/demo_xpbd_stack.py Supported wall stack.
python/demos/xpbd/demo_xpbd_weld.py Welded bodies with XPBD weld constraint.
python/demos/demo_pyramid_ball.py --solver xpbd Pyramid stack solved with XPBD.
python/demos/demo_100_robots.py --solver xpbd Many quadrupeds via XPBD.

See Also