def freqresp(system, xlim=None, N=10000, xlog=True): """Frequency response, possibly over a log range, of a continuous time system.""" if xlim is None: w, resp = signal.freqresp(system, n=N) # Recalculate the data points over a linear interval if requested if not xlog: w = np.linspace(w.min(), w.max(), N) _, resp = signal.freqresp(system, w) else: w = 2 * np.pi * lin_or_logspace(xlim[0], xlim[1], N, xlog) _, resp = signal.freqresp(system, w) freq = w / (2 * np.pi) return freq, resp
def plot_nyquist(L, zoom=None, margin=False, rightticks = False, save=False): fig, axes = plt.subplots(figsize=[6,6]) nyquistSetup(axes, zoom=zoom) #axes[1].yaxis.tick_right(); axes[1].set_ylabel('') w_ = np.linspace(0, 1.5, 10**4)*2*np.pi w_ = np.append(w_[1:], [100]) _, H = signal.freqresp(L, w=w_) axes.plot(H.real, H.imag, 'k', lw=1, label='Nyquist Plot') axes.plot(H.real, -H.imag, '--k', lw=1) # plot stability margin sm, H_ = ControlDesign._stabilityMargin(w_, H) axes.plot([-1, H_.real], [0, H_.imag], '--r', lw=1, label='Stability Margin, $s_m$') angle = np.rad2deg(np.arctan(H_.imag/(H_.real + 1))) axes.text(-0.5 + H_.real/2, H_.imag/2, '${:2.2f}$'.format(sm), rotation=angle, ha='center', va='bottom') axes.legend(loc='lower left') if rightticks: axes.yaxis.tick_right() if save: plt.savefig(save, dpi=200, bbox_inches='tight') plt.show(); print() return sm
def run( SAVE=False): models = BladeModel.make() # plot transfer function over frequency response WSP = [6, 12, 18, 24] models = [x for x in models if x.wsp in WSP] fig, axes = plt.subplots(2, 1, sharex=True) plt.subplots_adjust(hspace=0.05) axes[0].grid(axis='x', which='minor') axes[1].grid(axis='x', which='minor') axes[1].set_ylim([-180, 180]) axes[0].set_xlim([0.05, 5]) axes[0].set_xscale('log') axes[0].set_yscale('log') axes[0].set_ylim([1e-2, 1e2]) axes[1].set_yticks(np.arange(-180, 121, 60)) axes[0].set_ylabel('$|G(jw)|$ [dB]') axes[1].set_ylabel('$< G(jw)$ [deg]') axes[1].set_xlabel('Frequency [Hz]') F1p = 0.16 axes[1].set_xticks([F1p, 2*F1p, 3*F1p, 4*F1p], minor=True) axes[1].set_xticklabels(['$f_{1p}$', '$f_{2p}$', '$f_{3p}$', '$f_{4p}$'], minor=True) for i, model in enumerate(models): w, h = signal.freqresp(model.tf) f = w/(2*np.pi) axes[0].plot(f, abs(h), lw=1, label=f'${WSP[i]}m/s$') axes[1].plot(f, np.angle(h, deg=True), '-', lw=1) axes[0].legend(title='Windspeed', loc='lower right', ncol=2) if SAVE: plt.savefig(SAVE, dpi=200, bbox_inches='tight') plt.show(); print()
def nyquist(*args, ax=None, title='', zoom=None, save=False, N=1e4): # Make axis if not given if not ax: fig, ax = plt.subplots() t_ = np.linspace(0, 2 * np.pi, 100) circx, circy = np.sin(t_), np.cos(t_) ax.axis('equal') ax.plot(circx, circy, '--', lw=1, c='0.7') ax.plot([-1], [0], 'xr') #ax.plot([-1, L(f_sm).real], [0, L(f_sm).imag], '--r', lw=0.5) ax.set_xlabel('Re') ax.set_ylabel('Im') if zoom: ax.set_xlim(zoom) ax.set_ylim(zoom) w_ = np.linspace(0, 1.5, N) * 2 * np.pi w_ = np.append(w_, [100]) for tf in args: w, H = signal.freqresp(tf, w=w_) ax.plot(H.real, H.imag, 'k', lw=1) ax.plot(H.real, -H.imag, '--k', lw=1) H_ = _stabilityMargin(w, H) ax.plot([-1, H_.real], [0, H_.imag], '--r', lw=0.5) if save: plt.savefig(save, dpi=200) return fig, ax
def plotModels(models, save=False): # plot transfer function over frequency response for model in models: w, h = signal.freqresp(model.tf) fig, axes = plt.subplots(2, 1, sharex=True) plt.subplots_adjust(hspace=0.05) axes[0].grid('off') axes[1].grid('off') fig.suptitle('wsp: {}'.format(model.wsp)) axes[0].set_ylabel('|G(jw)| [dB]') axes[1].set_ylabel('$\ angle$ G(jw) [deg]') axes[1].set_xlabel('Frequency [rad/s]') axes[1].set_ylim([-180, 180]) axes[0].set_xlim([0.1, 30]) axes[0].set_xscale('log') axes[0].set_yscale('log') axes[0].set_ylim([1e-2, 1e2]) axes[1].set_yticks(np.arange(-180, 121, 60)) axes[0].plot(model.f, abs(model.G), lw=1, label='Spectral') axes[0].plot(w, abs(h), '--', lw=1, label='Approximation') axes[1].plot(model.f, np.angle(model.G, deg=True), lw=1) axes[1].plot(w, np.angle(h, deg=True), '--', lw=1) if save: plt.savefig('../Figures/Blade_TF_{}.png'.format(model.wsp), dpi=200) plt.show() print()
def computar_datos(r1, r2, r3, r4, color, lw): print("r1 = ", r1) print("r2 = ", r2) print("r3 = ", r3) g_ideal = -r2 / r1 q = r1 * r2 + r2 * r3 + r1 * r3 G_ac = -a0 * r2 * r3 / (q + a0 * r1 * r3) fp = 12 wp = fp * 2 * pi fp_p = fp * (1 + r1 * r3 * a0 / q) wp_p = fp_p * 2 * pi wp_pp = (G_ac / a0 + 1) / (1 / wp_p + G_ac / (a0 * wp)) fp_pp = wp_pp / 2 / pi print("G_ideal=", g_ideal) print("G_ac=", G_ac) print("fp_p=", fp_p) print("fp_p[=", fp_pp) k = r1 / (G_ac / a0 + 1) s1 = signal.lti([r3 + r4], [1]) w, H = signal.freqresp(s1, w_all) f = [i / 2 / pi for i in w] # axes.figure() ax1.semilogx(f, abs(H), color, linewidth=lw)
def graficar_imp(mode, f_range, datos_medidos, spice_filename, output_filename, data): w_range = [i * (2 * pi) for i in f_range] num = data[0] den = data[1] s1 = signal.lti(num, den) w, H = signal.freqresp(s1, w_range) f = [i / 2 / pi for i in w] if mode == "mag": ax1.semilogx(f, abs(H), "blue", linewidth=0.5) else: pass #ax1.semilogx(f, a, "blue",linewidth=2) print(datos_medidos["abs"]) if mode == "mag": ax1.semilogx(datos_medidos["f"], datos_medidos["abs"], "cyan", linewidth=2) else: ax1.semilogx(datos_medidos["f"], datos_medidos["pha"], "cyan", linewidth=2) spice_data = read_file_spice("input/spice_data/" + spice_filename) for i in range(len(spice_data["abs"])): spice_data["abs"][i] = 10**(spice_data["abs"][i] / 20.0) if mode == "mag": ax1.semilogx(spice_data["f"], spice_data["abs"], "green", linewidth=0.5) else: ax1.semilogx(spice_data["f"], spice_data["pha"], "green", linewidth=0.5) ax1.minorticks_on() ax1.grid(which='minor', linestyle=':', linewidth=0.1, color='black') ax1.grid(which='major', linestyle='-', linewidth=0.3, color='black') blue_patch = mpatches.Patch(color='blue', label='Teoría') green_patch = mpatches.Patch(color='green', label='Simulación') cyan_patch = mpatches.Patch(color='cyan', label='Práctico') plt.xlabel("Frecuencia (Hz)") plt.ylabel("Impedancia (ohms)") plt.legend(handles=[green_patch, blue_patch, cyan_patch]) plt.savefig("output/contraste/" + output_filename, dpi=300) plt.cla()
def performance(self, f1p): # Returns the fractional change in tip deflection # amplitude at f1p, f2p, f3p and f4p in an array. S = self.S w = f1p * np.pi * 2 * np.array([1, 2, 3, 4]) _, H = signal.freqresp(S, w=w) return abs(H) - 1
def diff_amp(omega, Rg): """ Mimick an instrumentation amplifier using a butterworth lowpass filter""" f_c = 3.4e6 # cutoff freq G = (1 + 1e4 / Rg) b, a = sig.butter(4, f_c, 'low', analog=True) w, H = sig.freqresp((b, a), w=omega) return G * H
def sm(self): # Returns the stability margin of the system w_ = np.linspace(0, 1.5, 10000) * 2 * np.pi w_ = np.append(w_[1:], [100]) w, H = signal.freqresp(self.L, w=w_) return min(np.sqrt((H.real + 1)**2 + H.imag**2))
def amplitude(self, system): """ Modify Amplitude Spectrum :param system:Transfer function of desired spectrum, usually 1 or 1/LPF(s) :return: """ w, h = signal.freqresp(system, w=self.o_lines) self.a *= abs(h)
def test_from_zpk(self): # 4th order low-pass filter: H(s) = 1 / (s + 1) system = lti([], [-1] * 4, [1]) w = [0.1, 1, 10, 100] w, H = freqresp(system, w=w) s = w * 1j expected = 1 / (s + 1)**4 assert_almost_equal(H.real, expected.real) assert_almost_equal(H.imag, expected.imag)
def test_freq_range(self): # Test that freqresp() finds a reasonable frequency range. # 1st order low-pass filter: H(s) = 1 / (s + 1) # Expected range is from 0.01 to 10. system = lti([1], [1, 1]) n = 10 expected_w = np.logspace(-2, 1, n) w, H = freqresp(system, n=n) assert_almost_equal(w, expected_w)
def test_from_zpk(self): # 4th order low-pass filter: H(s) = 1 / (s + 1) system = lti([],[-1]*4,[1]) w = [0.1, 1, 10, 100] w, H = freqresp(system, w=w) s = w * 1j expected = 1 / (s + 1)**4 assert_almost_equal(H.real, expected.real) assert_almost_equal(H.imag, expected.imag)
def plot(self): G = signal.TransferFunction(5, (1,-3,3,-1)) w, H = signal.freqresp(G) plt.figure() plt.plot(H.real, H.imag, "b") plt.plot(H.real, -H.imag, "r") plt.title('Frequency Response') plt.grid() plt.show()
def test_imag_part(self): # Test freqresp() imaginary part calculation. # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, H = freqresp(system, w=w) jw = w * 1j y = np.polyval(system.num, jw) / np.polyval(system.den, jw) expected_im = y.imag assert_almost_equal(H.imag, expected_im)
def test_output(self): # Test freqresp() output calculation. # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, H = freqresp(system, w=w) s = w * 1j expected = np.polyval(system.num, s) / np.polyval(system.den, s) assert_almost_equal(H.real, expected.real) assert_almost_equal(H.imag, expected.imag)
def test_real_part_manual(self): # Test freqresp() real part calculation (manual sanity check). # 1st order low-pass filter: H(s) = 1 / (s + 1), # re(H(s=0.1)) ~= 0.99 # re(H(s=1)) ~= 0.5 # re(H(s=10)) ~= 0.0099 system = lti([1], [1, 1]) w = [0.1, 1, 10] w, H = freqresp(system, w=w) expected_re = [0.99, 0.5, 0.0099] assert_almost_equal(H.real, expected_re, decimal=1)
def test_imag_part_manual(self): # Test freqresp() imaginary part calculation (manual sanity check). # 1st order low-pass filter: H(s) = 1 / (s + 1), # im(H(s=0.1)) ~= -0.099 # im(H(s=1)) ~= -0.5 # im(H(s=10)) ~= -0.099 system = lti([1], [1, 1]) w = [0.1, 1, 10] w, H = freqresp(system, w=w) expected_im = [-0.099, -0.5, -0.099] assert_almost_equal(H.imag, expected_im, decimal=1)
def run(dlc, dlc_noipc, c, C, SAVE=False): WSP = [6, 12, 18, 24] fnp = 0.16 * np.array([1, 2, 3, 4]) for wsp in WSP: # Load transfer functions P = BladeModel.Blade(wsp) Yol = OLResponse.Response(wsp) # Calculate predicted output spectrum system = ControlDesign.Turbine(P, C) w, H = signal.freqresp(system.S) f = w / (2 * np.pi) Ycl_pred = abs(H) * Yol(f) # Load close loop output spectrum Sim = dlc(yaw=0, wsp=wsp, controller=c, Kp=-1)[0] Ycl = Spectrum(Sim) fig, ax = magplotSetup(F1p=0.16) ax.set_ylabel('Magnitude [m]') ax.plot(f, Yol(f), label='$Y_{OL}$') ax.plot(f, Ycl_pred, '--k', label='$Y_{CL}$ (predicted)') ax.plot(f, Ycl(f), 'r', label='$Y_{CL}$ (actual)') ax.set_xlim(f.min(), 1.5) ax.set_title('wsp = {}m/s'.format(wsp)) ax.legend() if SAVE: plt.savefig( '../Figures/{}/{}_TipDeflection_Spectrum_{}.png'.format( c, c, wsp), dpi=200) plt.show() print() for f in fnp: pred = abs(signal.freqresp(system.S, f * 2 * np.pi)[1][0]) * 100 - 100 act = Ycl(f) / Yol(f) * 100 - 100 print('{:2.2f}%, {:2.2f}%'.format(pred, act))
def freqresp(zpkTup, ff): ''' Like scipy.signal.freqresp, but without having to pass around aggrivating factors of -2*np.pi. ''' zArr, pArr, k = zpkTup zArr = np.array(zArr) pArr = np.array(pArr) _, tf = sig.freqresp( (-2 * np.pi * zArr, -2 * np.pi * pArr, k * np.prod(-2 * np.pi * pArr) / np.prod(-2 * np.pi * zArr)), w=2 * np.pi * ff) return ff, tf
def plot_high_pass_input_impedance(values): R1, R2, C1, C2 = values tf = signal.TransferFunction([C1 * C2 * R1 * R2, R2 * (C1 + C2), 1], [C1 * C2 * R2, C1, 0.0]) print(tf) w, H = signal.freqresp(tf, np.logspace(1, 5, 1000)) plt.figure() plt.semilogx(w / (2 * np.pi), 20 * np.log10(np.abs(H))) print("Minimum input impedance:", np.min(np.abs(H))) plt.figure() plt.semilogx(w / (2 * np.pi), np.angle(H, deg=True)) plt.show()
def plot_Yol_Ycl(Yol, S, save=False): w, H = signal.freqresp(S) f_ = w / (2 * np.pi) fig, ax = magplotSetup(F1p=0.16) ax.set_ylabel('Magnitude [m]') ax.plot(f_, Yol(f_), '--k', label='$Y_{OL}$') ax.plot(f_, abs(H) * Yol(f_), label='$Y_{CL}$ (predicted)') ax.set_xlim(f_.min(), 5) ax.legend() if save: plt.savefig(save, dpi=200) plt.show() print()
def maxent(P,A,B,omega=None): assert P.ndim==2 and P.shape[0] == P.shape[1], 'P must be a square matrix' if omega is None: omega=linspace(0,2*pi,200) N = omega.size iP = inv(P) e = inv(B.T @ iP @ B) C1 = e @ B.T @ iP n,m = B.shape # Phi=C1*G(z); max entropy spectrum = Phi^{-1} e Phi^{-1}^* rA = A.real iA = A.imag AA = array([[rA, -iA],[iA, rA]]) rB = B.real iB = B.imag BB = array([[rB, -iB],[iB, rB]]) rC = C1.real iC = C1.imag CC1= array([[rC, -iC],[iC, rC]]) Phi_inv = StateSpace(AA-BB*CC1*AA, BB, -CC1*AA, eye(2*m,2*m)); HH = freqresp(Phi_inv,omega) H = HH[:m,:m,:] + 1j*HH[m:2*m,:m,:] if m==1: h = H.squeeze() spectrum = diag(h @ e @ h.T).real.T else: print('The spectrum is matricial m*m, where m=',m) spectrum = zeros((m,N*m)) halfspectrum = zeros((m,N*m)) [Ue,svdOmega] = svd(e) sqrtsvdOmega = sqrt(svdOmega) for i in range(N): temp=H[:,:,i] #H(:,:,i)=temp*e*temp.T spectrum[:,(i-1)*m:i*m] = temp @ e @ temp.T halfspectrum[:,(i-1)*m:i*m] = temp @ Ue @ sqrtsvdOmega return spectrum, halfspectrum, omega
def maxent(P,A,B,omega=None): assert P.ndim==2 and P.shape[0] == P.shape[1], 'P must be a square matrix' if omega is None: omega=linspace(0,2*pi,200) N = omega.size iP = inv(P) e = inv(B.T @ iP @ B) C1 = e @ B.T @ iP n,m = B.shape # Phi=C1*G(z); max entropy spectrum = Phi^{-1} e Phi^{-1}^* rA = A.real iA = A.imag AA = array([[rA, -iA],[iA, rA]]) rB = B.real iB = B.imag BB = array([[rB, -iB],[iB, rB]]) rC = C1.real iC = B1.imag CC1= array([[rC, -iC],[iC, rC]]) Phi_inv = StateSpace(AA-BB*CC1*AA, BB, -CC1*AA, eye(2*m,2*m)); HH = freqresp(Phi_inv,omega) H = HH[:m,:m,:] + 1j*HH[m:2*m,:m,:] if m==1: h = H.squeeze() spectrum = diag(h @ e @ h.T).real.T else: print('The spectrum is matricial m*m, where m={}'.format(m)) spectrum = zeros((m,N*m)) halfspectrum = zeros((m,N*m)) [Ue,svdOmega] = svd(e) sqrtsvdOmega = sqrt(svdOmega) for i in range(N): temp=H[:,:,i] #H(:,:,i)=temp*e*temp.T spectrum[:,(i-1)*m:i*m] = temp @ e @ temp.T halfspectrum[:,(i-1)*m:i*m] = temp @ Ue @ sqrtsvdOmega return spectrum, halfspectrum, omega
def test_from_state_space(self): # Ensure that freqresp works with a system that was created from the # state space representation matrices A, B, C, D. In this case, # system.num will be a 2-D array with shape (1, n+1), where (n,n) is # the shape of A. # A Butterworth lowpass filter is used, so we know the exact # frequency response. a = np.array([1.0, 2.0, 2.0, 1.0]) A = linalg.companion(a).T B = np.array([[0.0],[0.0],[1.0]]) C = np.array([[1.0, 0.0, 0.0]]) D = np.array([[0.0]]) with warnings.catch_warnings(): warnings.simplefilter("ignore", BadCoefficients) system = lti(A, B, C, D) w, H = freqresp(system, n=100) expected_magnitude = np.sqrt(1.0 / (1.0 + w**6)) assert_almost_equal(np.abs(H), expected_magnitude)
def test_from_state_space(self): # Ensure that freqresp works with a system that was created from the # state space representation matrices A, B, C, D. In this case, # system.num will be a 2-D array with shape (1, n+1), where (n,n) is # the shape of A. # A Butterworth lowpass filter is used, so we know the exact # frequency response. a = np.array([1.0, 2.0, 2.0, 1.0]) A = linalg.companion(a).T B = np.array([[0.0], [0.0], [1.0]]) C = np.array([[1.0, 0.0, 0.0]]) D = np.array([[0.0]]) with warnings.catch_warnings(): warnings.simplefilter("ignore", BadCoefficients) system = lti(A, B, C, D) w, H = freqresp(system, n=100) expected_magnitude = np.sqrt(1.0 / (1.0 + w**6)) assert_almost_equal(np.abs(H), expected_magnitude)
def plot_hw(self, w=None, ylabel=None, bode=False, xscale='log', yscale='log', figsize=None): w, H = signal.freqresp((self.num, self.den), w) if bode: y = 20 * np.log10(abs(H)) x = w yscale = 'linear' xlabel = r"Angular frequency $\omega$ [in rad/s]" else: if yscale == 'db': y = 20 * np.log10(abs(H)) yscale = 'linear' else: y = abs(H) yscale = 'log' x = w / 2 / np.pi xlabel = r"Frequency f [in Hz]" plt.figure(figsize=figsize) plt.subplot(2, 1, 1) plt.plot(x, y) plt.yscale(yscale) plt.xlabel(xlabel) plt.xscale(xscale) #plt.yticks(np.arange(-120,20,30)) plt.grid(which="both") plt.ylabel(ylabel if ylabel is not None else "Amplitude") plt.subplot(2, 1, 2) plt.plot(x, np.unwrap(np.angle(H)) * 180 / np.pi) plt.xscale(xscale) plt.grid(which="both") plt.yticks(np.arange(-110, 30, 40)) plt.xlabel(xlabel) plt.ylabel("Phase [in deg]") plt.tight_layout(True)
def test_from_state_space(self): # Ensure that freqresp works with a system that was created from the # state space representation matrices A, B, C, D. In this case, # system.num will be a 2-D array with shape (1, n+1), where (n,n) is # the shape of A. # A Butterworth lowpass filter is used, so we know the exact # frequency response. a = np.array([1.0, 2.0, 2.0, 1.0]) A = linalg.companion(a).T B = np.array([[0.0], [0.0], [1.0]]) C = np.array([[1.0, 0.0, 0.0]]) D = np.array([[0.0]]) with suppress_warnings() as sup: sup.filter(BadCoefficients) system = lti(A, B, C, D) w, H = freqresp(system, n=100) s = w * 1j expected = (1.0 / (1.0 + 2 * s + 2 * s**2 + s**3)) assert_almost_equal(H.real, expected.real) assert_almost_equal(H.imag, expected.imag)
def test_from_state_space(self): # Ensure that freqresp works with a system that was created from the # state space representation matrices A, B, C, D. In this case, # system.num will be a 2-D array with shape (1, n+1), where (n,n) is # the shape of A. # A Butterworth lowpass filter is used, so we know the exact # frequency response. a = np.array([1.0, 2.0, 2.0, 1.0]) A = linalg.companion(a).T B = np.array([[0.0],[0.0],[1.0]]) C = np.array([[1.0, 0.0, 0.0]]) D = np.array([[0.0]]) with suppress_warnings() as sup: sup.filter(BadCoefficients) system = lti(A, B, C, D) w, H = freqresp(system, n=100) s = w * 1j expected = (1.0 / (1.0 + 2*s + 2*s**2 + s**3)) assert_almost_equal(H.real, expected.real) assert_almost_equal(H.imag, expected.imag)
def test_PDC(): t_control_start = 5 system = sim.System(dt=T, t_stop=20) source = sim.UserDefinedSource(func_source, name='source') beam = sim.TransferFunction(SYS_D.num, SYS_D.den, name='beam') controller = sim.PDC(3, lambda x: signal.freqresp(SYS_C, x)[1], 1, 1, t_fft=t_control_start, resolution=0.01) combiner = sim.Sum('++') recorder = sim.Recorder(name='recorder') system.add_blocks(source, beam, controller, combiner, recorder) beam.inports[0].connect(combiner.outports[0]) controller.inports[0].connect(beam.outports[0]) combiner.inports[0].connect(source.outports[0]) combiner.inports[1].connect(controller.outports[0]) recorder.inports[0].connect(beam.outports[0]) system.log(source.outports[0], 'equivalent disturbance') system.log(controller.outports[0], 'controller output') system.log(beam.outports[0], 'system output') system.run() fig = system.logger.plot() fig.set_size_inches(8, 6) ax = fig.axes[0] ax.set_xlabel('Time (s)') ax.set_ylabel('Magnitude') fig.tight_layout() ylim = [-3.5, 3.5] # ax.get_ylim() ax.plot([5, 5], ylim, 'r') ax.set_ylim(ylim) ax.text(5.3, 3.05, 'control starts', color='r') ax.legend(loc='lower right')
def run(dlc=None, dlc_noipc=None, SAVE=None): f = np.linspace(0, 1.5, 1000)[1:] Yol = OLResponse.Response(18) Ycl = Spectrum(dlc(wsp=18, controller='ipcpi')[0]) C = make() P = BladeModel.Blade(18) sys = ControlDesign.Turbine(P, C) mag = signal.bode(sys.S, w=f * (2 * np.pi))[1] #actualMag = 20*np.log10(Ycl(f)/Yol(f)) w, H = signal.freqresp(sys.S, n=100000) f = w / (2 * np.pi) Ycl_pred = abs(H) * Yol(f) fig, ax = ControllerEvaluation.magplotSetup(F1p=0.16) ax.set_xlim(0.05, 1.5) ax.axhline(0, lw=1, c='0.8', ls='-') ax.plot(f, Yol(f), label='Open loop') ax.plot(f, Ycl_pred, '--k', label='Closed loop (linear)') ax.plot(f, Ycl(f), 'r', label='Closed loop (HAWC2)') #ax.plot(f, mag, label='$S(C_{PI})$, linear model') #ax.plot(f, actualMag, '--', label='$S(C_{PI})$, HAWC2 model') ax.set_ylabel('Magnitude [m]') ax.set_xlim(0.05, 1.5) ax.set_ylim(0.01, 0.4) ax.set_yscale('log') ax.legend(loc='upper right') if SAVE: plt.savefig(SAVE, dpi=200, bbox_inches='tight') plt.show() print()
#!/usr/bin/env python # encode: utf8 from scipy.io import loadmat from scipy.signal import freqresp import numpy as np import matplotlib.pyplot as plt import seaborn as sns sns.set_style('ticks') plt.close('all') f = loadmat('data/tf.mat')['f'][0, :] rawdata = loadmat('data/tf.mat')['h0'][0, :] A, B, C, D = np.load('data/ss_param.npy') _, Hfit = freqresp((A, B, C, D), 2 * np.pi * f) plt.figure(figsize=(4, 3)) plt.plot(f, abs(rawdata), '-b', label='Data') plt.plot(f, abs(Hfit), '-r', label='Fitted data') plt.ylabel('Amplitude [in mm/A]') plt.xlabel('Frequency [in Hz]') plt.yscale('log') plt.xscale('log') plt.grid(which='both') plt.ylim([min(abs(rawdata)), 11]) plt.xlim([0.3, f[-1]]) plt.legend(loc='best', frameon=True, fancybox=True) sns.despine() plt.tight_layout() plt.savefig('ctl_id_amplitude.pdf')
t, s = step(sys) # -- Plot of impulse response plt.plot(t, i, t, s) plt.title('Impulse and Unit Step Response') plt.xlabel('Time [s]') plt.ylabel('Amplitude') plt.xlim(xmax = max(t)) plt.legend(('Impulse Response', 'Unit Step Response'), loc = 0) plt.grid() plt.show() # -- Plot of frequency response w, H = freqresp(sys) plt.figure() plt.plot(w, H) plt.title('Frequency response') plt.xlabel('Frequency [rad/s]') plt.ylabel('Gain') plt.legend(('Frequency response'), loc = 0) plt.grid() plt.show() T = np.linspace(-5, 25, 1000) x1 = np.zeros(len(T)) x2 = np.zeros(len(T)) x3 = np.zeros(len(T))
EventTablePlot, EventTableAxes, HistogramPlot, HistogramAxes, SegmentPlot, SegmentAxes, SpectrogramPlot, BodePlot) from gwpy.plotter.gps import (GPSTransform, InvertedGPSTransform) from gwpy.plotter.html import map_data from gwpy.plotter.tex import (float_to_latex, label_to_latex, unit_to_latex, USE_TEX) from gwpy.plotter.table import get_column_string from test_timeseries import TEST_HDF_FILE from test_table import SnglBurstTableTestCase # design ZPK for BodePlot test ZPK = [100], [1], 1e-2 FREQUENCIES, H = signal.freqresp(ZPK, n=200) FREQUENCIES /= 2. * pi MAGNITUDE = 20 * numpy.log10(numpy.absolute(H)) PHASE = numpy.degrees(numpy.unwrap(numpy.angle(H))) __author__ = 'Duncan Macleod <*****@*****.**>' class Mixin(object): FIGURE_CLASS = Plot AXES_CLASS = Axes def new(self): """Create a new `Figure` with some `Axes` Returns (fig, ax)
TimeSeriesAxes, FrequencySeriesPlot, FrequencySeriesAxes, EventTablePlot, EventTableAxes, HistogramPlot, HistogramAxes, SegmentPlot, SegmentAxes, SpectrogramPlot, BodePlot) from gwpy.plotter.gps import (GPSTransform, InvertedGPSTransform) from gwpy.plotter.html import map_data from gwpy.plotter.tex import (float_to_latex, label_to_latex, unit_to_latex, USE_TEX) from gwpy.plotter.table import get_column_string from test_timeseries import TEST_HDF_FILE from test_table import SnglBurstTableTestCase # design ZPK for BodePlot test ZPK = [100], [1], 1e-2 FREQUENCIES, H = signal.freqresp(ZPK, n=200) FREQUENCIES /= 2. * pi MAGNITUDE = 20 * numpy.log10(numpy.absolute(H)) PHASE = numpy.degrees(numpy.unwrap(numpy.angle(H))) __author__ = 'Duncan Macleod <*****@*****.**>' class Mixin(object): FIGURE_CLASS = Plot AXES_CLASS = Axes def new(self): """Create a new `Figure` with some `Axes` Returns (fig, ax)
import matplotlib.pyplot as plt omega = np.linspace(-1000, 1000, 2000) # our desired range of omega values from scipy import signal #if using termux import subprocess import shlex #end if zeros = [] #a this list contains zeros of G(s) poles = [0] #a this list contains poles of G(s) H_s = signal.ZerosPolesGain( zeros, poles, 1 ) # feed zeros and poles as inputs to this function to get H_s which is a transfer function with GAIN=1 w, H = signal.freqresp( H_s, w=omega ) #feed H_s and omega values as inputs to this funtion it will return frequency response H of H_s and w the range of omega values of H s = 1j * w #make s=jw substitution GAIN = (np.pi * np.exp(-0.25 * s) ) #enter the GAIN function which could be either constant or variable H = H * GAIN #we multiply GAIN function with H(jw) to get our desired final transfer functions frequency response #finally H is the frequency response of our desired Transfer Function plt.plot( H.real, H.imag ) #plotting the nyquist plot of H(s) by taking Re{H} as x-axis parameter and Im{H} as y-axis parameter plt.grid() plt.xlim(-1.5, 1) #limiting x-axis values plt.xlabel("${Re}\{G(j\omega)\}$")
def test_weighting_systems(self, weighting): frequencies = NOMINAL_THIRD_OCTAVE_CENTER_FREQUENCIES values = WEIGHTING_VALUES[weighting] w, H = freqresp((WEIGHTING_SYSTEMS[weighting]()), w=2.0*np.pi*frequencies) results = 20.0*np.log10(np.abs(H)) assert(np.abs(values-results).max() < 0.3)
#import scipy.signal as signal from scipy import signal from pylab import * hold(True) # L(s) = K/s # K/(K+s) for i in logspace(-10,10): w, h = signal.freqresp(((i), (1, i))) plot(h.real, h.imag, 'b', label=str(i)) plot(h.real, -h.imag, 'r', label=str(i)) show()
# # Generating the Nyquist plot of a transfer function from scipy import signal import matplotlib.pyplot as plt s1 = signal.lti([], [1, 1, 1], [5]) # # transfer function: H(s) = 5 / (s-1)^3 w, H = signal.freqresp(s1) plt.figure() plt.plot(H.real, H.imag, "b") plt.plot(H.real, -H.imag, "r") plt.show()
def test_pole_zero(self): # Test that freqresp() doesn't fail on a system with a pole at 0. # integrator, pole at zero: H(s) = 1 / s system = lti([1], [1, 0]) w, H = freqresp(system, n=2) assert_equal(w[0], 0.01) # a fail would give not-a-number