🚧 Rewrite continous simulation.
This commit is contained in:
+42
-37
@@ -580,44 +580,49 @@ unchanged whether or not CSV streaming is used.
|
||||
top-level `until:` bounding the run. All §8.3–8.4 machinery (degradation,
|
||||
invariants, rate limits, snapshots) applies identically, whether or not
|
||||
any CSV streaming is configured.
|
||||
- FR-8.2.14: **Plant environment abstraction** (requested 2026-10-04): the
|
||||
continuous engine exposes a gymnasium-style **environment object** —
|
||||
`PlantEnv` — as the single programmatic interface to the simulated plant.
|
||||
Per deterministic tick (the engine's fixed tick clock, FR-4.3.9 — never
|
||||
wall-clock), the cycle is:
|
||||
**`state = env.observe()`** → the caller (plant logic, an external
|
||||
agent, or the scenario) decides → **`env.apply(actions)`** writes the
|
||||
decided output values → the engine advances exactly one tick
|
||||
(edges, datasets, degradation, invariants — FR-8.2.12 order) → repeat.
|
||||
`observe()` returns the state of the **generic inputs** — the WAGO
|
||||
input process image in engineering units (all DI/DO/AI/AO channel
|
||||
values, per-type module/channel addressing, configurable channel
|
||||
names, plus the active aliases) — and `apply(actions)` maps decided
|
||||
values onto the **output process image** through the datastore's
|
||||
internal Modbus write paths, so mirrors, statistics, and watchdog
|
||||
behavior stay consistent (FR-9.2.6 semantics). The environment owns
|
||||
no policy: the plant model (physics, closed-loop control) is supplied
|
||||
by the caller, exactly like `gym.Env` vs. its agents.
|
||||
- FR-8.2.15: **Environment integration**: `PlantEnv` is the interface the
|
||||
per-tick plugins (FR-4.3.8) are migrated onto: a plugin becomes
|
||||
`env.observe()` → decide → `env.apply()` per tick, and a scenario may
|
||||
alternatively register an external `step(env)` agent — including a
|
||||
non-Python one (e.g., a trained RL policy) communicating over a
|
||||
socket/pipe — without touching the engine loop. The existing
|
||||
`plugins:` mechanism keeps working unchanged (thin adapter); the
|
||||
engine always owns the tick clock, and exactly one decision source
|
||||
may drive an output alias per tick (ownership conflicts are validation
|
||||
errors, extending FR-8.2.2).
|
||||
- FR-8.2.14: **Plant environment abstraction** (requested 2026-10-04,
|
||||
reworked same day to environment-first): `PlantEnv` is the **primary
|
||||
interface** for continuous plant simulation, standalone-first — it
|
||||
requires only a virtual node + datastore (no scenario), with the §8.3/8.4
|
||||
machinery (degradation, invariants) as optional attachments. Per
|
||||
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 — →
|
||||
`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).
|
||||
- FR-8.2.15: **Action semantics**: `apply()` primarily writes the **input
|
||||
side (DI/AI)** — the simulated field: what the sensors show, driven by
|
||||
plant physics reacting to the PLC's output commands. Writing outputs
|
||||
(DO/AO) is allowed as explicit **forcing** via a `force=True` keyword or
|
||||
`env.force(...)` — for headless runs without a PLC and for bench
|
||||
fault setup; forced outputs go through the datastore's internal write
|
||||
paths so mirrors/statistics/watchdog stay consistent (FR-9.2.6).
|
||||
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` (channel values, names, I/O codes,
|
||||
ranges, sim-time, wear/parameters); `env.apply(actions) -> None`
|
||||
(actions keyed by I/O code or alias name; unknown keys are errors);
|
||||
`env.reset(config) -> PlantState` (fresh episode, deterministic
|
||||
seed); `env.tick_ms`, `env.sim_time_ms` (read-only clock); and the
|
||||
full §8.3/§8.4 machinery (parameters, degradation, invariants,
|
||||
snapshots) reachable as `env.parameters`, `env.invariants`. The same
|
||||
object is served over the scenario-run HTTP API in server mode (§9),
|
||||
so external agents can run against a live PLC-connected bench.
|
||||
`env.observe() -> PlantState` (all channels, 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.
|
||||
- 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
|
||||
(`--env myenvs.pump_station.PumpStationEnv`), or a module-level
|
||||
factory function. Two runners: (a) `wago-sim serve --env ...` ticks
|
||||
the environment on a **wall-clock-paced** periodic task (10 ms tick
|
||||
alongside the Modbus server, real-time behavior for a live PLC) and
|
||||
runs **until manually stopped** (SIGINT/SIGTERM — the existing
|
||||
graceful-shutdown path); (b) `wago-sim sim --node ... --env ...`
|
||||
runs headless unpaced (as fast as determinism allows) until
|
||||
`is_done()` or SIGINT. The scenario-continuous mode (FR-8.2.1-13)
|
||||
remains a scripted layer on top of the same engine ticks.
|
||||
|
||||
### 8.3 Requirements — degradation models (plant logic over time)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user