- TC: state IDLE introduced
- TC: send states
This commit is contained in:
@@ -7,7 +7,7 @@ from components.plant.pot import Pot, APlant
|
||||
from components.actor.heater import Heater, AHeater
|
||||
from components.pid import kalman, temp_controller
|
||||
from ws.message import MsgIo, MessageDispatcher
|
||||
from utils.value import Value, ValueChanged
|
||||
from utils.value import Value, ChangedFloat, ChangedInteger
|
||||
|
||||
TC_DT = 0.1
|
||||
|
||||
@@ -41,7 +41,7 @@ class TempSensorTask(ATask):
|
||||
|
||||
async def on_process(self):
|
||||
print("{}: Started with interval {} s".format(self.msg_handler.get_key(), self.interval))
|
||||
temp = ValueChanged(self.on_temp_changed, prec=1)
|
||||
temp = ChangedFloat(self.on_temp_changed, prec=1)
|
||||
self.sensor.set_on_changed("temp", temp.set)
|
||||
while True:
|
||||
self.sensor.process()
|
||||
@@ -126,6 +126,10 @@ class TcTask(ATask):
|
||||
self.tc = tc
|
||||
self.temp_soll = 30
|
||||
|
||||
def on_state_changed(self, state):
|
||||
print ("State change to {}".format(state))
|
||||
asyncio.create_task(self.send({'State': state.value}))
|
||||
|
||||
async def recv(self, data):
|
||||
print(data)
|
||||
for pair in data.items():
|
||||
@@ -138,6 +142,9 @@ class TcTask(ATask):
|
||||
async def on_process(self):
|
||||
print("{}: Started with interval {} s".format(self.msg_handler.get_key(), self.interval))
|
||||
temp_soll = Value()
|
||||
|
||||
self.tc.set_on_changed('state', ChangedInteger(self.on_state_changed).set)
|
||||
|
||||
while True:
|
||||
temp_soll.set(self.temp_soll)
|
||||
if temp_soll.is_changed():
|
||||
@@ -201,12 +208,12 @@ if __name__ == '__main__':
|
||||
"kn" : 0.2
|
||||
}
|
||||
pot = Pot(pot_params, 20)
|
||||
pot.set_on_changed("temp", ValueChanged(sensor.set_fake_temp, prec=3).set)
|
||||
pot.set_on_changed("temp", ChangedFloat(sensor.set_fake_temp, prec=3).set)
|
||||
taskmgr.add(PotTask(pot, TC_DT, dispatcher.msgio_get("Pot")))
|
||||
|
||||
# Heater
|
||||
heater = Heater()
|
||||
heater.set_on_changed("power_eff", ValueChanged(pot.setPower, prec=0).set)
|
||||
heater.set_on_changed("power_eff", ChangedFloat(pot.setPower, prec=0).set)
|
||||
heater_task = HeaterTask(heater, TC_DT, dispatcher.msgio_get("Heater"))
|
||||
taskmgr.add(heater_task)
|
||||
|
||||
@@ -231,7 +238,7 @@ if __name__ == '__main__':
|
||||
tc.set_on_changed("y", heater_task.actor)
|
||||
tc_task = TcTask(tc, TC_DT, dispatcher.msgio_get("TempCtrl"))
|
||||
taskmgr.add(tc_task)
|
||||
sensor.set_on_changed("temp", ValueChanged(tc.set_theta_ist, prec=2).set)
|
||||
sensor.set_on_changed("temp", ChangedFloat(tc.set_theta_ist, prec=2).set)
|
||||
|
||||
# Message dispatcher
|
||||
h_dispatcher = taskmgr.start()
|
||||
|
||||
@@ -28,7 +28,7 @@ class TempController(AttributeChange):
|
||||
self.params = params_pid
|
||||
self.kalman = kalman.Kalman(params_kalman)
|
||||
self.y = 0
|
||||
self.state = States.HOLD
|
||||
self.state = States.IDLE
|
||||
self.use_kalman = True
|
||||
self.kalman.initial((20, 0))
|
||||
|
||||
@@ -60,12 +60,30 @@ class TempController(AttributeChange):
|
||||
|
||||
# Process state
|
||||
state_next = self.state
|
||||
if self.state == States.HOLD:
|
||||
if (self.theta_ist + 1.0) < self.theta_soll_set:
|
||||
diff = self.theta_soll_set - self.theta_ist
|
||||
|
||||
THRESH_HEAT = 1.0
|
||||
THRESH_IDLE = 1.0
|
||||
THRESH_IDLE_HOLD = 0.1
|
||||
THRESH_HEAT_HOLD = 1.0
|
||||
|
||||
if self.state == States.IDLE:
|
||||
if diff > THRESH_HEAT:
|
||||
state_next = States.HEAT
|
||||
self.pid_rate.reset()
|
||||
elif diff > -THRESH_IDLE_HOLD:
|
||||
state_next = States.HOLD
|
||||
self.pid_hold.reset()
|
||||
elif self.state == States.HOLD:
|
||||
if diff > THRESH_HEAT:
|
||||
state_next = States.HEAT
|
||||
self.pid_rate.reset()
|
||||
elif diff < -THRESH_IDLE_HOLD:
|
||||
state_next = States.IDLE
|
||||
elif self.state == States.HEAT:
|
||||
if (self.theta_ist + 1.0) >= self.theta_soll_set:
|
||||
if diff < -THRESH_IDLE:
|
||||
state_next = States.IDLE
|
||||
elif diff < THRESH_HEAT_HOLD:
|
||||
state_next = States.HOLD
|
||||
self.pid_hold.reset()
|
||||
|
||||
@@ -75,8 +93,10 @@ class TempController(AttributeChange):
|
||||
|
||||
if self.state == States.HEAT:
|
||||
self.y = self.pid_rate.get_y()
|
||||
else:
|
||||
elif self.state == States.HOLD:
|
||||
self.y = self.pid_hold.get_y()
|
||||
else:
|
||||
self.y = 0
|
||||
|
||||
if state_next != self.state:
|
||||
print("New state = {}".format(state_next))
|
||||
|
||||
+16
-1
@@ -15,7 +15,7 @@ class Value:
|
||||
return self.value
|
||||
|
||||
|
||||
class ValueChanged(object):
|
||||
class ChangedFloat(object):
|
||||
def __init__(self, on_changed, prec=2, initial=None):
|
||||
self.on_changed = on_changed
|
||||
self.prec = prec
|
||||
@@ -32,6 +32,21 @@ class ValueChanged(object):
|
||||
self.on_changed(value_rounded)
|
||||
|
||||
|
||||
class ChangedInteger(object):
|
||||
def __init__(self, on_changed, initial=None):
|
||||
self.on_changed = on_changed
|
||||
self.value = initial
|
||||
|
||||
def set(self, value):
|
||||
has_changed = True
|
||||
if self.value is not None:
|
||||
has_changed = self.value != value
|
||||
|
||||
self.value = value
|
||||
if has_changed:
|
||||
self.on_changed(value)
|
||||
|
||||
|
||||
class AttributeChange(object):
|
||||
def __init__(self):
|
||||
self.callbacks = {}
|
||||
|
||||
Reference in New Issue
Block a user