🚧 WIP
This commit is contained in:
@@ -588,7 +588,8 @@ unchanged whether or not CSV streaming is used.
|
||||
deterministic tick (the engine or the runner advances the tick clock,
|
||||
never wall-clock arithmetic): **`state = env.observe()`** returns the
|
||||
state of ALL modules — DI/DO/AI/AO channels, engineering units, per-type
|
||||
I/O codes, configured names, plus active aliases and parameters — →
|
||||
I/O codes, configured names, analog display ranges (FR-10.2.14),
|
||||
plus active aliases and parameters — →
|
||||
`env.model(state, dt)` (the caller-supplied plant physics) → **`apply()`
|
||||
writes the new field state**. The environment owns no policy; plant
|
||||
models are supplied by subclassing (FR-8.2.17).
|
||||
@@ -602,15 +603,19 @@ unchanged whether or not CSV streaming is used.
|
||||
Exactly one decision source may own an alias per tick (ownership
|
||||
conflicts are validation errors, extending FR-8.2.2).
|
||||
- FR-8.2.16: **Environment API surface** (concrete):
|
||||
`env.observe() -> PlantState` (all channels, aliases, parameters,
|
||||
sim-time); `env.apply(values, force=False)` (keys: I/O code or alias
|
||||
`env.observe() -> PlantState` (all channels with names and analog
|
||||
display ranges, aliases, parameters, sim-time); `env.apply(values, force=False)` (keys: I/O code or alias
|
||||
name; DI/AI default, DO/AO require force; unknown keys are errors);
|
||||
`env.model(state, dt_s)` — override point for plant physics, returning
|
||||
new field values; `env.is_done(state) -> bool` — optional end
|
||||
criterion, default False (runs until manually stopped);
|
||||
`env.reset()` — deterministic fresh episode; `env.tick_ms` /
|
||||
`env.sim_time_ms` (read-only clock); `env.parameters` /
|
||||
`env.invariants` attachments.
|
||||
`env.invariants` attachments. `PlantState.channel(key)` returns
|
||||
the full channel record by I/O code or by configured application
|
||||
name (FR-10.2.11); `by_code()` returns values by I/O code;
|
||||
`channel_range(key)` returns an analog channel's display range
|
||||
(min, max) — always defined for AI/AO (dense store, FR-10.2.14).
|
||||
- FR-8.2.17: **Environment authoring & runners**: environments are easy
|
||||
to create and call — a subclass of `PlantEnv` overriding `model()`
|
||||
(and optionally `is_done()`) in any importable module
|
||||
@@ -1056,6 +1061,14 @@ Terminal monitors (§9) suffice for single engineers, but FAT benches are
|
||||
onto the bar). Simulated AI values and AO forces accept negative
|
||||
numbers within the same window; values are stored in the image
|
||||
as their 16-bit two's-complement representation.
|
||||
**Dense runtime store** (2026-10-04): `node.channel_ranges` is
|
||||
always complete — every analog channel of the current layout has
|
||||
an entry (unconfigured channels carry the materialized default),
|
||||
codes that no longer match an analog channel are pruned on
|
||||
rebuild, so envs and API consumers can read ranges without
|
||||
default-fallback guesswork. Persistence (node YAML, config
|
||||
export) stays **lean**: only explicit non-default entries are
|
||||
written, so defaults survive a future DEFAULT_RANGE change.
|
||||
|
||||
### 10.3 Implementation decisions (binding, 2026-10-03)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user