newton.CollisionSubstepScheduler#
- class newton.CollisionSubstepScheduler(collision_pipeline, states, *, collision_callback, substep_callback, frame_dt, substeps, collision_dt_max=None)[source]#
Bases:
objectSchedule collision refreshes over a fixed number of simulation substeps.
The scheduler always invokes
substep_callbackexactlysubstepstimes per frame. It invokescollision_callbackbefore substep zero and thereafter whenever the accumulated global relative-travel estimate would exhaust the configured budget or the previous collision horizon expires. The speed bound is reevaluated after every substep, including the final substep for overflow reporting. Selection stays on the device and useswarp.capture_if(), so it is compatible with CUDA graph capture.During the collision callback, the supplied pipeline reserves at least
speculative_contact_gap_maxof pairwise detection distance, independently of velocity. Authored gaps and physical margins are preserved. The callback must call this pipeline; calls outside the callback keep their usual velocity-adapted behavior. The reserve can increase contact counts.Velocity changes alone do not invalidate reserved candidates. Scheduling is based on instantaneous rigid-shape velocities and observed speed increases. It reacts to acceleration and impulses after a completed substep; it does not bound unobserved forces or impulses within the next substep. This is an optimization for speculative rigid contacts, not continuous collision detection, and sufficiently abrupt motion can still tunnel through thin geometry. Use enough solver substeps for the expected acceleration and impulses.
step()works both directly and during CUDA graph capture. When an outer capture is active, the complete fixed schedule is recorded inline. CUDA graph conditional nodes require CUDA 12.4 or newer.The two states are used as ping-pong buffers.
substepsmust be even so every frame begins and ends instates[0]. Callbacks must be capture-safe and must preallocate all storage before the first call.Experimental
This scheduling API may change without notice.
- Parameters:
collision_pipeline (CollisionPipeline) – Speculative collision pipeline whose model and extension limit determine the schedule.
states (Sequence[State]) – Two simulation states used as input/output ping-pong buffers.
collision_callback (Callable[[State, float], None]) – Called as
callback(state, collision_dt)before each scheduled collision refresh.collision_dtis the planned horizon until the next refresh [s], capped at the frame boundary; faster observed travel may trigger an earlier refresh.substep_callback (Callable[[State, State, float], None]) – Called as
callback(state_in, state_out, dt)exactlysubstepstimes per frame.frame_dt (float) – Fixed frame duration [s].
substeps (int) – Fixed positive even number of solver substeps per frame.
collision_dt_max (float | None) – Maximum time between collision refreshes [s]. The actual interval is rounded down to a whole number of solver substeps and capped at one frame, even if the limit exceeds
frame_dt. Intervals need not dividesubsteps. IfNone, refresh frequency is limited only by the relative-travel estimate.
- Raises:
TypeError – If collision_pipeline is not a CollisionPipeline, either callback is not callable, or substeps is not an integer or is a bool.
ValueError – If speculative contacts are disabled, the pipeline contains particles, the states are not two distinct compatible rigid-body buffers, or a numeric configuration value is invalid.
- __init__(collision_pipeline, states, *, collision_callback, substep_callback, frame_dt, substeps, collision_dt_max=None)#
- step()#
Execute or record one complete fixed-substep frame.
- interval_overflow#
Device scalar set when observed per-substep or accumulated travel exceeds the budget.