newton.solvers.SolverXPBD#

class newton.solvers.SolverXPBD(model, *, iterations=2, soft_body_relaxation=0.9, soft_contact_relaxation=0.9, joint_linear_relaxation=0.7, joint_angular_relaxation=0.4, joint_linear_compliance=0.0, joint_angular_compliance=0.0, rigid_contact_relaxation=0.8, rigid_contact_con_weighting=True, angular_damping=0.0, enable_restitution=False, deterministic=None)[source]#

Bases: SolverBase, CouplingInterface

An implicit integrator using eXtended Position-Based Dynamics (XPBD) for rigid and soft body simulation.

References

  • Miles Macklin, Matthias Müller, and Nuttapong Chentanez. 2016. XPBD: position-based simulation of compliant constrained dynamics. In Proceedings of the 9th International Conference on Motion in Games (MIG ‘16). Association for Computing Machinery, New York, NY, USA, 49-54. https://doi.org/10.1145/2994258.2994272

  • Matthias Müller, Miles Macklin, Nuttapong Chentanez, Stefan Jeschke, and Tae-Yong Kim. 2020. Detailed rigid body simulation with extended position based dynamics. In Proceedings of the ACM SIGGRAPH/Eurographics Symposium on Computer Animation (SCA ‘20). Eurographics Association, Goslar, DEU, Article 10, 1-12. https://doi.org/10.1111/cgf.14105

After constructing Model, State, and Control (optional) objects, this time-integrator may be used to advance the simulation state forward in time.

Limitations:

Momentum conservation – When rigid_contact_con_weighting is enabled (the default), each body’s positional correction is divided by its number of active contacts. This improves convergence for stacking scenarios but means the solver does not conserve momentum at contacts. Reported per-contact forces (see update_contacts()) are approximate: for contacts between two dynamic bodies the force is computed using the harmonic mean of the two bodies’ contact counts, which is symmetric but not exact.

Reported parent-joint forces (see body_parent_f, populated when the extended state attribute is requested) are approximate. XPBD applies relaxation factors (joint_linear_relaxation, joint_angular_relaxation) to each joint constraint correction, and with a finite iterations count residual constraint error remains at end-of-step, so the reported wrench is the applied constraint reaction rather than the exact wrench needed to enforce the joint perfectly. The convention matches SolverFeatherstone and SolverMuJoCo: it is the spatial wrench transmitted from the parent through the inbound joint, in world frame at the child body’s COM, including both the constraint reaction and the body-frame contribution of joint_f. In equilibrium this wrench counters all applied forces (gravity, contacts, State.body_f) by Newton’s third law.

Joint limitations:

See Joint Feature Support for the full comparison across solvers.

Example

solver = newton.solvers.SolverXPBD(model)

# simulation loop
for i in range(100):
    solver.step(state_in, state_out, control, contacts, dt)
    state_in, state_out = state_out, state_in
__init__(model, *, iterations=2, soft_body_relaxation=0.9, soft_contact_relaxation=0.9, joint_linear_relaxation=0.7, joint_angular_relaxation=0.4, joint_linear_compliance=0.0, joint_angular_compliance=0.0, rigid_contact_relaxation=0.8, rigid_contact_con_weighting=True, angular_damping=0.0, enable_restitution=False, deterministic=None)#

Initialize the XPBD solver.

Parameters:
  • model (Model) – Simulation model to integrate.

  • iterations (int) – Number of constraint-solver iterations per time step. Defaults to 2.

  • soft_body_relaxation (float) – Relaxation factor applied to tetrahedral constraint corrections [dimensionless]. Defaults to 0.9.

  • soft_contact_relaxation (float) – Relaxation factor applied to particle-particle and particle-shape contact corrections [dimensionless]. Defaults to 0.9.

  • joint_linear_relaxation (float) – Relaxation factor applied to linear joint constraint corrections [dimensionless]. Defaults to 0.7.

  • joint_angular_relaxation (float) – Relaxation factor applied to angular joint constraint corrections [dimensionless]. Defaults to 0.4.

  • joint_linear_compliance (float) – Compliance shared by linear joint constraints [m/N]. Defaults to 0.0.

  • joint_angular_compliance (float) – Compliance shared by angular joint constraints [rad/(N·m)]. Defaults to 0.0.

  • rigid_contact_relaxation (float) – Relaxation factor applied to rigid contact constraint corrections [dimensionless]. Defaults to 0.8.

  • rigid_contact_con_weighting (bool) – Whether to divide each rigid body’s contact correction by its number of active contacts. Defaults to True.

  • angular_damping (float) – Rigid-body angular velocity damping coefficient [1/s]. Defaults to 0.0.

  • enable_restitution (bool) – Whether to apply restitution to rigid and particle-shape contacts after the positional solve. Defaults to False.

  • deterministic (DeterministicMode | None) – Opt-in determinism for this solver’s atomic-emitting kernel module. Pass a warp.DeterministicMode, or None (default) to inherit the current wp.config.deterministic mode.

copy_kinematic_body_state(model, state_in, state_out)#

Copy kinematic body poses and velocities from an input state to an output state.

Parameters:
  • model (Model) – Simulation model that owns the body data.

  • state_in (State) – State containing the source kinematic body poses and velocities.

  • state_out (State) – State that receives the kinematic body poses and velocities.

coupling_supports_inertial_property_refresh()#

Return whether inertial properties can be refreshed during graph capture.

Returns:

True because notify_model_changed() refreshes the derived inertial buffers with device work.

Return type:

bool

notify_model_changed(flags)#

Refresh cached body data after model properties change.

Effective inverse masses and inertia tensors are refreshed when BODY_PROPERTIES or BODY_INERTIAL_PROPERTIES is set. Other flags are ignored.

Parameters:

flags (ModelFlags | int) – Bitmask of ModelFlags or custom int bits indicating which model properties changed.

step(state_in, state_out, control, contacts, dt)#

Advance the simulation state by one time step using XPBD.

Parameters:
  • state_in (State) – State at the beginning of the time step.

  • state_out (State) – State that receives the simulation result.

  • control (Control | None) – Control inputs. If None, the model’s default control values are used.

  • contacts (Contacts | None) – Contact data produced by collide(). If None, rigid and particle-shape contact handling is skipped; particle-particle contacts and model constraints are still solved.

  • dt (float) – Time step size [s].

update_contacts(contacts, state=None)#

Populate contacts.force from XPBD contact impulses accumulated during the last step().

Both force [N] and torque [N·m] components are written. The torque includes torsional and rolling friction contributions that cannot be reconstructed from the linear force alone.

When rigid_contact_con_weighting is enabled, the raw per-contact impulse is scaled to reflect the 1/N correction that apply_body_deltas applies. For contacts between a dynamic and a kinematic body, N is the dynamic body’s contact count. For contacts between two dynamic bodies, the harmonic mean 2/(N_a + N_b) is used so that the reported force is symmetric with respect to body ordering. This is an approximation – the solver applies 1/N_a and 1/N_b independently to each side, so no single scalar can exactly represent both.

Parameters:
  • contacts (Contacts) – Contacts object whose force buffer will be written. Must have been created with "force" in its requested attributes and must match the Contacts instance (same rigid_contact_max) passed to the preceding step().

  • state (State | None) – Unused (accepted for API compatibility with SolverBase).

Raises:

ValueError – If contacts.force is None (not requested), if no step has been run yet, or if the contacts capacity does not match the one used in the last step().