Skip to content

Commit 7c788d5

Browse files
committed
build closed-loop system using interconnect
1 parent 729f724 commit 7c788d5

1 file changed

Lines changed: 29 additions & 17 deletions

File tree

autotune/autotune.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
import matplotlib.patches as mpatches
4747

4848
from data_extractor import *
49-
from pid_design import computePidGmvc, gainsToNumDen, computePidDahlin
49+
from pid_design import computePidGmvc
5050
from system_identification import SystemIdentification
5151
import control as ctrl
5252
from scipy.signal import resample, detrend
@@ -520,7 +520,6 @@ def computeController(self):
520520
self.ki /= 5.0
521521
static_gain = sum(self.num) / sum(self.den)
522522
self.kff = 1 / static_gain
523-
# (self.kc, self.ki, self.kd) = computePidDahlin(self.num, self.den, self.dt, sigma)
524523

525524
self.updateKIDSliders()
526525
self.updateClosedLoop()
@@ -542,24 +541,37 @@ def updateClosedLoop(self):
542541
ki = self.ki
543542
kd = self.kd
544543
kff = self.kff
545-
Gd = ctrl.TransferFunction([1], np.append([1], np.zeros(self.sys_id_delays)), dt)
546-
Gz2 = ctrl.TransferFunction(num, den, dt)
547-
Gi = ctrl.TransferFunction([ki * dt, ki * dt], [2, -2], dt)
548-
549-
if True:
550-
# PI controller without zero
551-
Gcp = ctrl.feedback(kc * Gz2, [1])
552-
Gcl = ctrl.feedback(ctrl.series(Gi, Gcp), [1])
553-
else:
554-
# Standard PI controller
555-
pi = ctrl.series(kc, ctrl.parallel([1], Gi))
556-
Gcl = ctrl.feedback(ctrl.series(pi, Gz2), [1])
557544

558-
t_out,y_out = ctrl.step_response(Gcl, T=np.arange(0,1,dt))
545+
delays = ctrl.TransferFunction([1], np.append([1], np.zeros(self.sys_id_delays)), dt, inputs='r', outputs='rd')
546+
plant = ctrl.TransferFunction(num, den, dt, inputs='u', outputs='plant_out')
547+
sampler = ctrl.TransferFunction([1], [1, 0], dt, inputs='plant_out', outputs='y')
548+
sum_feedback = ctrl.summing_junction(inputs=['rd', '-y'], output='e')
549+
550+
# Default is standard PID
551+
feedforward = ctrl.TransferFunction([kff], [1], dt, inputs='rd', outputs='ff_out')
552+
p_control = ctrl.TransferFunction([kc], [1], dt, inputs='e', outputs='p_out')
553+
i_control = ctrl.TransferFunction([kc * ki * dt, kc * ki * dt], [2, -2], dt, inputs='e', outputs='i_out') # Integrator discretized using bilinear transform
554+
d_control = ctrl.TransferFunction([2 * kc * kd , -2 * kc * kd], [dt, dt], dt, inputs='e', outputs='d_out')
555+
sum_control = ctrl.summing_junction(inputs=['ff_out', 'p_out', 'i_out', 'd_out'], output='u')
556+
557+
remove_zero = False
558+
no_derivative_kick = True
559+
560+
if remove_zero:
561+
# P on feedback only to remove zero (3-loop autopilot style)
562+
p_control = ctrl.TransferFunction([-kc], [1], dt, inputs='y', outputs='p_out')
563+
564+
if no_derivative_kick:
565+
# Derivative on feedback only to remove the "derivative kick"
566+
d_control = ctrl.TransferFunction([-2 * kc * kd , 2 * kc * kd], [dt, dt], dt, inputs='y', outputs='d_out')
567+
568+
closed_loop = ctrl.interconnect([delays, sampler, sum_feedback, feedforward, sum_control, p_control, i_control, d_control, plant], inputs='r', outputs='y')
569+
570+
t_out,y_out = ctrl.step_response(closed_loop, T=np.arange(0,1,dt))
559571
self.plotClosedLoop(t_out, y_out)
560572
w = np.logspace(-1, 3, 40).tolist()
561-
mag, phase, omega = ctrl.bode(Gz2, omega=np.asarray(w), plot=False)
562-
mag_cl, phase_cl, omega_cl = ctrl.bode(Gcl, omega=np.asarray(w), plot=False)
573+
mag, phase, omega = ctrl.bode(plant, omega=np.asarray(w), plot=False)
574+
mag_cl, phase_cl, omega_cl = ctrl.bode(closed_loop, omega=np.asarray(w), plot=False)
563575
self.plotBode(omega, mag, omega_cl, mag_cl)
564576

565577
def plotClosedLoop(self, t, y):

0 commit comments

Comments
 (0)