API Reference#

This page is a map of the SAP Warp surface you normally touch from Python. It does not try to list every Newton-derived helper or Warp kernel; those modules remain implementation details unless they are needed to understand the SAP runtime path.

Read the reference in the same order as a simulation step:

  1. Load a scene with sim.loader.scene.load_sap_scene().

  2. Keep the returned sim.sap_runtime.SapModel, sim.sap_runtime.SapState, and sim.sap_runtime.SapControl objects as the solver boundary data.

  3. Build sim.collision.pipeline.SapCollisionPipeline from the collision model and call sim.collision.pipeline.SapCollisionPipeline.collide() whenever body poses change.

  4. Pass the active contacts into sim.solver_sap.SolverSAP.step().

The generated pages below give each documented object its own entry, while the short notes in this page explain why the object exists in the end-to-end loop.

Benchmark Entry Points#

Use these when you want to run the repository benchmark exactly as the command line tool does. They are thin orchestration helpers around the same loader, collision, and solver APIs shown later on this page.

benchmark.build_parser

Build the command-line parser for the benchmark entry point.

benchmark.run_native

Run the native SAP benchmark loop from parsed command-line arguments.

Scene Loader#

The loader is the bridge from tutorial examples and YAML/JSON scene files into runtime arrays. Start here when you need a model, initial state, control, and collision model without constructing Warp arrays by hand.

sim.loader.scene.load_sap_scene_config

Read a YAML or JSON scene file, validate its schema version, and return the raw configuration mapping.

sim.loader.scene.load_sap_scene

Load a scene file into SAP collision and solver runtime objects ready for benchmark or direct stepping code.

sim.loader.scene.SapLoadedScene

Loaded scene bundle returned by load_sap_scene.

sim.loader.scene.SapUnsupportedSceneFeature

Exception that reports scene features recognized by the loader but not yet supported by the SAP runtime.

Runtime Data#

Runtime data objects are plain containers around Warp arrays. SapModel is the immutable topology and default data, while SapState and SapControl are the mutable boundary objects you pass to a timestep.

sim.sap_runtime.SapModel

Immutable SAP model arrays describing topology, articulated bodies, shapes, materials, limits, drives, labels, and initial state for one or more replicated worlds.

sim.sap_runtime.SapState

Mutable SAP simulation state.

sim.sap_runtime.SapControl

Mutable control input for a SAP timestep, including generalized forces, drive targets, target velocities, and actuation values.

sim.sap_runtime.SapContacts

Compatibility contact bundle used by solver-facing SAP runtime code.

sim.sap_runtime.sap_model_from_newton

Convert a Newton model into an immutable SapModel with SAP-owned array conventions and optional debug mirrors.

sim.sap_runtime.sap_state_from_newton

Convert a Newton state into a SapState that uses the public boundary ordering expected by high- level callers.

sim.sap_runtime.sap_control_from_newton

Convert a Newton control object into SapControl arrays using the public generalized-force ordering.

sim.sap_runtime.sap_contacts_from_newton

Convert Newton contact storage into the SAP runtime contact bundle consumed by the solver.

Runtime Methods#

These methods allocate or reset runtime buffers. They are intentionally small, but they define the normal ownership pattern: create states and controls from the model, then clear only the buffers that should not carry over between steps.

sim.sap_runtime.SapModel.state

Create a mutable SapState initialized from the model position, velocity, body pose, and body velocity arrays.

sim.sap_runtime.SapModel.control

Create a SapControl object initialized from the model force, target, and actuation arrays.

sim.sap_runtime.SapState.clear_forces

Clear external body forces in place while leaving positions and velocities unchanged.

sim.sap_runtime.SapControl.clear

Clear direct forces, drive targets, target velocities, and actuation arrays in place.

Collision#

Collision APIs own the shape-side model and the active contact buffer. The pipeline is separate from the solver so callers can choose exactly when contact generation runs. The implementation deliberately tracks Newton’s collision data model for compatibility with imported assets and geometry behavior, then adapts the generated contacts into SAP-owned buffers. Hydroelastic contact support is in development; the documented API here covers the rigid-contact path.

sim.resources.collision_model.SapCollisionModel

Newton-compatible collision-side arrays consumed by SapCollisionPipeline.

sim.resources.collision_model.SapCollisionState

Collision-side state containing body poses in the shape model frame expected by SapCollisionPipeline.

