- added stirrer

- many other improvements

git-svn-id: http://moon:8086/svn/projects/HendiControl@116 fda53097-d464-4ada-af97-ba876c37ca34
This commit is contained in:
2019-03-21 17:55:37 +00:00
parent 75b920047a
commit 08d8c32106
10 changed files with 213 additions and 71 deletions
+62 -44
View File
@@ -11,11 +11,12 @@ controllerStates = Enum('controllerStates', 'ACQU TRACK')
class Controller():
def __init__(self, params, plant):
def __init__(self, params, plant, stirrer):
print(json.dumps({'Controller': params}, indent=4, sort_keys=True))
self.ovenState = ovenStates.NOP
self.controllerState = controllerStates.ACQU
self.plant = plant
self.stirrer = stirrer
self.dt = params['dt']
self.params = params
self.pid = Pid()
@@ -23,20 +24,23 @@ class Controller():
self.heatrate_v = np.empty(0)
self.time_v = np.empty(0)
self.power_v = np.empty(0)
self.theta_err_v = np.empty(0)
self.heatrate_err_v = np.empty(0)
self.theta_ist = 0
self.error_v = np.empty(0)
self.time = 0
pass
def start(self, recipe):
print(json.dumps({recipe['Name'] : recipe}, indent=4, sort_keys=True))
# Stirrer
self.stirrRpmHeat = recipe['stirrRpmHeat']
self.stirrRpmRast = recipe['stirrRpmRast']
self.stirrDutyRast = recipe['stirrDutyRast']
self.stirrCycleTime = recipe['stirrCycleTime']
self.time = 0
for rast in recipe['Rasten']:
self.rast(rast)
def stop(self):
figure(1)
subplot(4, 1, 1)
@@ -50,8 +54,8 @@ class Controller():
grid(True)
ylabel('W')
subplot(4, 1, 3)
plot(self.time_v, self.theta_err_v, 'b-', linewidth=1)
title('Temperature Error')
plot(self.time_v, self.error_v, 'b-', linewidth=1)
title('Error')
grid(True)
ylabel('°C')
subplot(4, 1, 4)
@@ -63,53 +67,58 @@ class Controller():
show()
def rast(self, rast):
temp_soll = rast['temp']
heatrate_soll = rast['heatRate']
print("Target temperature {} °C".format(temp_soll))
doLoop = True
timer_ist = 0
heatrate_ist = 0
timer_soll = 60*rast['time']/self.dt
heatRateMeasureInterval = 1
heatRateMeasureCount = 1
theta_err_sm = Smoother(0.5)
heatrate_err_sm = Smoother(0.5)
# Stirrer
self.stirrer.start()
self.stirrer.setCycleTime(self.stirrCycleTime)
# Temperature
theta_last = self.plant.getTemperature()
theta_soll = rast['temp']
heatrate_soll = rast['heatRate']
print("Target temperature {} °C".format(theta_soll))
# Timer
timer_ist = 0
timer_soll = 60*rast['time']/self.dt
# ------------------------------
# The loop
# ------------------------------
doLoop = True
theta_err_sm = Smoother(0.5)
heatrate_err_sm = Smoother(0.5)
while(doLoop):
controllerStateNext = self.controllerState
ovenStateNext = self.ovenState
# -----------------------------------------
self.plant.process(self.dt)
self.stirrer.process()
self.plant.process()
theta_ist = self.plant.getTemperature()
if heatRateMeasureCount <= 0:
heatrate_ist = 60 * (theta_ist - self.theta_ist) / heatRateMeasureInterval;
heatRateMeasureCount = heatRateMeasureInterval;
theta_last = theta_ist;
heatrate_ist = 60/self.dt * (theta_ist - theta_last)
heatRateMeasureCount = heatRateMeasureCount - self.dt;
# print ("{}: Temp IST = {:0.2f} °C".format(timer_ist, temp_ist))
# print ("{}: Temp IST = {:0.2f} °C".format(timer_ist, temp_ist))
theta_err = temp_soll - theta_ist
theta_err = theta_soll - theta_ist
heatrate_err = heatrate_soll - heatrate_ist
theta_err_sm.process(theta_err)
heatrate_err_sm.process(heatrate_err)
if self.ovenState == ovenStates.NOP:
if theta_ist < temp_soll:
if theta_ist < theta_soll:
ovenStateNext = ovenStates.HEAT
pid_err = 0
if self.ovenState == ovenStates.HEAT:
pid_err = heatrate_err_sm.get_y()
pid_params_acqu = self.params['Heat']['Acqu']['Pid']
pid_params_track = self.params['Heat']['Track']['Pid']
if theta_ist >= temp_soll:
pid_thresh_acqu = 0.2
pid_thresh_track = 0.5
if theta_ist >= theta_soll:
ovenStateNext = ovenStates.HOLD
timer_ist = 0
@@ -117,6 +126,8 @@ class Controller():
pid_err = theta_err_sm.get_y()
pid_params_acqu = self.params['Hold']['Acqu']['Pid']
pid_params_track = self.params['Hold']['Track']['Pid']
pid_thresh_acqu = 0.2
pid_thresh_track = 0.5
timer_ist += self.dt
if timer_ist >= timer_soll:
ovenStateNext = ovenStates.NOP
@@ -125,42 +136,49 @@ class Controller():
if self.ovenState != ovenStates.NOP:
if self.controllerState == controllerStates.ACQU:
pid_params = pid_params_acqu
if abs(theta_err) < 0.2:
if abs(pid_err) < pid_thresh_acqu:
controllerStateNext = controllerStates.TRACK
if self.controllerState == controllerStates.TRACK:
pid_params = pid_params_track
if abs(theta_err) > 0.5:
if abs(pid_err) > pid_thresh_track:
controllerStateNext = controllerStates.ACQU
self.pid.process(pid_params, pid_err)
self.pid.process(self.dt, pid_params, pid_err)
y = self.pid.get_y()
# print ("theta_err = {:0.2f} °C".format(theta_err))
power = max(self.params['P_min'], min(self.params['P_max'], self.params['P_max']*y))
# print ("Power = {:0.2f} W".format(power))
self.plant.setPower(power)
self.time += self.dt
self.theta_ist = theta_ist
theta_last = theta_ist
self.theta_v = np.append(self.theta_v, theta_ist)
self.heatrate_v = np.append(self.heatrate_v, heatrate_ist)
self.time_v = np.append(self.time_v, self.time/60)
self.power_v = np.append(self.power_v, power)
self.theta_err_v = np.append(self.theta_err_v, theta_err_sm.get_y())
self.heatrate_err_v = np.append(self.heatrate_err_v, heatrate_err_sm.get_y())
self.error_v = np.append(self.error_v, pid_err)
#self.error_v = np.append(self.error_v, self.stirrer.getRpm())
# print ("theta_err = {:0.2f} °C".format(theta_err))
# print ("Power = {:0.2f} W".format(power))
# -----------------------------------------
if ovenStateNext != self.ovenState:
print("{} -> {}".format(self.ovenState, ovenStateNext))
if ovenStateNext == ovenStates.HEAT:
self.stirrer.setRpm(self.stirrRpmHeat)
self.stirrer.setDutyCycle(1.0)
if ovenStateNext == ovenStates.HOLD:
self.stirrer.setRpm(self.stirrRpmRast)
self.stirrer.setDutyCycle(self.stirrDutyRast)
if controllerStateNext != self.controllerState:
print("{} -> {}".format(self.controllerState, controllerStateNext))
if ovenStateNext != self.ovenState:
print("{} -> {}".format(self.ovenState, ovenStateNext))
self.controllerState = controllerStateNext
self.ovenState = ovenStateNext
self.controllerState = controllerStateNext
# ------------------------------
# ------------------------------
self.stirrer.stop()