- Controller have separate PID controller for heat and hold
- do actor fusion - PID : fixed reset() git-svn-id: http://moon:8086/svn/projects/HendiControl@259 fda53097-d464-4ada-af97-ba876c37ca34
This commit is contained in:
@@ -29,7 +29,7 @@ def results_plot(self):
|
|||||||
grid(True)
|
grid(True)
|
||||||
ylabel('°C')
|
ylabel('°C')
|
||||||
subplot(4, 1, 2)
|
subplot(4, 1, 2)
|
||||||
plot(self.time_v, self.power_v, 'b-', linewidth=1)
|
plot(self.time_v, self.power_heat_v, self.time_v, self.power_hold_v, self.time_v, self.power_v, 'r-', linewidth=1)
|
||||||
title('Power')
|
title('Power')
|
||||||
grid(True)
|
grid(True)
|
||||||
ylabel('W')
|
ylabel('W')
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class Controller(TimerListener):
|
|||||||
self.dt = params['dt']
|
self.dt = params['dt']
|
||||||
self.params = params
|
self.params = params
|
||||||
self.pid = Pid()
|
self.pid = Pid()
|
||||||
|
self.pid_rate = Pid()
|
||||||
self.timer_ist = 0
|
self.timer_ist = 0
|
||||||
self.sensorTime_v = np.empty(0)
|
self.sensorTime_v = np.empty(0)
|
||||||
self.theta_raw_v = np.empty(0)
|
self.theta_raw_v = np.empty(0)
|
||||||
@@ -34,6 +35,8 @@ class Controller(TimerListener):
|
|||||||
self.heatrate_k_v = np.empty(0)
|
self.heatrate_k_v = np.empty(0)
|
||||||
self.time_v = np.empty(0)
|
self.time_v = np.empty(0)
|
||||||
self.power_v = np.empty(0)
|
self.power_v = np.empty(0)
|
||||||
|
self.power_heat_v = np.empty(0)
|
||||||
|
self.power_hold_v = np.empty(0)
|
||||||
self.error_v = np.empty(0)
|
self.error_v = np.empty(0)
|
||||||
self.time = 0
|
self.time = 0
|
||||||
self.report_interval = 1.0
|
self.report_interval = 1.0
|
||||||
@@ -199,9 +202,6 @@ class Controller(TimerListener):
|
|||||||
# ------------------------------
|
# ------------------------------
|
||||||
# The loop
|
# The loop
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
if self.ctrl_theta_soll < self.ctrl_theta:
|
|
||||||
return True
|
|
||||||
|
|
||||||
controllerStateNext = self.controllerState
|
controllerStateNext = self.controllerState
|
||||||
ovenStateNext = self.ovenState
|
ovenStateNext = self.ovenState
|
||||||
|
|
||||||
@@ -218,43 +218,23 @@ class Controller(TimerListener):
|
|||||||
if ctrl_theta < self.ctrl_theta_soll:
|
if ctrl_theta < self.ctrl_theta_soll:
|
||||||
ovenStateNext = ovenStates.HEAT
|
ovenStateNext = ovenStates.HEAT
|
||||||
|
|
||||||
pid_err = 0
|
|
||||||
if self.ovenState == ovenStates.HEAT:
|
if self.ovenState == ovenStates.HEAT:
|
||||||
pid_err = ctrl_heatrate_err
|
|
||||||
pid_params_acqu = self.params['Heat']['Acqu']['Pid']
|
|
||||||
pid_params_track = self.params['Heat']['Track']['Pid']
|
|
||||||
pid_thresh_acqu = self.params['Heat']['Acqu']['thresh_leave']
|
|
||||||
pid_thresh_track = self.params['Heat']['Track']['thresh_leave']
|
|
||||||
if (ctrl_theta + 1.0) >= self.ctrl_theta_soll:
|
if (ctrl_theta + 1.0) >= self.ctrl_theta_soll:
|
||||||
ovenStateNext = ovenStates.HOLD
|
ovenStateNext = ovenStates.HOLD
|
||||||
self.log("Set rast timer to {:0.1f} min.".format(timer_soll/60))
|
self.log("Set rast timer to {:0.1f} min.".format(timer_soll/60))
|
||||||
self.timer_ist = timer_soll
|
self.timer_ist = timer_soll
|
||||||
|
|
||||||
if self.ovenState == ovenStates.HOLD:
|
if self.ovenState == ovenStates.HOLD:
|
||||||
pid_err = ctrl_theta_err
|
|
||||||
pid_params_acqu = self.params['Hold']['Acqu']['Pid']
|
|
||||||
pid_params_track = self.params['Hold']['Track']['Pid']
|
|
||||||
pid_thresh_acqu = self.params['Heat']['Acqu']['thresh_leave']
|
|
||||||
pid_thresh_track = self.params['Heat']['Track']['thresh_leave']
|
|
||||||
if self.timer_ist == 0:
|
if self.timer_ist == 0:
|
||||||
ovenStateNext = ovenStates.NOP
|
ovenStateNext = ovenStates.NOP
|
||||||
doLoop = False
|
|
||||||
|
|
||||||
if self.ovenState != ovenStates.NOP:
|
if self.ovenState != ovenStates.NOP:
|
||||||
if self.controllerState == controllerStates.ACQU:
|
self.pid.process(self.dt, self.params['Hold']['Acqu']['Pid'], ctrl_theta_err)
|
||||||
pid_params = pid_params_acqu
|
self.pid_rate.process(self.dt, self.params['Heat']['Acqu']['Pid'], ctrl_heatrate_err)
|
||||||
if abs(pid_err) < pid_thresh_acqu:
|
|
||||||
controllerStateNext = controllerStates.TRACK
|
|
||||||
|
|
||||||
if self.controllerState == controllerStates.TRACK:
|
power_hold = max(self.params['P_min'], min(self.params['P_max'], self.params['P_max']*self.pid.get_y()))
|
||||||
pid_params = pid_params_track
|
power_heat = max(self.params['P_min'], min(self.params['P_max'], self.params['P_max']*self.pid_rate.get_y()))
|
||||||
if abs(pid_err) > pid_thresh_track:
|
power_soll = min(power_hold, power_heat)
|
||||||
controllerStateNext = controllerStates.ACQU
|
|
||||||
|
|
||||||
self.pid.process(self.dt, pid_params, pid_err)
|
|
||||||
|
|
||||||
y = self.pid.get_y()
|
|
||||||
power_soll = max(self.params['P_min'], min(self.params['P_max'], self.params['P_max']*y))
|
|
||||||
self.plant.setPower(power_soll)
|
self.plant.setPower(power_soll)
|
||||||
power_ist = self.plant.getPower()
|
power_ist = self.plant.getPower()
|
||||||
|
|
||||||
@@ -262,13 +242,15 @@ class Controller(TimerListener):
|
|||||||
self.theta_v = np.append(self.theta_v, ctrl_theta)
|
self.theta_v = np.append(self.theta_v, ctrl_theta)
|
||||||
self.heatrate_v = np.append(self.heatrate_v, ctrl_heatrate)
|
self.heatrate_v = np.append(self.heatrate_v, ctrl_heatrate)
|
||||||
self.power_v = np.append(self.power_v, power_ist)
|
self.power_v = np.append(self.power_v, power_ist)
|
||||||
self.error_v = np.append(self.error_v, pid_err)
|
self.power_hold_v = np.append(self.power_hold_v, power_hold)
|
||||||
|
self.power_heat_v = np.append(self.power_heat_v, power_heat)
|
||||||
|
self.error_v = np.append(self.error_v, ctrl_theta_err)
|
||||||
|
|
||||||
# -----------------------------------------
|
# -----------------------------------------
|
||||||
if ovenStateNext != self.ovenState:
|
if ovenStateNext != self.ovenState:
|
||||||
self.log("{} -> {}".format(self.ovenState, ovenStateNext))
|
self.log("{} -> {}".format(self.ovenState, ovenStateNext))
|
||||||
self.pid.reset()
|
|
||||||
if ovenStateNext == ovenStates.HEAT:
|
if ovenStateNext == ovenStates.HEAT:
|
||||||
|
self.pid_rate.reset()
|
||||||
self.stirrer.setSpeed(self.stirrSpeedHeat)
|
self.stirrer.setSpeed(self.stirrSpeedHeat)
|
||||||
self.stirrer.setDutyCycle(1.0)
|
self.stirrer.setDutyCycle(1.0)
|
||||||
|
|
||||||
@@ -289,4 +271,4 @@ class Controller(TimerListener):
|
|||||||
else:
|
else:
|
||||||
self.timer_ist = 0
|
self.timer_ist = 0
|
||||||
|
|
||||||
|
return self.ovenState == ovenStates.NOP
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class Pid():
|
|||||||
def reset(self):
|
def reset(self):
|
||||||
self.yi = 0
|
self.yi = 0
|
||||||
self.xd = 0
|
self.xd = 0
|
||||||
|
self.diff_aw = 0.0
|
||||||
|
|
||||||
def process(self, dt, params, err, derr=None):
|
def process(self, dt, params, err, derr=None):
|
||||||
kp = params['kp']
|
kp = params['kp']
|
||||||
|
|||||||
Reference in New Issue
Block a user