This commit is contained in:
Jonas Bengtsson
2026-10-04 20:59:22 +02:00
parent f82e8d4be9
commit 68d3c42d79
12 changed files with 394 additions and 73 deletions
+17 -4
View File
@@ -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)