newton.solvers.SolverBase#
- class newton.solvers.SolverBase(model, *, collision_pipeline=None, collision_frequency=None, collision_frequency_type=None)[source]#
Bases:
objectGeneric base class for solvers.
The implementation provides helper kernels to integrate rigid bodies and particles. Concrete solver back-ends should derive from this class and override
step()as well asnotify_model_changed()where necessary.- class CollisionFrequencyType(*values)#
Bases:
IntEnumWhen, inside a
step(), a solver-owned collision pipeline runs detection.The frequency number in
collision_frequencyapplies only toITERATIONS; the other members ignore it. Skipping detection across steps carries no hidden solver state — set a slot toNONEbetween steps viaset_collision_frequency().- AUTO = 4#
Solver-specific default.
- ITERATIONS = 3#
Before initialization, then immediately before iterations k, 2k, and so on.
- NONE = 0#
Never detect; the user may run detection externally into
contacts.
- PRE_INIT = 1#
Once per step, before solver initialization.
- PRE_POST_INIT = 2#
Before and after solver initialization (one detection each).
- class CollisionSlot(*values)#
Bases:
IntEnumCollision-detection categories scheduled by a solver.
- RIGID = 0#
Rigid-rigid and particle-shape collision detection.
- SOFT_SELF_CONTACT = 1#
Triangle-mesh soft self-contact detection.
- class ObservableKind#
Bases:
objectInheritable names for standard and solver-specific observable kinds.
Access kinds through
solver.ObservableKindand compose requests as sets. This is an ordinary namespace class of string constants: solvers may subclass it and declare new entries, such asBODY_TEMPERATURE = "body_temperature". Inherited names remain available. Literal strings and these constants are interchangeable in requests. Kind strings must be unique within a solver’s observable declarations.Subclasses are checked when defined. Every public attribute must be a nonempty string. Changing an inherited name’s value or assigning one string to different names raises an error, including conflicts between multiple parents. Redeclaring the same name with the same value is allowed. Attributes beginning with an underscore are excluded from these checks.
The available names do not imply solver support. Query
SolverBase.supported_observablesfor the effective capabilities of a configured solver. Use that set for iteration or requesting all supported observables; the namespace itself is not iterable.See Solver Observables for request and extension examples.
Experimental
The solver observable API may change without prior notice.
- BODY_PARENT_F = 'body_parent_f'#
Incoming parent-joint wrenches on rigid bodies.
- BODY_QDD = 'body_qdd'#
Rigid-body spatial accelerations.
- class Observables#
Bases:
objectArrays populated by a solver in addition to the simulation state.
Allocate a container once with
SolverBase.observables(), then pass that same container asobservables=to the allocating solver’sSolverBase.step()on each step that needs diagnostics. The solver writes requested results into the existing arrays during each such call; allocation alone does not register them for automatic updates.Solver implementations can derive from this class to add solver-specific arrays while retaining the standard Newton observables. Decorate derived containers with
@dataclass(eq=False)and declare arrays withfield(). Identity equality keeps containers usable as sources inArticulationViewcaches.See Solver Observables for allocation, selection, and custom field examples.
Experimental
The solver observable API may change while additional solvers and observable categories are migrated to it.
- static field(*, dtype, frequency, kind=None)#
Declare an optional observable array on a dataclass container.
See Solver Observables for custom observable declarations.
- Parameters:
dtype (type) – Warp element type, such as
wp.float32orwp.vec3.frequency (AttributeFrequency | str) – Row domain, not update cadence. Custom string frequencies use model count and articulation-ownership metadata.
kind (str | None) – Nonempty string identifying this observable. If omitted or
None, use the Python field name.
- Returns:
A dataclass field defaulting to
None. No array is allocated untilSolverBase.observables()requests it.- Raises:
TypeError – If an explicit kind is not a nonempty string or the frequency is not an attribute frequency or nonempty string.
- Return type:
Experimental
Experimental feature. API, behavior, defaults, and supported use cases may change without prior notice.
- __init__()#
- get_attribute_frequency(name)#
Return an array’s row domain, including inherited declarations.
- is_requested(kind)#
Return whether this container requests an observable on the current call.
This checks the request, not whether its values are fresh. It also returns True for requested zero-length arrays and during allocation.
- Parameters:
kind (str) – A standard or solver-specific observable name.
- select(kinds)#
Return a reusable subset sharing this container’s allocated arrays.
The result has the same concrete type, solver owner, and selected array objects, including gradients. Fields omitted from the selection are None in the result; this container is not modified. Stepping a subset therefore leaves the source’s omitted arrays unchanged.
Create selections before graph capture and reuse them across substeps. Only Python containers are created; no array allocation or copying is performed. Selections share the source’s contact-storage binding.
Derived containers with nested observable containers should override this method, call super(), and select their children in the result. Other solver-specific metadata is shallow-copied.
See Solver Observables for selection examples.
- Parameters:
kinds (Iterable[str]) – Subset of
kindsto request. An empty set requests no observables. Selecting a selection can only narrow it.- Returns:
A same-type container referencing the selected arrays.
- Raises:
TypeError – If kinds is not a collection of nonempty strings.
ValueError – If this container was not allocated by a solver or a kind is not requested by this container.
- Return type:
- body_parent_f: wp.array[wp.spatial_vectorf] | None = None#
Incoming parent-joint wrenches [N, N·m], shape
(body_count,).
- body_qdd: wp.array[wp.spatial_vectorf] | None = None#
Rigid-body accelerations [m/s², rad/s²], shape
(body_count,).
- contact_f: wp.array[wp.spatial_vectorf] | None = None#
Contact forces [N, N·m], shape
(rigid_contact_max + soft_contact_max,).
- classmethod register_custom_attributes(builder)#
Register custom attributes for the solver.
- Parameters:
builder (ModelBuilder) – The model builder to register the custom attributes to.
- __init__(model, *, collision_pipeline=None, collision_frequency=None, collision_frequency_type=None)#
Initialize common solver state and optional collision scheduling.
- Parameters:
model (Model) – Simulation model integrated by the solver.
collision_pipeline (CollisionPipeline | None) – Collision pipeline owned and driven by the solver. The pipeline must use
model, and the concrete solver must setsupports_collision_pipeline.collision_frequency (Mapping[CollisionSlot, int] | None) – Per-slot iteration frequencies. Values must be at least one and are used only for slots scheduled with
CollisionFrequencyType.ITERATIONS. Unspecified slots retain their defaults.collision_frequency_type (Mapping[CollisionSlot, CollisionFrequencyType] | None) – Per-slot detection points. Unspecified slots retain their defaults.
- integrate_bodies(model, state_in, state_out, dt, angular_damping=0.0)#
Integrate the rigid bodies of the model.
- Parameters:
model (Model) – The model to integrate.
state_in (newton.State) – The input state.
state_out (newton.State) – The output state.
dt (float) – The time step (typically in seconds).
angular_damping (float) – The angular damping factor. Defaults to 0.0.
- integrate_particles(model, state_in, state_out, dt)#
Integrate the particles of the model.
- Parameters:
model (Model) – The model to integrate.
state_in (newton.State) – The input state.
state_out (newton.State) – The output state.
dt (float) – The time step (typically in seconds).
- notify_model_changed(flags)#
Notify the solver that parts of the
Modelwere modified.The flags argument is a bit-mask composed of the
ModelFlagsenums or customintbits. Each flag represents a category of model data that may have been updated after the solver was created. Passing the appropriate combination of flags enables a solver implementation to refresh its internal buffers without having to recreate the whole solver object. Solver implementations must handle each relevant narrow DOF flag: checkingJOINT_DOF_PROPERTIESalone does not detect them. The broad flag covers force, inertial, and reference properties; friction/damping belongs to the force category. Solvers may ignore categories they do not cache or support, but should preserve unrelated pending edits except for documented backend dependencies. In MuJoCo, notifications that recompute constants also republish the current tendon limit modes, gains, raw solref values, and ranges, even withoutTENDON_PROPERTIES. Force-only joint notifications leave these tendon parameters unchanged. Valid flags are:ModelFlags.JOINT_PROPERTIES: Joint transforms, axes, or coordinates have changed.ModelFlags.JOINT_DOF_PROPERTIES: Full joint DOF update, including force, armature, and reference-pose properties (legacy behavior).ModelFlags.JOINT_DOF_FORCE_PROPERTIES: Joint friction, damping, target gains/modes, effort limits, passive stiffness, or limit coefficients/bounds have changed.ModelFlags.JOINT_DOF_INERTIAL_PROPERTIES: Joint armature has changed.ModelFlags.JOINT_REFERENCE_POSE_PROPERTIES: Joint reference poses or spring references have changed.ModelFlags.BODY_PROPERTIES: Rigid-body pose or velocity buffers have changed.ModelFlags.BODY_INERTIAL_PROPERTIES: Rigid-body mass or inertia tensors have changed.ModelFlags.SHAPE_PROPERTIES: Shape transforms or geometry have changed.ModelFlags.MODEL_PROPERTIES: Model global properties (e.g., gravity) have changed.ModelFlags.CONSTRAINT_PROPERTIES: Constraint definitions, coefficients, or enable flags have changed.ModelFlags.TENDON_PROPERTIES: Tendon stiffness or related tendon properties have changed.ModelFlags.ACTUATOR_PROPERTIES: Actuator gains, biases, limits, or force properties have changed.
- Parameters:
flags (ModelFlags | int) – Bit-mask of
ModelFlagsor customintbits indicating which model properties changed.
- observables(kinds, *, contacts=None, requires_grad=None)#
Allocate reusable arrays for requested solver observables.
See Solver Observables for allocation and usage examples.
A container is owned by the solver that allocates it and can be passed to that solver’s
step()method on every time step. Derived solvers add custom kinds toSUPPORTED_OBSERVABLESand declare fields on a dataclass derived fromSolverBase.Observables. The default allocator handles both standard and custom fields. Override this factory and delegate tosuper()when additional solver-specific initialization is needed.All requested arrays are allocated before this method returns; unrequested fields remain
None. Contact arrays use the model’s resolved rigid and soft capacities, not the live contact count. Allocate before graph capture and pass the sameContactstostep()and consumers.- Parameters:
kinds (Iterable[str]) – Required set or other iterable of observable names. Entries from
ObservableKindand literal strings are interchangeable. Passsupported_observablesto allocate all observables for this instance. An empty collection allocates no arrays.contacts (Contacts | None) – Contact storage to bind to contact-indexed observables. Required when any requested field has contact frequency, including zero-capacity fields. Its device and rigid/soft capacities must match the model. Ignored when no contact-indexed fields are requested.
requires_grad (bool | None) – Whether allocated arrays require gradients. If
None, use the model’s setting.
- Returns:
A solver-owned observable container with requested arrays allocated.
- Raises:
TypeError – If a request is not a collection of nonempty strings or the configured observable type does not derive from
SolverBase.Observables, or required contacts are not aContactsinstance.ValueError – If this solver does not support a requested observable or its container does not declare a unique field for the kind, or required contacts are missing or incompatible.
RuntimeError – If contact-indexed observables are requested before constructing
CollisionPipelinefor the model.
- Return type:
Experimental
The solver observable API may change while additional solvers and observable categories are migrated to it.
- reset(state, world_mask=None, flags=None)#
Reset the solver internal state data.
Modifies the given state in place. Derived solvers override this to reset solver-specific internal buffers or custom state attributes when environments are reset (e.g. during RL training).
The default implementation is a no-op so solvers that do not require special reset logic need not override this method.
- Parameters:
state (newton.State) – The simulation state to reset (modified in place).
world_mask (wp.array[wp.bool] | None) – Optional boolean mask of shape
(world_count + 1,)specifying which worlds to reset. Entries before the last select local worlds by index, and the final entry selects global entities whose world is-1. IfNone, all local and global entities are reset.flags (StateFlags | int | None) – Optional
StateFlagsorintbitmask controlling which state attributes need to be reset. IfNone, all state attributes are reset.
- set_collision_frequency(*, collision_frequency=None, collision_frequency_type=None)#
Change the detection schedule; takes effect at the next
step().The solver keeps no hidden cross-step scheduling state, so detecting every N steps is expressed by toggling a slot between
CollisionFrequencyType.NONEand an active type from the calling loop.Nonekeeps the corresponding current setting. Recapture an existing CUDA graph after changing the schedule.- Parameters:
collision_frequency (Mapping[CollisionSlot, int] | None) – Frequency numbers keyed by
CollisionSlot; used only byITERATIONSslots (before iterations k, 2k, and so on) and must be at least one.collision_frequency_type (Mapping[CollisionSlot, CollisionFrequencyType] | None) – Detection points keyed by
CollisionSlot.
- step(state_in, state_out, control, contacts, dt, *, observables=None)#
Simulate the model for a given time step using the given control input.
- Parameters:
state_in (newton.State) – The input state.
state_out (newton.State) – The output state.
control (Control | None) – The control input. Defaults to None which means the control values from the
Modelare used.contacts (Contacts | None) – The contact information.
dt (float) – The time step (typically in seconds).
observables (Observables | None) – Optional solver observable arrays allocated by
observables().
- update_contacts(contacts, state=None)#
Update a legacy Contacts object with forces from the solver state.
Deprecated since version 1.7: Request
ObservableKind.CONTACT_Fusingobservables()and pass the resulting container tostep()instead.
- validate_observables(observables, contacts=None)#
Validate ownership and contact storage before a custom solver step.
Call this at the start of
step(), before launching work or writing observable arrays. PassingNoneis a no-op. This checks only ownership and contact identity; layout validation happens during allocation.See Solver Observables for custom solver integration.
- Parameters:
observables (Observables | None) – Optional container allocated by this solver.
contacts (Contacts | None) – The instance supplied at allocation, required for contact-indexed observables.
- Raises:
TypeError – If the container has an incompatible type.
ValueError – If the owner or contact storage is incompatible.
Experimental
Experimental feature. API, behavior, defaults, and supported use cases may change without prior notice.
- SUPPORTED_OBSERVABLES: ClassVar[frozenset[str]] = frozenset({})#
Names of observables supported by this solver class.
Entries are string identifiers, such as
ObservableKind.BODY_QDD. Querysupported_observablesfor the capabilities of an instance.
- property collision_frequency: dict[CollisionSlot, int]#
Per-slot detection frequency numbers as a read-only copy.
- property collision_frequency_type: dict[CollisionSlot, CollisionFrequencyType]#
Per-slot
CollisionFrequencyTypevalues as a read-only copy.
- collision_pipeline#
The solver-owned collision pipeline, or
Nonewhen detection is driven externally.
- property contacts: Contacts | None#
The solver-owned contacts buffer, or
Nonewhen no pipeline is owned.Unlike
Model.contacts(), this property does not allocate; it returns the buffer created from the owned pipeline at construction. With a slot set toCollisionFrequencyType.NONEthe user may fill this buffer externally, e.g.pipeline.collide(state, solver.contacts).
- property device: Device#
Get the device used by the solver.
- Returns:
The device used by the solver.
- Return type:
wp.Device
- property supported_observables: frozenset[str]#
Names accepted by
observables()on this instance.Defaults to
SUPPORTED_OBSERVABLES. Solvers may narrow the class declaration for backend limitations, or derive capabilities from child solvers. Applications should query this property.See Solver Observables for available observables and backend limitations.
- supports_collision_pipeline: bool = False#
Whether this solver can own a
CollisionPipelineand drive detection itself.Currently only
SolverVBDopts in; passingcollision_pipelineto any other solver raisesValueError(drive detection externally instead).