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

1from pydantic import Field 

2from agentlib.core import Agent 

3from agentlib.modules.controller import SISOController, SISOControllerConfig 

4from agentlib.core.datamodels import AgentVariable 

5 

6 

7class BangBangConfig(SISOControllerConfig): 

8 """Special config for a BangBang-Controller""" 

9 

10 gain: float = Field(title="Gain of output", default=1) 

11 

12 

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 """ 

18 

19 config: BangBangConfig 

20 

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 

24 

25 @property 

26 def gain(self): 

27 """Get the gain of the BangBang controller""" 

28 return self.config.gain 

29 

30 @property 

31 def last_out_val(self): 

32 """Last output value of the controller""" 

33 return self._last_out_val 

34 

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 

39 

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 

47 

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)