- added generic tracer class
- create tracer for TC - tracer task runs TC-Tracer
This commit is contained in:
@@ -9,6 +9,7 @@ from components.pid import PidFactory
|
||||
from components.plant import Pot
|
||||
from components.actor import HeaterFactory, StirrerFactory
|
||||
from tasks import TaskManager, TempSensorTask, HeaterTask, PotTask, TcTask, StirrerTask, TracerTask
|
||||
from tracer import Tracer
|
||||
|
||||
if __name__ == '__main__':
|
||||
config = json.load(open("config.json"))
|
||||
@@ -40,13 +41,24 @@ if __name__ == '__main__':
|
||||
tc_task = TcTask(tc, DT_TASK, dispatcher.msgio_get("TempCtrl"))
|
||||
taskmgr.add(tc_task)
|
||||
|
||||
tc_trace_vars = [
|
||||
{'variable': 'theta_ist_plant', 'name': 'theta_ist_plant', 'unit': ''},
|
||||
{'variable': 'dtheta_ist_plant', 'name': 'dtheta_ist_plant', 'unit': ''},
|
||||
{'variable': 'theta_ist_model', 'name': 'theta_ist_model', 'unit': ''},
|
||||
{'variable': 'dtheta_ist_model', 'name': 'dtheta_ist_model', 'unit': ''},
|
||||
{'variable': 'theta_ist_model_delay', 'name': 'theta_ist_model_delay', 'unit': ''},
|
||||
{'variable': 'dtheta_ist_model_delay', 'name': 'dtheta_ist_model_delay', 'unit': ''}
|
||||
]
|
||||
|
||||
trace_tc = Tracer(tc, tc_trace_vars, name='tc_trace')
|
||||
|
||||
# Stirrer
|
||||
stirrer = StirrerFactory.create(config['Controller']['stirrer_name'], DT, config['Stirrer'])
|
||||
stirrer_task = StirrerTask(stirrer, DT_TASK, dispatcher.msgio_get("Stirrer"))
|
||||
taskmgr.add(stirrer_task)
|
||||
|
||||
# Tracer
|
||||
taskmgr.add(TracerTask(sensor, heater, tc, DT_TASK_TRACER, dispatcher.msgio_get("Tracer")))
|
||||
taskmgr.add(TracerTask(sensor, heater, tc, trace_tc, DT_TASK_TRACER, dispatcher.msgio_get("Tracer")))
|
||||
|
||||
# Assign data flow
|
||||
tc.set_on_changed("y", heater_task.actor)
|
||||
|
||||
@@ -100,9 +100,9 @@ class TempController(APid):
|
||||
|
||||
self.heatrate_soll = self.heatrate_soll_set * self.pid_hold.get_y()
|
||||
|
||||
print ("Model : T_ist={:2.2f}, dT_ist={:2.2f}".format(theta_ist_model, heatrate_ist_model))
|
||||
print ("Model*z-1: T_ist={:2.2f}, dT_ist={:2.2f}".format(theta_ist_model_delay, dtheta_ist_model_delay))
|
||||
print ("Plant : T_ist={:2.2f}, dT_ist={:2.2f}".format(theta_ist_plant, heatrate_ist_plant))
|
||||
# print ("Model : T_ist={:2.2f}, dT_ist={:2.2f}".format(theta_ist_model, heatrate_ist_model))
|
||||
# print ("Model*z-1: T_ist={:2.2f}, dT_ist={:2.2f}".format(theta_ist_model_delay, dtheta_ist_model_delay))
|
||||
# print ("Plant : T_ist={:2.2f}, dT_ist={:2.2f}".format(theta_ist_plant, heatrate_ist_plant))
|
||||
if 0:
|
||||
theta_err = self.theta_soll_set - (theta_ist_plant - theta_ist_model_delay + theta_ist_model)
|
||||
else:
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
## Copyright (C) 2020 Jens
|
||||
##
|
||||
## This program is free software: you can redistribute it and/or modify it
|
||||
## under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful, but
|
||||
## WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see
|
||||
## <https://www.gnu.org/licenses/>.
|
||||
|
||||
## -*- texinfo -*-
|
||||
## @deftypefn {} {@var{retval} =} results (@var{input1}, @var{input2})
|
||||
##
|
||||
## @seealso{}
|
||||
## @end deftypefn
|
||||
|
||||
## Author: Jens <jens@orion>
|
||||
## Created: 2020-12-20
|
||||
|
||||
function retval = results_tc()
|
||||
|
||||
load ('logs/tc_trace.mat')
|
||||
|
||||
close all;
|
||||
|
||||
figure(1)
|
||||
|
||||
set(0, "defaultlinelinewidth", 1.5);
|
||||
subplot(2,1,1)
|
||||
plot(time, theta_ist_plant, time, theta_ist_model, theta_ist_model_delay); grid
|
||||
title("Temperature [°C]")
|
||||
legend("Plant","Model","Model*z")
|
||||
|
||||
subplot(2,1,2)
|
||||
plot(time, dtheta_ist_plant, time, dtheta_ist_model, dtheta_ist_model_delay); grid
|
||||
title("Heatrate [°C/min]")
|
||||
legend("Plant","Model","Model*z")
|
||||
|
||||
endfunction
|
||||
+10
-3
@@ -5,6 +5,7 @@ from ws.message import MsgIo
|
||||
from components import ATemperatureSensor
|
||||
from components import AHeater
|
||||
from components import APid
|
||||
from tracer import Tracer
|
||||
|
||||
import numpy as np
|
||||
import scipy.io
|
||||
@@ -12,7 +13,7 @@ import os
|
||||
|
||||
|
||||
class TracerTask(ATask):
|
||||
def __init__(self, sensor: ATemperatureSensor, heater: AHeater, temp_ctrl: APid, interval, msg_handler: MsgIo, path= './logs'):
|
||||
def __init__(self, sensor: ATemperatureSensor, heater: AHeater, temp_ctrl: APid, tracer: Tracer, interval, msg_handler: MsgIo, path= './logs'):
|
||||
ATask.__init__(self, interval)
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
@@ -23,6 +24,7 @@ class TracerTask(ATask):
|
||||
self.sensor = sensor
|
||||
self.heater = heater
|
||||
self.temp_ctrl = temp_ctrl
|
||||
self.tracer = tracer
|
||||
self.path = path
|
||||
|
||||
async def recv(self, data):
|
||||
@@ -44,8 +46,13 @@ class TracerTask(ATask):
|
||||
_tc_dtemp_soll = np.empty(0)
|
||||
_tc_dtemp_commanded = np.empty(0)
|
||||
|
||||
filename = os.path.join(self.path, '') + "brewpi." + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".mat"
|
||||
name = 'brewpi'
|
||||
filename = os.path.join(self.path, '') + name + ".mat"
|
||||
filename_full = os.path.join(self.path, '') + name + "." + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".mat"
|
||||
|
||||
while True:
|
||||
self.tracer.process()
|
||||
|
||||
_timestamp = np.append(_timestamp, timestamp)
|
||||
_sensor_temp = np.append(_sensor_temp, self.sensor.temperature())
|
||||
_heater_power = np.append(_heater_power, self.heater.get_power())
|
||||
@@ -57,8 +64,8 @@ class TracerTask(ATask):
|
||||
|
||||
data = {'time': _timestamp, 'sensor_temp': _sensor_temp, 'heater_power': _heater_power, 'tc_temp_ist': _tc_temp_ist, 'tc_dtemp_ist': _tc_dtemp_ist, 'tc_temp_soll': _tc_temp_soll, 'tc_dtemp_soll': _tc_dtemp_soll, 'tc_dtemp_commanded': _tc_dtemp_commanded}
|
||||
|
||||
scipy.io.savemat('brewpi.mat', data)
|
||||
scipy.io.savemat(filename, data)
|
||||
scipy.io.savemat(filename_full, data)
|
||||
timestamp += 1
|
||||
await asyncio.sleep(self.interval)
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
from typing import TypedDict
|
||||
import numpy as np
|
||||
import scipy.io
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
class Entry(TypedDict):
|
||||
variable: str
|
||||
name: str
|
||||
unit: str
|
||||
|
||||
|
||||
class Tracer:
|
||||
def __init__(self, obj, var_list: Entry, name='default', path='./logs'):
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
self.obj = obj
|
||||
self.var_list = var_list
|
||||
self.timestamp = 0
|
||||
self.timestamp_data = np.empty(0)
|
||||
self.filename_full = os.path.join(path, '') + name + "." + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".mat"
|
||||
self.filename = os.path.join(path, '') + name + ".mat"
|
||||
self.data_list = {}
|
||||
for var in self.var_list:
|
||||
self.data_list[var['name']] = np.empty(0)
|
||||
|
||||
def process(self):
|
||||
data = {}
|
||||
self.timestamp_data = np.append(self.timestamp_data, self.timestamp)
|
||||
data['time'] = self.timestamp_data
|
||||
|
||||
for var in self.var_list:
|
||||
key_name = var['name']
|
||||
key_variable = var['variable']
|
||||
self.data_list[key_name] = np.append(self.data_list[key_name], self.obj.__getattribute__(key_variable))
|
||||
data[key_name] = self.data_list[key_name]
|
||||
|
||||
scipy.io.savemat(self.filename, data)
|
||||
scipy.io.savemat(self.filename_full, data)
|
||||
self.timestamp += 1
|
||||
|
||||
|
||||
class Test:
|
||||
def __init__(self):
|
||||
self.a = 0
|
||||
self.b = 0
|
||||
|
||||
def process(self):
|
||||
self.a += 1
|
||||
self.b += 10
|
||||
|
||||
@staticmethod
|
||||
def get_entry():
|
||||
a: Entry = [{'variable': 'a', 'name' : 'v_a', 'unit': 'u_a'}]
|
||||
b: Entry = [{'variable': 'b', 'name' : 'v_b', 'unit': 'u_b'}]
|
||||
return a + b
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test = Test()
|
||||
|
||||
dut = Tracer(test, Test.get_entry(), name='TracerTest')
|
||||
|
||||
for i in range(0, 10):
|
||||
dut.process()
|
||||
test.process()
|
||||
Reference in New Issue
Block a user