novaphy.MultiEnvRunner¶
RL-style runtime wrapper for a solver-bound multi-world Model.
MultiEnvRunner owns double-buffered SimState, one Control buffer,
optional collision contacts, episode counters, and done flags. It delegates
physics to the existing SolverBase.step(state_in, state_out, control,
contacts, dt) contract. It is not a simulation World object.
Construction¶
model = builder.finalize()
solver = novaphy.solvers.SolverFeatherstone(model)
runner = novaphy.MultiEnvRunner(solver, enable_collision=False)
The runner allocates states on model.device, so CPU and CUDA models keep
their runtime buffers on the same device as the bound solver model.
Core Properties¶
| Property | Description |
|---|---|
model |
Solver-bound Model. |
solver |
Solver used by step(...). |
state |
Current SimState buffer. |
next_state |
Scratch/output SimState buffer. |
control |
Current Control buffer. |
contacts |
Runner-owned Contacts buffer. |
num_envs |
Number of worlds/envs in the model. |
collision_enabled |
Whether the runner always performs collision before stepping. |
layout |
MultiEnvLayout metadata. |
Runtime Methods¶
| Method | Description |
|---|---|
action_dim() |
Per-env action/control dimension; all envs must have the same joint DOF count. |
reset_all(update_fk=True) |
Restore all env state from the initial state and clear counters/flags. |
reset_envs(env_ids, update_fk=True) |
Restore only the selected envs and clear matching counters/flags. |
set_actions(actions, env_ids=None) |
Write per-env control values into the flat control buffer. |
clear_actions(env_ids=None) |
Clear all or selected per-env control values. |
set_done_flags(terminated, truncated) |
Replace per-env done flags. |
step(dt, substeps=1, collide=False) |
Advance one outer step of duration dt, split into substeps solver calls of dt / substeps. |
Layout Methods¶
| Method | Description |
|---|---|
env_origin(env_id) |
Return one env origin from the runner layout. |
set_env_origins(origins) |
Replace runner layout origins. |
set_linear_layout(spacing) |
Set a linear runner layout. |
set_grid_layout(spacing, columns=0) |
Set a grid runner layout. |
Layout setters update only runner metadata. They do not rewrite the immutable
Model.world_origins captured during ModelBuilder.finalize().
NumPy Copy Properties¶
| Property | Description |
|---|---|
env_origins |
NumPy copy of runner layout origins. |
episode_length |
NumPy copy of per-env episode counters. |
terminated |
NumPy copy of per-env task termination flags. |
truncated |
NumPy copy of per-env truncation flags. |
In-place edits to these arrays do not write back to the runner. Use
reset_envs(), reset_all(), set_done_flags(), or layout setter methods
to update runner-owned state.
Collision Notes¶
When collision_enabled=True or step(..., collide=True) is used, the runner
updates its contacts before each solver substep. When collision is disabled
and collide=False, it passes None to the solver.
Replicated worlds share broadphase storage, but the collision pipeline filters
pairs whose two non-global shapes have different world indices. Shapes with
world=-1 are global (for example a shared ground) and may interact with
every world. Physical spacing is still useful for visualization and for any
intentionally global geometry; it is not required to isolate ordinary
per-world shapes.