Solvers are used to integrate the dynamics of a Newton model.
The typical workflow is to construct a Model and a State object, then use a solver to advance the state forward in time
via the step() method:
Choosing a Solver
MuJoCo, Kamino, and VBD currently have dedicated backend guides:
MuJoCo — generalized-coordinate rigid-body simulation and
MuJoCo or MJCF workflows.
Kamino — constrained rigid mechanisms with kinematic loops
and hard frictional contacts; experimental.
VBD — unified simulation of cloth, soft bodies, and rigid
bodies in a single VBD-based solver; experimental.
The other solver backends are documented through their linked API references
and the comparison tables below.
For a rigid articulated robot, first decide which coordinate representation
fits the application. SolverMuJoCo and
SolverFeatherstone use generalized coordinates, while
SolverXPBD,
SolverSemiImplicit, and
SolverKamino use maximal coordinates. For deformable
bodies, particles, or differentiable simulation, use the feature matrix below
to narrow the choice, then follow the linked API documentation.
Joint Feature Support
Not every solver supports every joint type or joint property.
The tables below document which joint features each solver handles.
Only SolverFeatherstone and SolverMuJoCo
operate on articulations (generalized/reduced coordinates).
The maximal-coordinate solvers (SolverSemiImplicit,
SolverXPBD, and SolverKamino)
enforce joints as pairwise body constraints but do not use the articulation kinematic-tree structure.
SolverVBD supports a subset of joint types through maximal-coordinate
constraints, with unified compliant ALM by default and a deprecated legacy AVBD path.
SolverStyle3D and SolverImplicitMPM do not support joints.
Joint types
1 DISTANCE joints are treated as FREE (no distance constraint enforcement).
Joint properties
2 Not enforced for BALL joints in SemiImplicit.
Actuation and control
Constraints
3 Featherstone eliminates follower degrees of freedom from its reduced dynamics and transfers follower forces and inertia to the reference joint.
4 SemiImplicit enforces joint-owned mimic relationships with penalty springs configured by joint_mimic_ke and joint_mimic_kd.
5 XPBD and VBD enforce joint-owned mimic relationships through coupled maximal-coordinate corrections. Both apply one mimic correction per solver iteration.
6 MuJoCo lowers each joint-owned relationship to joint equality constraints. Multi-axis D6 relationships produce one equality constraint per axis.
7 VBD interprets joint_target_kd and joint_limit_kd as absolute damping coefficients in physical units.
Particle-Body Attachments
A particle-body attachment ties one cloth or solid particle to a point in a
rigid body’s local frame. Author attachments with
newton.ModelBuilder.add_attachment_particle_body(). They are stored on the
Model and do not require a coupled solver.
SolverVBD applies an attachment whenever it integrates
both endpoints. The attachment is compliant rather than rigid: it contributes a
quadratic penalty with stiffness [N/m] and damping [N·s/m], so a heavily
loaded attachment keeps a small offset instead of holding the particle exactly.
The constraint is translational, similar to the positional part of a ball joint;
a single particle has no orientation, so there is no angular counterpart. Forces
are equal and opposite, including the torque about the body’s center of mass, and
the path is independent of contact, so it stays active without penetration.
Both endpoints must be integrated by the same solver, so
SolverVBD rejects attachments when it is constructed
with integrate_with_external_rigid_solver=True.
When the endpoints belong to two different solvers in a coupled simulation,
SolverCoupledADMM turns the same
model rows into cross-solver interface constraints; see ADMM Coupling.
The two cases are mutually exclusive, so no attachment is applied twice, and a
row whose body or particle is owned by no solver applies no force at all. The
coupler also warns when both endpoints belong to one entry whose solver does not
support attachments.
Differentiability
Differentiable simulation in Newton typically runs a forward rollout inside
wp.Tape(), computes a scalar loss from the simulated state, and then calls
tape.backward(loss) to populate gradients on differentiable state,
control, or model arrays. In practice, this starts by calling
finalize() with requires_grad=True.
import warp as wp
import newton
@wp.kernel
def loss_kernel(particle_q: wp.array[wp.vec3], target: wp.vec3, loss: wp.array[float]):
delta = particle_q[0] - target
loss[0] = wp.dot(delta, delta)
builder = newton.ModelBuilder()
builder.add_particle(pos=wp.vec3(0.0, 0.0, 0.0), vel=wp.vec3(1.0, 0.0, 0.0), mass=1.0)
model = builder.finalize(requires_grad=True)
solver = newton.solvers.SolverSemiImplicit(model)
state_in = model.state(requires_grad=True)
state_out = model.state(requires_grad=True)
control = model.control()
loss = wp.zeros(1, dtype=float, requires_grad=True)
target = wp.vec3(0.25, 0.0, 0.0)
tape = wp.Tape()
with tape:
state_in.clear_forces()
solver.step(state_in, state_out, control, None, 1.0 / 60.0)
wp.launch(
loss_kernel,
dim=1,
inputs=[state_out.particle_q, target],
outputs=[loss],
)
tape.backward(loss)
initial_velocity_grad = state_in.particle_qd.grad.numpy()
assert float(initial_velocity_grad[0, 0]) < 0.0
See the DiffSim examples on GitHub for the current reference workflows.