Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Environment Configuration — Particles

Space Robotics Bench can simulate liquid and granular materials like regolith, sand, and dust using particle-based physics. This is particularly relevant for space applications where interaction with loose granular material is common.

Enabling Particles

You can enable particles in any environment by setting the particles parameter to true:

srb agent teleop -e _manipulation env.particles=true env.robot=franka+scoop

Particle Configuration Parameters

Most particle parameters accept either a single scalar (used for every particle system) or a (min, max) 2-tuple that is interpolated across env.particles_systems to produce a graded distribution. Defaults below are taken from BaseEnvCfg (srb/core/env/common/base/env_cfg.py).

ParameterDescriptionDefault
env.particlesEnable particle simulationfalse
env.particles_systemsNumber of independent particle systems per environment1
env.particles_spawnerPile spawner kernel — grid or pyramidgrid
env.particles_sizeParticle diameter in metres (scalar or (min, max) 2-tuple)(0.01, 0.005)
env.particles_areaFootprint of the pile (scalar or 2-tuple)(0.75, 0.5)
env.particles_ratioVolume-fill ratio (scalar or 2-tuple)(0.025, 0.1)
env.particles_heightStack height per system (integer scalar or 2-tuple)(1, 10)
env.particles_densityBulk material density (kg/m³)1600.0
env.particles_frictionParticle–particle friction coefficient1.0
env.particles_dampingVelocity damping0.2
env.particles_cohesionCohesion (particle–particle stickiness)0.01
env.particles_adhesionAdhesion (particle–surface stickiness)0.05
env.particles_materialVisual-material override for the particle set (advanced — a VisualMaterialCfg, not a scalar)None
env.particles_dim_xyOverride grid count (dim_x = dim_y) per systemNone (derived)
env.particles_init_posExplicit (x, y, z) placement of the first systemNone (derived)
env.particles_freezeFreeze systems after they settle — the solver stops but the settled geometry keeps rendering (for clean renders)false
env.particles_conform_to_terrainSnap particles onto the terrain height field instead of PBD settlingfalse
env.particles_conform_jitterRandom XY scatter (metres) applied when conforming to terrain (0 keeps the regular grid)0.0
env.particles_pile_center_jitterPer-reset random XY offset (metres) of the whole settled pile — domain randomization of pile location (0 disables)0.0
srb agent teleop -e _manipulation env.particles=true \
  env.particles_size=0.01 env.particles_ratio=0.1

Particle Behavior

The default grid spawner produces a regular tessellation of particles within particles_area. Switch to particles_spawner=pyramid for natural-looking piles with higher density at the centre. Multi-system stacking (particles_systems>1) layers piles vertically and supports gradients across particle size, area, ratio, etc. Particles collide with rigid bodies and articulations, settle under gravity, and can be pushed, scooped, or otherwise manipulated by the agent.

In the particle tasks (excavation, terrain_landscaping) the agent additionally observes a heightmap of the particle surface. PhysX particle sets are not raycastable, so this heightmap is derived at runtime from the live particle positions rather than from a ray sensor — it tracks the pile as it is reshaped. The landscaping tasks route that derivation through a versioned external-heightmap seam with a fixed footprint-aware surface rule, not through ad-hoc binning.

Note: When particles are enabled, Fabric is automatically disabled (env.sim.use_fabric=false) so that the underlying PhysX particle simulation receives consistent state.

Where Particles Are Simulated vs. Where They Are Read

These are two different places, and the distinction is operationally load-bearing:

  • The solver is GPU-only. PhysX PBD particles require GPU dynamics. When GPU dynamics are unavailable, PhysX rejects every particle set at parse time with Particles feature is only supported on GPU. Please enable GPU dynamics flag in Property/Scene of physics scene! and the particles stay bit-identically inert — while rigid bodies in the same stage keep behaving normally. A CUDA-capable NVIDIA GPU is required for any particle task.
  • The per-particle readback is the CPU-facing USD transport (UsdGeom.Points), fed by that GPU solver. On the pinned Isaac Sim 6.0.1 build there is no direct/Fabric per-particle alternative: omni.physics.tensors.SimulationView exposes only cloth, material and system-level particle views, and isaacsim.core.prims.ParticleSystem is system-level. This was probed on the installed build, not assumed.
  • Consequently the landscaping tasks pin sim.device = "cpu". Isaac Sim 6’s CUDA direct-data pipeline does not synchronize PBD particle positions or velocities back to the USD points consumed by the heightmap, the reward, and the renderer.

Trap — a persisted Kit setting can silently disable all particles. The app-global /persistent/physics/overrideGPUSettings value overrides the authored per-scene physxScene:enableGPUDynamics=true. A machine on which “Force CPU” was ever selected in the UI keeps 0 in kit/data/Kit/IsaacLab/*/user.config.json and will produce a completely inert particle bed in every scene. SRB now clears that override at spawn time (with a warning) instead of trusting machine state. Measured enum: -1 = use per-scene settings, 0 = force CPU, 1/2 = force GPU.

Each spawned particle set also authors an explicit simulationOwner relationship, which must equal the configured env.sim.physics_prim_path; a missing or non-UsdPhysics.Scene owner fails fast rather than falling back to stage traversal. Note that ownership is a determinism invariant, not a motion prerequisite — an unowned set still moves, and blaming a missing owner for inert particles is a diagnosis error the repository has already made once.

Known limitation — cloned environments. Per-particle state is read and written in prim-local coordinates while being exposed as world-frame buffers, so with env.num_envs > 1 the beds of cloned environments collapse onto the world origin seam. Particle tasks are currently single-environment only.

Domain Randomization

Regolith interaction is a prime sim-to-real gap, so a few knobs randomize the granular material to keep a policy from overfitting one fixed pile:

  • env.particles_pile_center_jitter — on every reset the settled pile is restored and rigidly translated in XY by an independent per-environment sample in [-jitter, +jitter]. The pile keeps its settled shape (the translation is physically valid without re-settling), so 0.05 scatters where the pile sits by ±5 cm without changing its profile. 0 (the default) keeps the pile fixed.
  • The excavation and terrain-landscaping tasks additionally randomize the PhysX PBD particle material on every reset — friction is sampled in [0.6, 1.0] and density in [2700, 3100] kg/m³ — so the settled angle of repose and bulk behaviour vary trial-to-trial. This is wired into the tasks themselves rather than exposed as an env.* knob; in those two tasks env.particles_friction / env.particles_density therefore set the spawn baseline, not a per-episode constant.

Static Renders

For clean stills or offline datasets you often want the pile visible but motionless:

  • env.particles_freeze — after the initial settle completes, each system is disabled (its PhysX particleSystemEnabled flag is cleared and velocities zeroed). The settled points keep rendering, but the solver no longer simulates them, so the particles stay perfectly still. Pair it with the --snapshot capture for a frozen render bed.
  • env.particles_conform_to_terrain (optionally with env.particles_conform_jitter) snaps the spawned grid onto the terrain height field instead of PBD settling — useful when PBD settling is unavailable and you just need regolith that follows the terrain relief.