sim.resources.collision_model.sap_collision_state_from_state

Extract the collision body-pose state from a SapState for use by SapCollisionPipeline.collide.

sim.collision.pipeline.SapCollisionPipeline

Newton-compatible collision front end that writes SAP-owned rigid contacts.

sim.collision.pipeline.sap_estimate_rigid_contact_max

Estimate a conservative rigid-contact capacity for a collision model when the caller did not provide one.

sim.collision.pipeline.sap_normalize_broad_phase_mode

Normalize a user-provided broad-phase mode string into the canonical mode used by SapCollisionPipeline.

sim.collision.contacts.SapContacts

Rigid contact storage consumed by SAP-owned collision generation.

Collision Methods#

Use contacts once to allocate the output buffer, then call collide each time current body poses should produce a new active contact set.

sim.collision.pipeline.SapCollisionPipeline.contacts

Allocate a SapContacts buffer sized for this pipeline and carrying any contact attributes requested by the model.

sim.collision.pipeline.SapCollisionPipeline.collide

Populate a SapContacts buffer from the current collision state by running AABB setup, broad phase, and narrow phase.

Solver#

The solver section contains the high-level timestepper and the three internal SAP stages that are useful when debugging or validating the solve: free motion, contact Jacobian assembly, and contact solve.

sim.solver_sap.SolverSAP

SAP-native solver pipeline.

sim.contact_jacobian.SapContactJacobian

Standalone Warp implementation of SAP-style contact preparation.

sim.contact_jacobian.SapContactJacobianResult

Views into buffers owned by SapContactJacobian.

sim.contact_solve.SapContactSolve

SAP SAP stage2 contact solve in SAP-order generalized velocities.

sim.contact_solve.SapContactSolveResult

Views into buffers owned by SapContactSolve.

sim.free_motion.SapFreeMotion

Standalone SAP-style free-motion calculation for articulated models.

sim.free_motion.SapFreeMotionResult

Views into the mutable output buffers owned by SapFreeMotion.

Solver Methods#

For normal use, sim.solver_sap.SolverSAP.step() is the method you call. The stage-specific methods are listed so advanced users can inspect the same data flow one stage at a time.

sim.solver_sap.SolverSAP.step

Advance one SAP timestep from state_in to state_out using control inputs, active contacts, and the configured solver settings.

sim.free_motion.SapFreeMotion.compute

Compute SAP free motion from SAP-native state/control.

sim.contact_jacobian.SapContactJacobian.compute

Build contact Jacobians, material parameters, gap values, and per-environment dynamics blocks for the SAP contact solve.

sim.contact_solve.SapContactSolve.solve

Solve the SAP velocity objective for the active contacts and write the next generalized velocity in SAP order.

Modules#

These modules are documented as modules because they collect helper kernels or stage-specific data that is easier to understand in context than as dozens of low-level entries.

sim.sap_helpers

Conversion and material helpers shared by the SAP runtime stages.

sim.contact_jacobian

Contact Jacobian assembly for the SAP velocity solve.

Minimal Program#

The shortest complete program follows the same sequence as the benchmark:

import warp as wp

from sim.collision.pipeline import SapCollisionPipeline
from sim.loader.scene import load_sap_scene
from sim.resources.collision_model import sap_collision_state_from_state
from sim.solver_sap import SolverSAP

num_worlds = 1
max_rigid_contact_per_env = 48
rigid_contact_capacity = max_rigid_contact_per_env * num_worlds
device = wp.get_device("cuda:0" if wp.is_cuda_available() else "cpu")

scene = load_sap_scene(
    "assets/yaml/unitree_g1_usd.yaml",
    device=device,
    rigid_contact_max=rigid_contact_capacity,
    num_worlds=num_worlds,
    strict=True,
)

solver = SolverSAP(
    scene.sap_model,
    max_rigid_contact=max_rigid_contact_per_env,
    contact_preset_variant="drake",
)
collision = SapCollisionPipeline(
    scene.collision_model,
    rigid_contact_max=rigid_contact_capacity,
)
contacts = collision.contacts()

state_0 = scene.sap_state
state_1 = scene.sap_model.state()
control = scene.sap_control

state_0.clear_forces()
collision.collide(sap_collision_state_from_state(state_0), contacts)
solver.step(state_0, state_1, control, contacts, 0.003)