pub struct ObsPlan { /* private fields */ }Expand description
Compiled observation plan: either Simple or Standard class.
Simple (all Fixed regions): pre-computed gather indices, branch-free
loop, zero spatial computation at runtime. Use execute.
Standard (any agent-relative region): template-based gather with
interior/boundary dispatch. Use execute_agents.
Implementations§
Source§impl ObsPlan
impl ObsPlan
Sourcepub fn compile_bound(
spec: &ObsSpec,
space: &dyn Space,
generation: WorldGenerationId,
) -> Result<ObsPlanResult, ObsError>
pub fn compile_bound( spec: &ObsSpec, space: &dyn Space, generation: WorldGenerationId, ) -> Result<ObsPlanResult, ObsError>
Compile with generation binding for PLAN_INVALIDATED detection.
Same as compile but records the snapshot’s
world_generation_id for later validation in ObsPlan::execute.
Sourcepub fn output_len(&self) -> usize
pub fn output_len(&self) -> usize
Total number of f32 elements in the output tensor.
Sourcepub fn compiled_generation(&self) -> Option<WorldGenerationId>
pub fn compiled_generation(&self) -> Option<WorldGenerationId>
The generation this plan was compiled against, if bound.
Sourcepub fn execute(
&self,
snapshot: &dyn SnapshotAccess,
engine_tick: Option<TickId>,
output: &mut [f32],
mask: &mut [u8],
) -> Result<ObsMetadata, ObsError>
pub fn execute( &self, snapshot: &dyn SnapshotAccess, engine_tick: Option<TickId>, output: &mut [f32], mask: &mut [u8], ) -> Result<ObsMetadata, ObsError>
Execute the observation plan against a snapshot.
Fills output with gathered and transformed field values, and
mask with validity flags (1 = valid, 0 = padding). Both
buffers must be pre-allocated to output_len
and mask_len respectively.
engine_tick is the current engine tick for computing
ObsMetadata::age_ticks. Pass None in Lockstep mode
(age is always 0). In RealtimeAsync mode, pass the current
engine tick so age reflects snapshot staleness.
Returns ObsMetadata on success.
§Errors
ObsError::PlanInvalidatedif bound and generation mismatches.ObsError::ExecutionFailedif a field is missing from the snapshot.
Sourcepub fn execute_batch(
&self,
snapshots: &[&dyn SnapshotAccess],
engine_tick: Option<TickId>,
output: &mut [f32],
mask: &mut [u8],
) -> Result<Vec<ObsMetadata>, ObsError>
pub fn execute_batch( &self, snapshots: &[&dyn SnapshotAccess], engine_tick: Option<TickId>, output: &mut [f32], mask: &mut [u8], ) -> Result<Vec<ObsMetadata>, ObsError>
Execute the plan for a batch of N identical environments.
Each snapshot in the batch fills output_len() elements in the
output buffer, starting at batch_idx * output_len(). Same for
masks. This is the primary interface for vectorized RL training.
Returns one ObsMetadata per snapshot.
Sourcepub fn execute_agents(
&self,
snapshot: &dyn SnapshotAccess,
space: &dyn Space,
agent_centers: &[Coord],
engine_tick: Option<TickId>,
output: &mut [f32],
mask: &mut [u8],
) -> Result<Vec<ObsMetadata>, ObsError>
pub fn execute_agents( &self, snapshot: &dyn SnapshotAccess, space: &dyn Space, agent_centers: &[Coord], engine_tick: Option<TickId>, output: &mut [f32], mask: &mut [u8], ) -> Result<Vec<ObsMetadata>, ObsError>
Execute the Standard plan for N agents in one environment.
Each agent gets output_len() elements starting at
agent_idx * output_len(). Fixed entries produce the same
output for all agents; agent-relative entries are resolved
per-agent using interior/boundary dispatch.
Interior agents (~49% for 20×20 grid, radius 3) use a branchless fast path with stride arithmetic. Boundary agents fall back to per-cell bounds checking.
Sourcepub fn is_standard(&self) -> bool
pub fn is_standard(&self) -> bool
Whether this plan requires execute_agents (Standard) or execute (Simple).