Skip to content

Multi-rate plants

The base step dt must suit the fastest part of a plant. Slower parts can update less often: they cost less, and a controller can run at its real scan rate.

seed: 1
duration: 12h
dt: 1s
library: process@1

units:
  - {id: FIC-101, template: flow_loop, sp: 20, span: [0, 40]}           # fast: every step
  - {id: TIC-102, template: heat_exchanger, sp: 70, period: 10s}        # slow: every 10 s
  - {id: TIC-103, template: temperature_loop, sp: 80, scan: 5s}         # a controller scanned every 5 s

exogenous:
  - {target: TIC-102.flow, from: FIC-101.cv}
  • period on a unit makes every operator of the unit update at that period; period also applies to a custom operator.
  • scan on a loop template sets the controller's scan period. It overrides the unit's period for the controller.

A period must be a whole multiple of dt; anything else is an error (E_BAD_PERIOD).

How a slow operator behaves

An operator with a period of n steps is discretized exactly for its own step, updates only on its turn, and holds its outputs in between. It also draws random numbers only on its turn, so a slow noise source is as slow as its period says. The result on the base grid is exactly the result of running that operator alone at the coarser step.

Other operators read its held outputs at every base step, which is how a sampled-data controller behaves in a real plant: its output changes at each scan and holds between scans.

Settling (init: steady) keeps the same schedule, and compares the states over windows long enough for every operator to take its turn.

In Python

With the core API, meta sets an operator's period, and phase its offset within the period:

from homeostat.core import Graph
from homeostat.core.operators import FirstOrder, Schedule

g = Graph()
g.add(Schedule("u", value=1.0))
g.add(FirstOrder("y", K=2.0, tau=30.0), inputs={"u": "u"}, meta={"period": 10.0, "phase": 2.0})

An operator with a phase takes its first turn at the phase: before it, it shows outputs from its initial state and does not update.