# closed-loop transfer function L = G * K # magnitude and phase of L plt.figure('Figure 2.19') bode(L, -2, 1) # From the figure we can calculate w180 # w180 = 0.44 GM, PM, wc, wb, wbt, valid = marginsclosedloop(L) print('GM:', np.round(GM, 2)) print('PM:', np.round(PM * np.pi / 180, 2), "rad or", np.round(PM, 2), "deg") print('wb:', np.round(wb, 2)) print('wc:', np.round(wc, 2)) print('wbt:', np.round(wbt, 4)) # Response to step in reference for loop shaping design # y = Tr, r(t) = 1 for t > 0 # u = KSr, r(t) = 1 for t > 0 plt.figure('Figure 2.20') T = feedback(L, 1) S = feedback(1, L) u = K * S step_response_plot(T, u, 50, 0) # magnitude and phase of K plt.figure('Figure 2.21') bode(K, -2, 1) plt.show()
G = 5/((10*s + 1)*(s - 1)) Gd = Kd/((s + 1)*(0.2*s + 1)) K = 0.04/s * ((10*s + 1)**2)/((0.1*s + 1)**2) L = G * K # Transfer function between disturbance and output y S = feedback(1, L)*Gd # Transfer function between disturbance and controller input u Gu = -S*K plt.figure('Figure 5.16 (a)') plt.subplot(1, 2, 1) w = np.logspace(-2, 1, 1000) wi = w*1j plt.loglog(w, np.abs(G(wi))) plt.loglog(w, np.abs(Gd(wi))) plt.axhline(1, color='black', linestyle=':') plt.title('(a) $|G|$ & $|G_d|$ with $k_d$=0.5') plt.xlabel('Frequency [rad/s]') plt.ylabel('Magnitude') plt.legend(('$|G|$','$|G_d|$'), loc=1) plt.subplot(1, 2, 2) step_response_plot(S, Gu, t_end=10, constraint=1) #TODO y(t)const is not yet correct plt.title('(b) Response to step in disturbance ($k_d=0.5$)') plt.show()
Gd = Kd / ((s + 1) * (0.2 * s + 1)) K = 0.04 / s * ((10 * s + 1)**2) / ((0.1 * s + 1)**2) L = G * K # Transfer function between disturbance and output y S = feedback(1, L) * Gd # Transfer function between disturbance and controller input u Gu = -S * K plt.figure('Figure 5.16 (a)') plt.subplot(1, 2, 1) w = np.logspace(-2, 1, 1000) wi = w * 1j plt.loglog(w, np.abs(G(wi))) plt.loglog(w, np.abs(Gd(wi))) plt.axhline(1, color='black', linestyle=':') plt.title('(a) $|G|$ & $|G_d|$ with $k_d$=0.5') plt.xlabel('Frequency [rad/s]') plt.ylabel('Magnitude') plt.legend(('$|G|$', '$|G_d|$'), loc=1) plt.subplot(1, 2, 2) step_response_plot(S, Gu, t_end=10, constraint=1) # TODO y(t)const is not yet correct plt.title('(b) Response to step in disturbance ($k_d=0.5$)') plt.show()
[Kc, Taui, Ku, Pu] = ControllerTuning(G, method='ZN') print 'Kc:', np.round(Ku/2.2, 3) print 'Taui:', np.round(Pu/1.2, 3) print 'Ku:', np.round(Ku, 3) print 'Pu:', np.round(Pu, 3) K1 = Kc * (1 + 1 / (Taui * s)) K = K1[0] # use this code to remove array L = G * K T = feedback(L, 1) S = feedback(1, L) u = S * K plt.figure('Figure 2.8') step_response_plot(T, u, 80, 0) plt.show() plt.figure('Figure 2.14') bodeclosedloop(G, K, -2, 1, margin=True) plt.show() GM, PM, wc, wb, wbt, valid = marginsclosedloop(L) print 'GM:' , np.round(GM, 2) print "PM: ", np.round(PM, 1) , "deg or", np.round(PM / 180 * np.pi, 2), "rad" print 'wb:' , np.round(wb, 2) print 'wc:' , np.round(wc, 2) print 'wbt:' , np.round(wbt, 2) if valid: print "Frequency range wb < wc < wbt is valid" else: print "Frequency range wb < wc < wbt is not valid"
import numpy as np import matplotlib.pyplot as plt from utils import feedback, tf, marginsclosedloop from utilsplot import step_response_plot, bodeclosedloop s = tf([1, 0], 1) G = 4 /((s - 1) * (0.02 * s + 1)**2) Kc = 1.25 Tauc = 1.5 K = Kc * (1 + 1 / (Tauc * s)) L = K * G T = feedback(L, 1) S = feedback(1, L) u = S * K plt.figure('Figure 2.9') step_response_plot(T, u, 4, 0) plt.show() plt.figure('Figure 2.15') bodeclosedloop(G, K, -1, 2, margin=True) plt.show() #TODO there is a descrepancy with the phase plots GM, PM, wc, wb, wbt, valid = marginsclosedloop(L) print 'GM:' , np.round(GM, 2) print 'PM:', np.round(PM / 180 * np.pi, 2), "rad or", np.round(PM, 2), "deg" print 'wb:' , np.round(wb, 2) print 'wc:' , np.round(wc, 2) print 'wbt:' , np.round(wbt, 4)
Gd = Kd / ((s + 1) * (0.2 * s + 1)) K = 0.04 / s * ((10 * s + 1)**2) / ((0.1 * s + 1)**2) L = G * K # Transfer function between disturbance and output y S = feedback(1, L) * Gd # Transfer function between disturbance and controller input u Gu = -S * K plt.figure('Figure 5.16 (a)') plt.subplot(1, 2, 1) w = np.logspace(-2, 1, 1000) wi = w * 1j plt.loglog(w, np.abs(G(wi))) plt.loglog(w, np.abs(Gd(wi))) plt.axhline(1, color='black', linestyle=':') plt.title('(a) $|G|$ & $|G_d|$ with $k_d$=0.5') plt.xlabel('Frequency [rad/s]') plt.ylabel('Magnitude') plt.legend(('$|G|$', '$|G_d|$'), loc=1) plt.subplot(1, 2, 2) # TODO y(t)const is not yet correct step_response_plot(S, Gu, t_end=10, constraint=1) plt.title('(b) Response to step in disturbance ($k_d=0.5$)') plt.show()
import matplotlib.pyplot as plt from utils import feedback, tf, marginsclosedloop from utilsplot import step_response_plot, bodeclosedloop s = tf([1, 0], 1) G = 4 / ((s - 1) * (0.02 * s + 1)**2) Kc = 1.25 Tauc = 1.5 K = Kc * (1 + 1 / (Tauc * s)) L = K * G T = feedback(L, 1) S = feedback(1, L) u = S * K plt.figure('Figure 2.9') step_response_plot(T, u, 4, 0) plt.show() plt.figure('Figure 2.15') bodeclosedloop(G, K, -1, 2, margin=True) plt.show() # TODO there is a discrepancy with the phase plots GM, PM, wc, wb, wbt, valid = marginsclosedloop(L) print('GM:', np.round(GM, 2)) print('PM:', np.round(PM / 180 * np.pi, 2), "rad or", np.round(PM, 2), "deg") print('wb:', np.round(wb, 2)) print('wc:', np.round(wc, 2)) print('wbt:', np.round(wbt, 4))