Coverage for agentlib/modules/controller/bangbang.py: 0%
35 statements
« prev ^ index » next coverage.py v7.4.4, created at 2025-04-07 16:27 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2025-04-07 16:27 +0000
1from pydantic import Field
2from agentlib.core import Agent
3from agentlib.modules.controller import SISOController, SISOControllerConfig
4from agentlib.core.datamodels import AgentVariable
7class BangBangConfig(SISOControllerConfig):
8 """Special config for a BangBang-Controller"""
10 gain: float = Field(title="Gain of output", default=1)
13class BangBang(SISOController):
14 """
15 A bang–bang controller (2 step or on–off controller), also known as a
16 hysteresis controller, that switches abruptly between two states.
17 """
19 config: BangBangConfig
21 def __init__(self, *, config: dict, agent: Agent):
22 super().__init__(config=config, agent=agent)
23 self._last_out_val = self.get(self.config.output.name).value
25 @property
26 def gain(self):
27 """Get the gain of the BangBang controller"""
28 return self.config.gain
30 @property
31 def last_out_val(self):
32 """Last output value of the controller"""
33 return self._last_out_val
35 @last_out_val.setter
36 def last_out_val(self, out_val):
37 """Set the last output value of the controller"""
38 self._last_out_val = out_val
40 def loop_sim(self):
41 out_val = None
42 while True:
43 inp = yield out_val
44 out_val = self.do_step(inp_var=inp)
45 self.last_out_val = out_val
46 out_val *= self.gain
48 def do_step(self, inp_var: AgentVariable):
49 # y = not pre(y) and u > uHigh or pre(y) and u >= uLow
50 if inp_var.value <= self.ub and self.last_out_val == int(not self.reverse):
51 return int(not self.reverse)
52 if inp_var.value > self.ub and self.last_out_val == int(not self.reverse):
53 return int(self.reverse)
54 if inp_var.value < self.lb and self.last_out_val == int(self.reverse):
55 return int(not self.reverse)
56 if inp_var.value >= self.lb and self.last_out_val == int(self.reverse):
57 return int(self.reverse)