Learn the rhythm of a periodic disturbance and get a protect-now decision plus the best protective action.
A disturbance anticipator learns the rhythm of a recurring disturbance —
something that hits your robot at a roughly regular interval — and tells you, at
any moment in time, whether to protect now and which registered protective
action is currently best.You feed it the times disturbances occur and the outcomes of protective
actions you deploy. It keeps the learned period, phase, and confidence entirely on
the server; you only ever see the decision.
Register the protective actions it may choose between, and (optionally) tune its
timing window.
from cadenza_cli import MeganTKtk = MeganTK()a = tk.anticipator( actions=["brace", "dodge"], # protective actions to choose between lead=1.4, # seconds to START protecting before a predicted hit guard=0.8, # seconds to KEEP protecting after min_events=2, # disturbances to observe before trusting the period)print(a.anticipator_id, a.actions)
Like sessions, it’s a context manager:
with tk.anticipator(actions=["brace", "dodge"]) as a: ...# anticipator deleted automatically
Call disturbance(t) each time the disturbance actually occurs, passing the time
(in seconds) it happened. After min_events observations it locks onto the period.
for t in (0.0, 2.0, 4.0): # a ~2s periodic disturbance status = a.disturbance(t=t)status # {'anticipator_id': ..., 'ready': True, 'best_action': 'brace'}
ready flips to True once it has learned enough to act on.
When you deploy a protective action, tell the anticipator whether it saved the
outcome. This is how it learns which action is best; over time best_action
reflects what actually protects you.
a.outcome("brace", saved=True) # 'brace' preserved the outcomea.outcome("dodge", saved=False) # 'dodge' didn't help this time
name must be one of the actions you registered when opening the anticipator. An
unregistered name is rejected (HTTP 422 → MeganTKError).
Ask, at a given time t, whether to protect right now:
p = a.protect(t=5.9) # just before the next ~6.0s hitp.should_protect # True → engage a protective action nowp.best_action # 'brace' → which onep.ready # True → the rhythm is learned; if False, treat as advisory
protect() returns a ProtectResult. The
predicted time of the next hit, the period, and the confidence are withheld so
the rhythm model can’t be reconstructed — you get the actionable answer only.
from cadenza_cli import MeganTKtk = MeganTK()with tk.anticipator(actions=["brace", "dodge"], min_events=2) as a: for event in control_loop(): # your real-time loop if event.disturbance_detected: a.disturbance(t=event.t) p = a.protect(t=event.t) if p.should_protect and p.ready: saved = actuators.engage(p.best_action) # deploy it a.outcome(p.best_action, saved=saved) # close the learning loop
The anticipator and a token session compose cleanly: run a
session to govern task progress while an anticipator guards against a periodic
disturbance in the same loop. See
Building deep.