- added abstarct PID APid
- added PidFactory - use variable args for factory
This commit is contained in:
@@ -5,7 +5,7 @@ from utils import ChangedFloat
|
|||||||
from ws.message import MessageDispatcher
|
from ws.message import MessageDispatcher
|
||||||
from ws.server.ws_server_multi_user import WsServerMultiUser
|
from ws.server.ws_server_multi_user import WsServerMultiUser
|
||||||
from components.sensor import TempSensorFactory
|
from components.sensor import TempSensorFactory
|
||||||
from components.pid import TempController
|
from components.pid import PidFactory
|
||||||
from components.plant import Pot
|
from components.plant import Pot
|
||||||
from components.actor import HeaterFactory, StirrerFactory
|
from components.actor import HeaterFactory, StirrerFactory
|
||||||
from tasks import TaskManager, TempSensorTask, HeaterTask, PotTask, TcTask, StirrerTask, TracerTask
|
from tasks import TaskManager, TempSensorTask, HeaterTask, PotTask, TcTask, StirrerTask, TracerTask
|
||||||
@@ -31,14 +31,14 @@ if __name__ == '__main__':
|
|||||||
taskmgr.add(PotTask(pot, DT_TASK, dispatcher.msgio_get("Pot")))
|
taskmgr.add(PotTask(pot, DT_TASK, dispatcher.msgio_get("Pot")))
|
||||||
|
|
||||||
# Heater
|
# Heater
|
||||||
heater = HeaterFactory.create(config['Controller']['heater_name'], DT, config['Heater'])
|
heater = HeaterFactory.create(config['Controller']['heater_name'], config['Heater'])
|
||||||
heater.set_on_changed("power_eff", ChangedFloat(pot.set_power, prec=0).set)
|
heater.set_on_changed("power_eff", ChangedFloat(pot.set_power, prec=0).set)
|
||||||
heater_task = HeaterTask(heater, DT_TASK, dispatcher.msgio_get("Heater"))
|
heater_task = HeaterTask(heater, DT_TASK, dispatcher.msgio_get("Heater"))
|
||||||
taskmgr.add(heater_task)
|
taskmgr.add(heater_task)
|
||||||
|
|
||||||
# Temperature Controller
|
# Temperature Controller
|
||||||
tc_params = config['TempCtrl']
|
tc_params = config['TempCtrl']
|
||||||
tc = TempController(DT, tc_params)
|
tc = PidFactory.create('Normal', DT, tc_params)
|
||||||
tc.set_on_changed("y", heater_task.actor)
|
tc.set_on_changed("y", heater_task.actor)
|
||||||
tc_task = TcTask(tc, DT_TASK, dispatcher.msgio_get("TempCtrl"))
|
tc_task = TcTask(tc, DT_TASK, dispatcher.msgio_get("TempCtrl"))
|
||||||
taskmgr.add(tc_task)
|
taskmgr.add(tc_task)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
from components.atemperatureSensor import *
|
from components.atemperatureSensor import *
|
||||||
from components.astirrer import *
|
from components.astirrer import *
|
||||||
from components.aheater import *
|
from components.aheater import *
|
||||||
|
from components.apid import *
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
class HeaterFactory:
|
class HeaterFactory:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(name, dt, params):
|
def create(name, *args, **kwargs):
|
||||||
if "sim" in name:
|
if "sim" in name:
|
||||||
from components.actor.heater_sim import HeaterSim
|
from components.actor.heater_sim import HeaterSim
|
||||||
return HeaterSim()
|
print (*args)
|
||||||
|
print (**kwargs)
|
||||||
|
return HeaterSim(*args, **kwargs)
|
||||||
elif "Hendi" in name:
|
elif "Hendi" in name:
|
||||||
from components.actor.heater_hendi import HeaterHendi
|
from components.actor.heater_hendi import HeaterHendi
|
||||||
return HeaterHendi(params)
|
return HeaterHendi(*args, **kwargs)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from components.aheater import AHeater
|
|||||||
|
|
||||||
|
|
||||||
class HeaterSim(AHeater):
|
class HeaterSim(AHeater):
|
||||||
def __init__(self):
|
def __init__(self, params):
|
||||||
AHeater.__init__(self)
|
AHeater.__init__(self)
|
||||||
self.power_set = 0
|
self.power_set = 0
|
||||||
self.power_eff = 0
|
self.power_eff = 0
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import abc
|
||||||
|
from utils.value import AttributeChange
|
||||||
|
|
||||||
|
|
||||||
|
class APid(AttributeChange):
|
||||||
|
def __init__(self):
|
||||||
|
AttributeChange.__init__(self)
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def set_theta_soll(self, value):
|
||||||
|
return None
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def set_heatrate_soll(self, value):
|
||||||
|
return None
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def get_theta_ist(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def get_heatrate_ist(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def get_theta_soll_set(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def get_theta_soll(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def get_heatrate_soll_set(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def get_heatrate_soll(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def process(self):
|
||||||
|
pass
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
from components.pid.pid import *
|
from components.pid.pid import *
|
||||||
from components.pid.kalman import *
|
from components.pid.kalman import *
|
||||||
from components.pid.temp_controller_smith import *
|
from components.pid.pid_factory import PidFactory
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
class PidFactory:
|
||||||
|
@staticmethod
|
||||||
|
def create(name, *args, **kwargs):
|
||||||
|
if "Normal" in name:
|
||||||
|
from components.pid.temp_controller import TempController
|
||||||
|
return TempController(*args, **kwargs)
|
||||||
|
elif "Smith" in name:
|
||||||
|
from components.pid.temp_controller_smith import TempController
|
||||||
|
return TempController(*args, **kwargs)
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
from components.plant.pot import Pot
|
from components.plant.pot import Pot
|
||||||
from matplotlib.pyplot import plot, figure, subplot, grid, show, legend
|
from matplotlib.pyplot import plot, figure, subplot, grid, show, legend
|
||||||
from components.pid import Pid, Kalman
|
from components.pid import Pid, Kalman
|
||||||
|
from components import APid
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from utils.value import AttributeChange
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
@@ -12,9 +12,9 @@ class States(Enum):
|
|||||||
HOLD = 2
|
HOLD = 2
|
||||||
|
|
||||||
|
|
||||||
class TempController(AttributeChange):
|
class TempController(APid):
|
||||||
def __init__(self, dt, params):
|
def __init__(self, dt, params):
|
||||||
AttributeChange.__init__(self)
|
APid.__init__(self)
|
||||||
self.pid_hold = Pid(dt)
|
self.pid_hold = Pid(dt)
|
||||||
self.pid_rate = Pid(dt)
|
self.pid_rate = Pid(dt)
|
||||||
self.theta_ist_set = 20
|
self.theta_ist_set = 20
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
from components.plant.pot import Pot, Delay
|
from components.plant.pot import Pot, Delay
|
||||||
from matplotlib.pyplot import plot, figure, subplot, grid, show, legend
|
from matplotlib.pyplot import plot, figure, subplot, grid, show, legend
|
||||||
from components.pid import Pid, Kalman
|
from components.pid import Pid, Kalman
|
||||||
|
from components import APid
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from utils.value import AttributeChange
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
@@ -12,9 +12,9 @@ class States(Enum):
|
|||||||
HOLD = 2
|
HOLD = 2
|
||||||
|
|
||||||
|
|
||||||
class TempController(AttributeChange):
|
class TempController(APid):
|
||||||
def __init__(self, dt, params):
|
def __init__(self, dt, params):
|
||||||
AttributeChange.__init__(self)
|
APid.__init__(self)
|
||||||
self.pid_hold = Pid(dt)
|
self.pid_hold = Pid(dt)
|
||||||
self.pid_rate = Pid(dt)
|
self.pid_rate = Pid(dt)
|
||||||
self.theta_ist_set = 20
|
self.theta_ist_set = 20
|
||||||
@@ -41,15 +41,33 @@ class TempController(AttributeChange):
|
|||||||
def set_theta_ist(self, value):
|
def set_theta_ist(self, value):
|
||||||
self.theta_ist_set = value
|
self.theta_ist_set = value
|
||||||
|
|
||||||
|
def get_theta_ist(self):
|
||||||
|
return self.theta_ist
|
||||||
|
|
||||||
def set_heatrate_ist(self, value):
|
def set_heatrate_ist(self, value):
|
||||||
self.heatrate_ist_set = value
|
self.heatrate_ist_set = value
|
||||||
|
|
||||||
|
def get_heatrate_ist(self):
|
||||||
|
return self.heatrate_ist
|
||||||
|
|
||||||
def set_theta_soll(self, value):
|
def set_theta_soll(self, value):
|
||||||
self.theta_soll_set = value
|
self.theta_soll_set = value
|
||||||
|
|
||||||
|
def get_theta_soll(self):
|
||||||
|
return self.theta_soll
|
||||||
|
|
||||||
|
def get_theta_soll_set(self):
|
||||||
|
return self.theta_soll_set
|
||||||
|
|
||||||
def set_heatrate_soll(self, value):
|
def set_heatrate_soll(self, value):
|
||||||
self.heatrate_soll_set = value
|
self.heatrate_soll_set = value
|
||||||
|
|
||||||
|
def get_heatrate_soll(self):
|
||||||
|
return self.heatrate_soll
|
||||||
|
|
||||||
|
def get_heatrate_soll_set(self):
|
||||||
|
return self.heatrate_soll_set
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
# Process Kalman of Model
|
# Process Kalman of Model
|
||||||
Z_model = self.kalman_model.process_measurement((self.model.get_temperature_intermediate(), 0), 0.0)
|
Z_model = self.kalman_model.process_measurement((self.model.get_temperature_intermediate(), 0), 0.0)
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ class TempSensorSim(ATemperatureSensor):
|
|||||||
def name(self):
|
def name(self):
|
||||||
return "FakeTemp"
|
return "FakeTemp"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, temp_offset=0):
|
||||||
ATemperatureSensor.__init__(self)
|
ATemperatureSensor.__init__(self)
|
||||||
|
self.temp_offset = temp_offset
|
||||||
self.temp = 22.37
|
self.temp = 22.37
|
||||||
self.temp_set = self.temp
|
self.temp_set = self.temp
|
||||||
self.k_noise = 0.01
|
self.k_noise = 0.01
|
||||||
@@ -16,8 +17,7 @@ class TempSensorSim(ATemperatureSensor):
|
|||||||
self.temp_set = temp
|
self.temp_set = temp
|
||||||
|
|
||||||
def temperature(self):
|
def temperature(self):
|
||||||
return self.temp_set + self.k_noise * np.random.normal(0, 1) / np.sqrt(12.0)
|
return self.temp_offset + self.temp
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
temp = self.temperature()
|
self.temp = self.temp_set + self.k_noise * np.random.normal(0, 1) / np.sqrt(12.0)
|
||||||
self.temp = temp
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/env python3
|
||||||
import time
|
import time
|
||||||
from components import ATemperatureSensor
|
from components import ATemperatureSensor
|
||||||
import spidev
|
import spidev
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
class TempSensorFactory:
|
class TempSensorFactory:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(name):
|
def create(name, *args, **kwargs):
|
||||||
if "sim" in name:
|
if "sim" in name:
|
||||||
from components.sensor.tempSensorSim import TempSensorSim
|
from components.sensor.tempSensorSim import TempSensorSim
|
||||||
return TempSensorSim()
|
return TempSensorSim(*args, **kwargs)
|
||||||
elif "31865" in name:
|
elif "31865" in name:
|
||||||
from components.sensor.tempSensor_max31865 import TempSensor_max31865
|
from components.sensor.tempSensor_max31865 import TempSensor_max31865
|
||||||
return TempSensor_max31865(temp_offset=0)
|
return TempSensor_max31865(*args, **kwargs)
|
||||||
|
|||||||
@@ -26,11 +26,27 @@
|
|||||||
function retval = results()
|
function retval = results()
|
||||||
|
|
||||||
load brewpi.mat
|
load brewpi.mat
|
||||||
|
|
||||||
|
close all;
|
||||||
|
|
||||||
|
figure(1)
|
||||||
|
|
||||||
set(0, "defaultlinelinewidth", 1.5);
|
set(0, "defaultlinelinewidth", 1.5);
|
||||||
subplot(3,1,1)
|
subplot(3,1,1)
|
||||||
plot(time, tc_temp_soll, time, tc_temp_ist); grid
|
plot(time, tc_temp_soll, time, tc_temp_ist); grid
|
||||||
legend("Temp_{soll}","Temp_{ist}")
|
legend("Temp_{soll}","Temp_{ist}")
|
||||||
subplot(3,1,2)
|
subplot(3,1,2)
|
||||||
|
plot(time, tc_temp_ist-tc_temp_soll, "ro"); grid
|
||||||
|
legend("Temp_{ist} - dTemp_{soll}")
|
||||||
|
subplot(3,1,3)
|
||||||
|
plot(time, heater_power); grid
|
||||||
|
legend("Power_{Heater}")
|
||||||
|
|
||||||
|
figure(2)
|
||||||
|
subplot(3,1,1)
|
||||||
|
plot(time, tc_temp_soll, time, tc_temp_ist); grid
|
||||||
|
legend("Temp_{soll}","Temp_{ist}")
|
||||||
|
subplot(3,1,2)
|
||||||
plot(time, tc_dtemp_soll, time, tc_dtemp_ist, time, tc_dtemp_commanded); grid
|
plot(time, tc_dtemp_soll, time, tc_dtemp_ist, time, tc_dtemp_commanded); grid
|
||||||
legend("dTemp_{soll}","dTemp_{ist}","dTemp_{cmd}")
|
legend("dTemp_{soll}","dTemp_{ist}","dTemp_{cmd}")
|
||||||
subplot(3,1,3)
|
subplot(3,1,3)
|
||||||
|
|||||||
+2
-2
@@ -2,11 +2,11 @@ import asyncio
|
|||||||
from tasks import ATask
|
from tasks import ATask
|
||||||
from ws.message import MsgIo
|
from ws.message import MsgIo
|
||||||
from utils.value import ChangedFloat
|
from utils.value import ChangedFloat
|
||||||
from components.pid import TempController
|
from components import APid
|
||||||
|
|
||||||
|
|
||||||
class TcTask(ATask):
|
class TcTask(ATask):
|
||||||
def __init__(self, tc: TempController, interval, msg_handler: MsgIo):
|
def __init__(self, tc: APid, interval, msg_handler: MsgIo):
|
||||||
ATask.__init__(self, interval)
|
ATask.__init__(self, interval)
|
||||||
|
|
||||||
self.tc = tc
|
self.tc = tc
|
||||||
|
|||||||
+2
-2
@@ -4,14 +4,14 @@ from tasks import ATask
|
|||||||
from ws.message import MsgIo
|
from ws.message import MsgIo
|
||||||
from components import ATemperatureSensor
|
from components import ATemperatureSensor
|
||||||
from components import AHeater
|
from components import AHeater
|
||||||
from components.pid import TempController
|
from components import APid
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import scipy.io
|
import scipy.io
|
||||||
|
|
||||||
|
|
||||||
class TracerTask(ATask):
|
class TracerTask(ATask):
|
||||||
def __init__(self, sensor: ATemperatureSensor, heater: AHeater, temp_ctrl: TempController, interval, msg_handler: MsgIo):
|
def __init__(self, sensor: ATemperatureSensor, heater: AHeater, temp_ctrl: APid, interval, msg_handler: MsgIo):
|
||||||
ATask.__init__(self, interval)
|
ATask.__init__(self, interval)
|
||||||
|
|
||||||
self.msg_handler = msg_handler
|
self.msg_handler = msg_handler
|
||||||
|
|||||||
Reference in New Issue
Block a user