def setFunction(self): ''' Set bode function from transfer function ''' if self.filterType == 0: # -R/L self.sig = signal.lti(\ [-self.R/self.L], \ [0], \ 1) elif self.filterType == 1: # -1/RC self.sig = signal.lti(\ [0], \ [-1/(self.C*self.R)], \ 1) elif self.filterType == 2: self.sig = signal.lti(\ [0], \ [((-1/self.L)-(1/self.L)*(self.C-4*self.L))/2,((-1/self.L)+(1/self.L)*(self.C-4*self.L))/2], \ 1) elif self.filterType == 3: self.sig = signal.lti(\ [(-1/self.L*self.C)**(1/2),-(-1/self.L*self.C)**(1/2)], \ [((-1/self.L)-(1/self.L)*(self.C-4*self.L))/2,((-1/self.L)+(1/self.L)*(self.C-4*self.L))/2], \ 1)
def decimate(x, q, n=None, ftype='iir', axis=-1, zero_phase=False): """ Downsample the signal by using a filter. By default, an order 8 Chebyshev type I filter is used. A 30 point FIR filter with hamming window is used if `ftype` is 'fir'. Parameters ---------- x : ndarray The signal to be downsampled, as an N-dimensional array. q : int The downsampling factor. n : int, optional The order of the filter (1 less than the length for 'fir'). ftype : str {'iir', 'fir'}, optional The type of the lowpass filter. axis : int, optional The axis along which to decimate. zero_phase : bool Prevent phase shift by filtering with ``filtfilt`` instead of ``lfilter``. Returns ------- y : ndarray The down-sampled signal. See also -------- resample Notes ----- The ``zero_phase`` keyword was added in 0.17.0. The possibility to use instances of ``lti`` as ``ftype`` was added in 0.17.0. """ if not isinstance(q, int): raise TypeError("q must be an integer") if ftype == 'fir': if n is None: n = 30 system = lti(firwin(n + 1, 1. / q, window='hamming'), 1.) elif ftype == 'iir': if n is None: n = 8 system = lti(*cheby1(n, 0.05, 0.8 / q)) else: system = ftype if zero_phase: y = filtfilt(system.num, system.den, x, axis=axis) else: y = lfilter(system.num, system.den, x, axis=axis) sl = [slice(None)] * y.ndim sl[axis] = slice(None, None, q) return y[sl]
def test_lti_instantiation(self): # Test that lti can be instantiated with sequences, scalars. # See PR-225. # TransferFunction s = lti([1], [-1]) assert_(isinstance(s, TransferFunction)) assert_(isinstance(s, lti)) assert_(not isinstance(s, dlti)) assert_(s.dt is None) # ZerosPolesGain s = lti(np.array([]), np.array([-1]), 1) assert_(isinstance(s, ZerosPolesGain)) assert_(isinstance(s, lti)) assert_(not isinstance(s, dlti)) assert_(s.dt is None) # StateSpace s = lti([], [-1], 1) s = lti([1], [-1], 1, 3) assert_(isinstance(s, StateSpace)) assert_(isinstance(s, lti)) assert_(not isinstance(s, dlti)) assert_(s.dt is None)
def _getABCD(arg): """Utility method to convert the input arg to an A, B, C, D representation. **Parameters:** arg, which may be: * ZPK tuple, * num, den tuple, * A, B, C, D tuple, * a scipy LTI object, * a sequence of the tuples of any of the above types. **Returns:** The sequence of ndarrays A, B, C, D **Raises:** TypeError, ValueError """ if isinstance(arg, np.ndarray): # ABCD matrix A, B, C, D = partitionABCD(arg) elif hasattr(arg, '__class__') and arg.__class__.__name__ == 'lti': A, B, C, D = arg.A, arg.B, arg.C, np.atleast_2d(arg.D) elif _is_zpk(arg) or _is_num_den(arg) or _is_A_B_C_D(arg): sys = lti(*arg) A, B, C, D = sys.A, sys.B, sys.C, sys.D elif isinstance(arg, collections.Iterable): A, B, C, D = None, None, None, None for i in arg: # Note we do not check if the user has assembled a list with # mismatched lti representations. sys = lti(*i) if not hasattr(i, 'A') else i if A is None: A = sys.A elif not np.allclose(sys.A, A, atol=1e-8, rtol=1e-5): raise ValueError("Mismatched lti list, A matrix disagreement.") else: pass if B is None: B = sys.B else: B = np.hstack((B, sys.B)) if C is None: C = sys.C elif not np.allclose(sys.C, C, atol=1e-8, rtol=1e-5): raise ValueError("Mismatched lti list, C matrix disagreement.") if D is None: D = sys.D else: D = np.hstack((D, sys.D)) else: raise TypeError("Unknown LTI representation: %s" % arg) return A, B, C, D
def SistemaW(self): """ Monta função de transferência do sistema em malha aberta ou fechada considerando com entrada w(t). """ if self.Malha == 'Aberta': return signal.lti(self.polyG2num.coeffs,self.polyG2den.coeffs) else: num = self.polyG2num * self.polyCden * self.polyGden * self.polyHden den = (self.polyCden * self.polyGden * self.polyG2den * self.polyHden) + (self.K * self.polyCnum * self.polyGnum * self.polyG2num * self.polyHnum) return signal.lti(num.coeffs,den.coeffs)
def series(sys1, sys2): """Series connection of two systems. """ if not isinstance(sys1, signal.lti): sys1 = signal.lti(*sys1) if not isinstance(sys2, signal.lti): sys2 = signal.lti(*sys2) num = np.polymul(sys1.num, sys2.num) den = np.polymul(sys1.den, sys2.den) sys = signal.lti(num, den) return sys
def feedback(plant, sensor=None): """Negative feedback connection of plant and sensor. If sensor is None, then it is assumed to be 1. """ if not isinstance(plant, signal.lti): plant = signal.lti(*plant) if sensor is None: sensor = signal.lti([1], [1]) elif not isinstance(sensor, signal.lti): sensor = signal.lti(*sensor) num = np.polymul(plant.num, sensor.den) den = np.polyadd(np.polymul(plant.den, sensor.den), np.polymul(plant.num, sensor.num)) sys = signal.lti(num, den) return sys
def GetSimWaveform(self, r,phi,z,scale, switchpoint, numSamples, temp=None, num=None, den=None, smoothing=None, electron_smoothing=None): if num is not None and den is not None: self.tfSystem = signal.lti(num, den) if temp is not None: self.siggenInst.SetTemperature(temp) if electron_smoothing is None: sig_wf = self.GetRawSiggenWaveform(r, phi, z) if sig_wf is None: return None #smoothing for charge cloud size effects if smoothing is not None: ndimage.filters.gaussian_filter1d(sig_wf, smoothing, output=sig_wf) sim_wf = self.ProcessWaveform(sig_wf, numSamples, scale, switchpoint) else: electron_wf = self.GetRawElectronWaveform(r, phi, z) hole_wf = self.GetRawHoleWaveform(r, phi, z) if hole_wf is None or electron_wf is None: #should i require only the hole signal... ?? return None ndimage.filters.gaussian_filter1d(electron_wf, electron_smoothing, output=electron_wf) ndimage.filters.gaussian_filter1d(hole_wf, smoothing, output=hole_wf) np.add(electron_wf, hole_wf, out=hole_wf) sim_wf = self.ProcessWaveform(hole_wf, numSamples, scale, switchpoint) return sim_wf
def tfc (num, den, freq, mf='std', pf='rad'): """Calculate magnitude and phase of a transfer function for a given frequency. Parameters: num, den: 1D-arrays see scipy.signal.lti for documentation freq: scalar frequency (Hz) mf: string, optional, default: 'std' accepted values: 'std', 'dB' pf: string, optional, default: 'rad' accepted values: 'rad', 'deg' Returns: mag, ph mag: scalar if mf valid else None its unity measure depends on mf NB: mag_dB = 20 * log10(mag_std) ph: scalar if pf valid else None its unity measure depends on pf """ mag, ph = None, None sys = signal.lti(num, den) w, magl, phl = signal.bode(sys, w=[2*np.pi*freq]) mag_dB, ph_deg = magl[0], phl[0] mag_std, ph_rad = 10**(mag_dB/20.), ph_deg/180.*np.pi if mf == 'std': mag = mag_std elif mf == 'dB': mag = mag_dB if pf == 'rad': ph = ph_rad elif pf == 'deg': ph = ph_deg return mag, ph
def _H(self): r"""Continuous-time linear time invariant system. This method is used to create a Continuous-time linear time invariant system for the mdof system. From this system we can obtain poles, impulse response, generate a bode, etc. """ Z = np.zeros((self.n, self.n)) I = np.eye(self.n) # x' = Ax + Bu B2 = I A = self.A() B = np.vstack([Z, la.solve(self.M, B2)]) # y = Cx + Du # Observation matrices Cd = I Cv = Z Ca = Z C = np.hstack((Cd - Ca @ la.solve(self.M, self.K), Cv - Ca @ la.solve(self.M, self.C))) D = Ca @ la.solve(self.M, B2) sys = signal.lti(A, B, C, D) return sys
def bode_plot(): # パラメータ設定 m = 1 c = 1 k = 400 A = np.array([[0, 1], [-k/m, -c/m]]) B = np.array([[0], [k/m]]) C = np.array([1, 0]) D = np.array([0]) s1 = signal.lti(A, B, C, D) w, mag, phase = signal.bode(s1, np.arange(1, 500, 1)) # プロット plt.figure(1) plt.subplot(211) plt.loglog(w, 10**(mag/20)) plt.ylabel("Amplitude") plt.axis("tight") plt.subplot(212) plt.semilogx(w, phase) plt.xlabel("Frequency[Hz]") plt.ylabel("Phase[deg]") plt.axis("tight") plt.ylim(-180, 180) plt.savefig('../files/150613ABCD01.svg')
def test_partitionABCD(): """Test function for partitionABCD()""" # FIXME: no test for m-input systems import numpy as np from scipy.signal import lti ob = lti((1, ), (1, 2, 10)) ab = np.hstack((ob.A, ob.B)) cd = np.hstack((ob.C, ob.D.reshape((1,1)))) abcd = np.vstack((ab, cd)) a, b, c, d = partitionABCD(abcd) assert np.allclose(a, ob.A, rtol=1e-5, atol=1e-8) assert np.allclose(b, ob.B, rtol=1e-5, atol=1e-8) assert np.allclose(c, ob.C, rtol=1e-5, atol=1e-8) assert np.allclose(d, ob.D, rtol=1e-5, atol=1e-8) ABCD = [[1.000000000000000, 0., 0., 0.044408783846879, -0.044408783846879], [0.999036450096481, 0.997109907515262, -0.005777399147297, 0., 0.499759089304780], [0.499759089304780, 0.999036450096481, 0.997109907515262, 0., -0.260002096136488], [0, 0, 1.000000000000000, 0, -0.796730400347216]] ABCD = np.array(ABCD) at = np.array([[1., 0., 0.], [0.999036450096481, 0.997109907515262, -0.005777399147297], [0.499759089304780, 0.999036450096481, 0.997109907515262] ]) bt = np.array([[0.044408783846879, -0.044408783846879], [0., 0.499759089304780], [0., -0.260002096136488] ]) ct = np.array([0., 0, 1]) dt = np.array([0., -0.796730400347216]) ar, br, cr, dr = partitionABCD(ABCD) assert np.allclose(at, ar, rtol=1e-5, atol=1e-8) assert np.allclose(bt, br, rtol=1e-5, atol=1e-8) assert np.allclose(ct, cr, rtol=1e-5, atol=1e-8) assert np.allclose(dt, dr, rtol=1e-5, atol=1e-8)
def filter(self, zeros=[], poles=[], gain=1, inplace=False): """Apply a filter to this `Spectrum` in zero-pole-gain format. Parameters ---------- zeros : `list`, optional list of zeros for the transfer function poles : `list`, optional list of poles for the transfer function gain : `float`, optional amplitude gain factor inplace : `bool`, optional modify this `Spectrum` in-place, default `True` Returns ------- Spectrum either a view of the current `Spectrum` with filtered data, or a new `Spectrum` with the filtered data """ # generate filter f = self.frequencies.data if not zeros and not poles: if inplace: self *= gain return self else: return self * gain else: lti = signal.lti(numpy.asarray(zeros), numpy.asarray(poles), gain) return self.filterba(lti.num, lti.den, inplace=inplace)
def second_ordre(f0, Q, filename='defaut.png', type='PBs', f=None): '''Petite fonction pour faciliter l'utilisation de la fonction "bode" du module "signal" quand on s'intéresse à des filtres du 2e ordre. Il suffit de donner la fréquence propre f0 et le facteur de qualité Q pour obtenir ce que l'on veut. Autres paramètres: * filename: le nom du fichier ('defaut.png' par défaut) * type: le type du filtre, à choisir parmi 'PBs' (passe-bas), 'PBd' (passe-bande) et 'PHt' (passe-haut). On peut aussi définir soi-même le numérateur sous forme d'une liste de plusieurs éléments, le degré le plus haut donné en premier. NB: le '1.01' des définitions est juste là pour améliorer sans effort le rendu graphique. * f: les fréquences à échantillonner (si None, la fonction choisit d'elle-même un intervalle adéquat). ''' den = [1. / f0**2, 1. / (Q * f0), 1] # Le dénominateur de la fonction de transfert if type == 'PBs': num = [1.01] # Le numérateur pour un passe-bas elif type == 'PBd': num = [1.01 / (Q * f0), 0] # pour un passe-bande elif type == 'PHt': num = [1.01 / f0**2, 0, 0] # pour un passe-haut else: # sinon, c'est l'utilisateur qui le définit. num = type # Définition de la fonction de transfert s1 = signal.lti(num, den) # Obtention des valeurs adéquates f, GdB, phase = signal.bode(s1, f) # Dessin du diagramme proprement dit diag_bode(f, GdB, phase, filename)
def rhSCCDisplacement(angVel, time): radius = 3.2e-03 #define transfer function T1 = 0.01 #value from wikibook T2 = 5 #value from wikibook #aligne with reid's line rM_reid = thr.R2(-15) #define orientation and size of right horizontal semicircular canal, and turn it into space-fixed coordinates rhScc = np.array([0.32269,-0.03837,-0.94573]) rhSccSpace = rM_reid.dot(rhScc) #sensed angular velocity in right horizontal semicircular canal vel = angVel.dot(rhSccSpace) numerator = [T1*T2, 0] denominator = [T1*T2, T1+T2, 1] scc = ss.lti(numerator,denominator) #calculate system response of input using transfer function defined above timeOut,sysResponse,timeEvol = ss.lsim(scc,vel,time) #calculate the displacement of the cupula from the system response displacementCupula = sysResponse*radius return displacementCupula
def work(self, input_items, output_items): in0 = input_items[:1] out0 = output_items[:1] # <+signal processing here+> #from multiorder_tf_sci import csim #out[:self.n] = csim(self.param0,self.param1,self.param2,self.param3,self.param4,self.param5,self.param6,self.param7,self.param8,self.param9,self.param10,in0[:self.n].tolist()) #print "OUT", out[:self.n] #self.consume(0,self.n) #self.produce(0,self.n) num = [self.param3] den = [self.param7,self.param8,self.param9] tf = lti(num, den) # get t = time, s = unit-step response #t, s = step(tf) out0[0:] = step(tf) self.consume(0,1); self.produce(0,1)
def returnScipySignalLTI(self): """Return a list of a list of scipy.signal.lti objects. For instance, >>> out = tfobject.returnScipySignalLTI() >>> out[3][5] is a signal.scipy.lti object corresponding to the transfer function from the 6th input to the 4th output. """ # TODO: implement for discrete time systems if (self.dt != 0 and self.dt is not None): raise NotImplementedError("Function not \ implemented in discrete time") # Preallocate the output. out = [[[] for j in range(self.inputs)] for i in range(self.outputs)] for i in range(self.outputs): for j in range(self.inputs): out[i][j] = lti(self.num[i][j], self.den[i][j]) return out
def fdfilter(data, *filt, **kwargs): """Filter a frequency-domain data object See Also -------- gwpy.frequencyseries.FrequencySeries.filter gwpy.spectrogram.Spectrogram.filter """ # parse keyword args inplace = kwargs.pop('inplace', False) analog = kwargs.pop('analog', False) fs = kwargs.pop('sample_rate', None) if kwargs: raise TypeError("filter() got an unexpected keyword argument '%s'" % list(kwargs.keys())[0]) # parse filter if fs is None: fs = 2 * (data.shape[-1] * data.df).to('Hz').value form, filt = parse_filter(filt, analog=analog, sample_rate=fs) lti = signal.lti(*filt) # generate frequency response freqs = data.frequencies.value.copy() fresp = numpy.nan_to_num(abs(lti.freqresp(w=freqs)[1])) # apply to array if inplace: data *= fresp return data new = data * fresp return new
def siggen_model(s, rad, phi, z, e, temp, num_1, num_2, num_3, den_1, den_2, den_3): out = np.zeros_like(data) detector.SetTemperature(temp) siggen_wf= detector.GetSiggenWaveform(rad, phi, z, energy=2600) if siggen_wf is None: return np.ones_like(data)*-1. if np.amax(siggen_wf) == 0: print "wtf is even happening here?" return np.ones_like(data)*-1. siggen_wf = np.pad(siggen_wf, (detector.zeroPadding,0), 'constant', constant_values=(0, 0)) num = [num_1, num_2, num_3] den = [1, den_1, den_2, den_3] # num = [-1.089e10, 5.863e17, 6.087e15] # den = [1, 3.009e07, 3.743e14,5.21e18] system = signal.lti(num, den) t = np.arange(0, len(siggen_wf)*10E-9, 10E-9) tout, siggen_wf, x = signal.lsim(system, siggen_wf, t) siggen_wf /= np.amax(siggen_wf) siggen_data = siggen_wf[detector.zeroPadding::] siggen_data = siggen_data*e out[s:] = siggen_data[0:(len(data) - s)] return out
def plot_bode(self,b,c): s1 = signal.lti(b,c) w, mag, phase = signal.bode(s1) plt.figure() plt.grid() plt.semilog(w, mag) plt.semilog(w, phase) plt.show()
def transfunc(): num = [1] den = [m, b, k] tf = scisig.lti(num, den) return tf
def _init_sub(self): """further init function""" sys = signal.lti(self._num, self._den) if self._fmin is not None and self._fmax is not None : wnp = np.logspace(np.log10(self._fmin*2*np.pi), np.log10(self._fmax*2*np.pi), num=1000) # consider frequencies w, mag, ph = signal.bode(sys, w=wnp) f = w/(2.*np.pi) # consider frequencies else: w, mag, ph = signal.bode(sys, n=1000) f = w/(2.*np.pi) # consider frequencies self._fmin = f[0] self._fmax = f[-1] #self.aM.tick_params(labelsize='x-small') #self.aP.tick_params(labelsize='x-small') self._aM_bl, = self.aM.semilogx(f, mag) self.aM.set_xlim([self._fmin, self._fmax]) [ymin, ymax] = self.aM.get_ylim() dy = (ymax - ymin) * 0.05 self.aM.set_ylim([ymin - dy, ymax + dy]) self.aM.set_ylabel('magnitude (dB)', size='small') self._aP_bl, = self.aP.semilogx(f, ph) self.aP.set_xlim([self._fmin, self._fmax]) [ymin, ymax] = self.aP.get_ylim() dy = (ymax - ymin) * 0.05 self.aP.set_ylim([ymin - dy, ymax + dy]) self.aP.set_ylabel('phase (degrees)', size='small') self._aM_pl, = self.aM.plot([], [], 'ro') self._aP_pl, = self.aP.plot([], [], 'ro') viniz = (np.log10(self._fmax) - np.log10(self._fmin))/4. + \ np.log10(self._fmin) self._slider = Slider(self.aS, r'freq', np.log10(self._fmin), np.log10(self._fmax), valinit=viniz) self._slider.vline.set_alpha(0.) self._slider.label.set_fontsize('small') self._slider.on_changed(self._onchange) txts = filter(lambda x: type(x)==mpl.text.Text, self.aS.get_children()) txts[1].set_visible(False) self.aT.set_axis_bgcolor('0.95') self.aT.xaxis.set_ticks_position('none') self.aT.yaxis.set_ticks_position('none') self.aT.spines['right'].set_visible(False) self.aT.spines['left'].set_visible(False) self.aT.spines['bottom'].set_visible(False) self.aT.spines['top'].set_visible(False) self.aT.set_xticks([]) self.aT.set_yticks([]) self._txt['f'] = self.aT.text(0, 0, '') self._txt['m'] = self.aT.text(0.34, 0, '') self._txt['p'] = self.aT.text(0.73, 0, '')
def add_filter(self, filter_, frequencies=None, dB=True, analog=False, sample_rate=None, **kwargs): """Add a linear time-invariant filter to this BodePlot Parameters ---------- filter_ : `~scipy.signal.lti`, `tuple` the filter to plot, either as a `~scipy.signal.lti`, or a `tuple` with the following number and meaning of elements - 2: (numerator, denominator) - 3: (zeros, poles, gain) - 4: (A, B, C, D) frequencies : `numpy.ndarray`, optional list of frequencies (in Hertz) at which to plot dB : `bool`, optional if `True`, display magnitude in decibels, otherwise display amplitude, default: `True` **kwargs any other keyword arguments accepted by :meth:`~matplotlib.axes.Axes.plot` Returns ------- mag, phase : `tuple` of `lines <matplotlib.lines.Line2D>` the lines drawn for the magnitude and phase of the filter. """ if not analog: if not sample_rate: raise ValueError("Must give sample_rate frequency to display " "digital (analog=False) filter") sample_rate = Quantity(sample_rate, 'Hz').value dt = 2 * pi / sample_rate if not isinstance(frequencies, (type(None), int)): frequencies = numpy.atleast_1d(frequencies).copy() frequencies *= dt # parse filter (without digital conversions) _, fcomp = parse_filter(filter_, analog=False) if analog: lti = signal.lti(*fcomp) else: lti = signal.dlti(*fcomp, dt=dt) # calculate frequency response w, mag, phase = lti.bode(w=frequencies) # convert from decibels if not dB: mag = 10 ** (mag / 10.) # draw mline = self.maxes.plot(w, mag, **kwargs)[0] pline = self.paxes.plot(w, phase, **kwargs)[0] return mline, pline
def test_05(self): # Test that bode() finds a reasonable frequency range. # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) n = 10 # Expected range is from 0.01 to 10. expected_w = np.logspace(-2, 1, n) w, mag, phase = bode(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 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 setUp(self): zeros = np.array(()) poles = np.array((.5,)) k = 1. self.zpk_tuple = zeros, poles, k splti = lti(zeros, poles, k) self.num_den_tuple = (splti.num, splti.den) self.ABCD_tuple = (splti.A, splti.B, splti.C, splti.D) self.splti = splti
def step_response(sys,sysd,Ts): #Draw the step response for the continuous-time and discrete-time systems sysnum = asarray(sys.num)[0][0] sysden = asarray(sys.den)[0][0] sysdnum = asarray(sysd.num)[0][0] sysdden = asarray(sysd.den)[0][0] x = arange(0,100,0.1) syslti = signal.lti(sysnum,sysden) sysdlti = signal.lti(sysdnum,sysdden) t,s = signal.step(syslti,T=x) t2,s2 = signal.dstep((sysdnum,sysdden,Ts),t=x) ax = plt.subplot(3,2,4) plt.plot(t, s,color='blue',label='Continuous-time') plt.plot(t2, s2[0],color='red',label='Discrete-time') plt.title('Step response') plt.xlabel('Time [sec]') plt.ylabel('Amplitude') plt.tight_layout(w_pad = 3.0) plt.show()
def reponse_capteur(entree): K=250 m=0.35 wn=2000 tf=signal.lti([entree*K],[(1/(wn**2)),2*m/wn,1]) t,y=signal.step(tf) return t,y
def main(argv): fitSamples = 250 #has to be longer than the longest wf you're gonna fit tempGuess = 81.5 #Set up detectors num = [3.64e+09, 1.88e+17, 6.05e+15] den = [1, 4.03e+07, 5.14e+14, 7.15e+18] system = signal.lti(num, den) gradList = np.linspace(0.01, 0.16, num=16) pcRadList = np.linspace(1.5, 2.9, num=15) pcLenList = np.linspace(1.5, 2.9, num=15) wpArray = None efld_rArray = None efld_zArray = None for (radIdx, pcRad) in enumerate(pcRadList): for (lenIdx, pcLen) in enumerate(pcLenList): for (gradIdx,grad) in enumerate(gradList): detName = "conf/P42574A_grad%0.2f_pcrad%0.2f_pclen%0.2f.conf" % (grad,pcRad, pcLen) det = Detector(detName, temperature=tempGuess, timeStep=1., numSteps=fitSamples*10, tfSystem=system) det.siggenInst.ReadElectricField() efld_r = np.array(det.siggenInst.GetElectricFieldR(), dtype=np.dtype('f4'), order='C') efld_z = np.array(det.siggenInst.GetElectricFieldZ(), dtype=np.dtype('f4'), order='C') #The "phi" component is always zero # efld_phi = np.array(det.siggenInst.GetElectricFieldPhi(), dtype=np.dtype('f4'), order='C') if efld_rArray is None: efld_rArray = np.zeros( (efld_r.shape[0], efld_r.shape[1], len(gradList), len(pcRadList), len(pcLenList) ), dtype=np.dtype('f4')) efld_zArray = np.zeros( (efld_z.shape[0], efld_z.shape[1], len(gradList), len(pcRadList), len(pcLenList) ), dtype=np.dtype('f4')) efld_rArray[:,:,gradIdx, radIdx, lenIdx] = efld_r efld_zArray[:,:,gradIdx, radIdx, lenIdx] = efld_z #WP doesn't change with impurity grad, so only need to loop thru pcRad wp = np.array(det.siggenInst.GetWeightingPotential(), dtype=np.dtype('f4'), order='C') if wpArray is None: wpArray = np.zeros((wp.shape[0], wp.shape[1], len(pcRadList), len(pcLenList) ), dtype=np.dtype('f4')) wpArray[:,:,radIdx, lenIdx] = wp # np.savez("P42574A_fields.npz", wpArray = wpArray, efld_rArray=efld_rArray, efld_zArray = efld_zArray, gradList = gradList, pcRadList = pcRadList ) r_space = np.arange(0, wpArray.shape[0]/10. , 0.1, dtype=np.dtype('f4')) z_space = np.arange(0, wpArray.shape[1]/10. , 0.1, dtype=np.dtype('f4')) wp_function = interpolate.RegularGridInterpolator((r_space, z_space, pcRadList, pcLenList), wpArray) efld_r_function = interpolate.RegularGridInterpolator((r_space, z_space, gradList, pcRadList, pcLenList), efld_rArray) efld_z_function = interpolate.RegularGridInterpolator((r_space, z_space, gradList, pcRadList, pcLenList), efld_zArray) np.savez("P42574A_fields.npz", wpArray = wpArray, efld_rArray=efld_rArray, efld_zArray = efld_zArray, gradList = gradList, pcRadList = pcRadList, pcLenList = pcLenList, wp_function = wp_function, efld_r_function=efld_r_function, efld_z_function = efld_z_function )
ax.semilogx(w, p_const_offset, lw=weight, label="constant") ax.semilogx(w, p_zero1, lw=weight, label="zero 1") ax.semilogx(w, p_pole1, lw=weight, label="pole 1") ax.semilogx(w, p_pole2, lw=weight, label="pole 2") ax.semilogx(w, np.sum([p_const_offset, p_zero1, p_pole1, p_pole2], axis=0), lw=1, label="sum", c='black') ax.set_xlabel(r"$\omega$ (rad/s)") ax.set_ylabel(r"$\angle H(\omega) (^{\circ})$") ax.legend() savefig('n_BodePlots_ex1b') # Compare approximation with exact s = signal.lti([0.1, 100], [10**-14, 10**-6 + 10**-8, 1]) w_exact, mag, phase = signal.bode(s, w=np.logspace(0, 11, 1200)) plt.clf() fig, axarr = plt.subplots(2, sharex=True, figsize=figsize(width)) axarr[0].semilogx(w_exact, mag, lw=weight, label="exact") axarr[0].semilogx(w, np.sum([const_offset, zero1, pole1, pole2], axis=0), lw=weight, label="approximation") axarr[0].set_ylabel(r"$\mid H(\omega)\mid (dB)$") axarr[0].legend() axarr[1].semilogx(w_exact, phase, lw=weight, label="exact") axarr[1].semilogx(w, np.sum([p_const_offset, p_zero1, p_pole1, p_pole2], axis=0), lw=weight, label="approximation")
Code by Gugulothu Yashwanth Naik April 30,2020 Released under GNU GPL ''' from scipy import signal import matplotlib.pyplot as plt from pylab import * #if using termux import subprocess import shlex #end if #closed loop transfer function s1 = signal.lti([50, 150], [1, 6, 58, 150]) w, mag, phase = signal.bode(s1) subplot(2, 1, 1) plt.semilogx(w, mag, label='original plot of CLTF') plt.ylabel('Mag(dB)') plt.title('Magnitude plot') plt.grid() #data points from intersection x = [ 5.08, 5.67, 6.34, 6.88, 6.98, 7.08, 7.58, 7.9, 8.02, 9.86, 11.17, 14.33, 57.91 ] y = [ 5.15, 6.8, 7.64, 7.64, 7.64, 7.64, 6.48, 5.15, 5.15, -0.81, -4.29, -10.17,
def new_fod(*args): """ new_fod(r, N, wb, wh, b, d) creates a ZPK object with a refined Oustaloup filter approximation of a fractional-order operator s^r of order N and valid within frequency range (wb, wh). s^r = (d*wh/b)^r * (ds^2 + b*wh*s)/(d*(1-r)*s^2+b*wh*s+d*r)*Gp where N ----- Gp = | | (s+w'_k) | | ---------- | | (s+wk) k= -N wk = (b*wh/d)^((r+2k)/(2N+1)) w'k = (d*wb/b)^((r-2k)/(2N+1)). Should parameters b and d be omitted, the default values will be used: b=10, d=9. :param r: signifies s^r :param N: order :param wb: frequency lower band :param wh: frequency upper band :param b: :param d: :return: Fractional Order Object """ if len(args) < 4: raise ValueError('new_fod: Not enough input arguments') elif len(args) == 4: r = args[0] N = args[1] wb = args[2] wh = args[3] b = 10 d = 9 elif len(args) == 6: r = args[0] N = args[1] wb = args[2] wh = args[3] b = args[4] d = args[5] if r == 0: return signal.lti(0) else: mu = wh / wb w_kz = [ wb * (mu**((k + N + 0.5 - (0.5 * r)) / (2 * N + 1))) for k in range(1, N + 1, 1) ] w_kp = [ wb * (mu**((k + N + 0.5 + (0.5 * r)) / (2 * N + 1))) for k in range(1, N + 1, 1) ] K = pow((d * wh / b), r) tff = signal.lti( (w_kz, w_kp, K) * tf([d, b * wh, 0], [d * (1 - r), b * wh, d * r])) return tff
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
#U, I = symbols('U I', positive=True) #t = symbols('t', positive=True, real = True) #s = symbols('s', positive=True) L = 25 C = 2.3 R = 1.5 A_CLR = A_C(C) * A_L(L) * A_R(R) H = trans_A2H(A_CLR) test_func = sympy_to_dlti(H[1, 1]) num, den = sympy_to_num_den(H[1, 1]) cont_sys = signal.lti(1, den) dis_sys = cont_sys.to_discrete(0.1) # Input t_in = np.linspace(0, 100, 1000) u_in = np.sin(t_in) + 2 plt.plot(t_in, u_in) plt.show() # Output u_out = dis_sys.output(u_in, t_in) u_out_cont = cont_sys.output(u_in, t_in) plt.plot(u_out[0], u_out[1])
max_v, min_v = np.matrix(max_v), np.matrix(min_v) # the analysis of rise time, overshoot decay ratio if max_peeks > 1: decay_ratio = (max_v[0, 0] - 1) / (max_v[1, 0] - 1) overshoot = max_v[0, 0] print 'decay ratio = ', decay_ratio print 'overshoot = ', overshoot total_varaince = np.sum(np.abs(np.diff(y))) print 'Total Varaince ', total_varaince plt.plot(time_max, max_v, 'rD') plt.plot(time_min, min_v, 'bD') plt.show() # example # time constant = 1 dampening coefficient = 0.7 and steady state gain = 1 # G = 1/(s**2+1.4*s+1) f = scs.lti([1], [1, 0.8, 1]) [t, y] = f.step() #y = np.random.random(20) #t = np.linspace(0, 19, 20) Analyses_second_order(y, t, 2)
import matplotlib.pyplot as plt from scipy import signal import control from control import tf import subprocess import shlex w1 = [ 0.1, 0.2, 0.3, 0.7, 1.0, 1.5, 2.0, 2.5, 4.0, 5.0, 6.0, 9.0, 20.0, 35.0, 50.0, 100.0 ] H_w = [ 34, 28, 24.6, 14.2, 8, 1.5, -3.5, -7.2, -10, -12.5, -14.7, -16.0, -17.5, -17.5, -18, -18.5 ] plt.semilogx((w1), H_w, 'b', label='Given Frequency response data') system = signal.lti([1, 8.5, 15], [1, 0.8, 0.07]) r = np.linspace(0.1, 100, 1001) w, mag, phase = signal.bode(system, w=r) plt.semilogx(w, (mag), 'g', label='Bode plot of Transfer Function') # Bode magnitude plot plt.ylabel("[dB]") plt.xlabel("[rad/s]") plt.legend() #if using termux plt.savefig('./figs/ee18btech11006/ee18btech11006_2.pdf') plt.savefig('./figs/ee18btech11006/ee18btech11006_2.eps') subprocess.run( shlex.split("termux-open ./figs/ee18btech11006/ee18btech11006_2.pdf")) #end if #plt.show()
def _convertToTransferFunction(sys, **kw): """Convert a system to transfer function form (if needed). If sys is already a transfer function, then it is returned. If sys is a state space object, then it is converted to a transfer function and returned. If sys is a scalar, then the number of inputs and outputs can be specified manually, as in: >>> sys = _convertToTransferFunction(3.) # Assumes inputs = outputs = 1 >>> sys = _convertToTransferFunction(1., inputs=3, outputs=2) In the latter example, sys's matrix transfer function is [[1., 1., 1.] [1., 1., 1.]]. If sys is an array-like type, then it is converted to a constant-gain transfer function. >>> sys = _convertToTransferFunction([[1. 0.], [2. 3.]]) In this example, the numerator matrix will be [[[1.0], [0.0]], [[2.0], [3.0]]] and the denominator matrix [[[1.0], [1.0]], [[1.0], [1.0]]] """ from .statesp import StateSpace if isinstance(sys, TransferFunction): if len(kw): raise TypeError("If sys is a TransferFunction, " + "_convertToTransferFunction cannot take keywords.") return sys elif isinstance(sys, StateSpace): try: from slycot import tb04ad if len(kw): raise TypeError( "If sys is a StateSpace, " + "_convertToTransferFunction cannot take keywords.") # Use Slycot to make the transformation # Make sure to convert system matrices to numpy arrays tfout = tb04ad(sys.states, sys.inputs, sys.outputs, array(sys.A), array(sys.B), array(sys.C), array(sys.D), tol1=0.0) # Preallocate outputs. num = [[[] for j in range(sys.inputs)] for i in range(sys.outputs)] den = [[[] for j in range(sys.inputs)] for i in range(sys.outputs)] for i in range(sys.outputs): for j in range(sys.inputs): num[i][j] = list(tfout[6][i, j, :]) # Each transfer function matrix row # has a common denominator. den[i][j] = list(tfout[5][i, :]) # print(num) # print(den) except ImportError: # If slycot is not available, use signal.lti (SISO only) if (sys.inputs != 1 or sys.outputs != 1): raise TypeError("No support for MIMO without slycot") lti_sys = lti(sys.A, sys.B, sys.C, sys.D) num = squeeze(lti_sys.num) den = squeeze(lti_sys.den) # print(num) # print(den) return TransferFunction(num, den, sys.dt) elif isinstance(sys, (int, float, complex)): if "inputs" in kw: inputs = kw["inputs"] else: inputs = 1 if "outputs" in kw: outputs = kw["outputs"] else: outputs = 1 num = [[[sys] for j in range(inputs)] for i in range(outputs)] den = [[[1] for j in range(inputs)] for i in range(outputs)] return TransferFunction(num, den) # If this is array-like, try to create a constant feedthrough try: D = array(sys) outputs, inputs = D.shape num = [[[D[i, j]] for j in range(inputs)] for i in range(outputs)] den = [[[1] for j in range(inputs)] for i in range(outputs)] return TransferFunction(num, den) except Exception as e: print("Failure to assume argument is matrix-like in" " _convertToTransferFunction, result %s" % e) raise TypeError("Can't convert given type to TransferFunction system.")
plt.show() ### Desde aca sistema Digital ### Convierto Forward Euler Fsampling = 4800 Tsampling = 1 / Fsampling num_d1, den_d1, td = cont2discrete((planta_real.num, planta_real.den), Tsampling, method='euler') # num_d1, den_d1, td = cont2discrete((planta_real.num, planta_real.den), Tsampling, method='zoh') # num_d1, den_d1, td = cont2discrete((planta_real.num, planta_real.den), Tsampling, method='backward_diff') # num_d1, den_d1, td = cont2discrete((planta_real.num, planta_real.den), Tsampling, method='bilinear') print('Numerador Digital planta out 1 ' + str(num_d1)) print('Denominador Digital planta out 1 ' + str(den_d1)) planta_d1 = lti(num_d1, den_d1) planta_d1_zpk = planta_d1.to_zpk() print('Ceros Digitales ' + str(planta_d1_zpk.zeros)) print('Polos Digitales ' + str(planta_d1_zpk.poles)) print('Gain Digital ' + str(planta_d1_zpk.gain)) # convierto a planta_d2 ajusto al sistema digital 2 zeros en infinito y corrijo la ganancia zd2, pd2, kd2 = tf2zpk(num_d1, den_d1) while (np.shape(zd2) < np.shape(pd2)): zd2 = np.append(zd2, [-1]) #normalizo planta_d2 = ZerosPolesGain(zd2, pd2, kd2) planta_d2 = planta_d2.to_tf() zd2, pd2, kd2 = tf2zpk(planta_d2.num, planta_d2.den)
from mpldatacursor import datacursor import numpy as np import matplotlib.pyplot as plt medicion = "meas_data/low_pass.csv" bodede = "modulo" R = 12000 C = 2.2e-9 Rg = 47 Cg = 10e-9 Zg = 200e3 BWP = 3e6 * 2 * pi sysposta = signal.lti([C * Cg * Rg, BWP * C * Cg * Rg, BWP], [ C**2 * Cg * R * Rg + C * Cg * R * Zg + C * Cg * Rg * Zg, BWP * C**2 * Cg * R * Rg + BWP * C * Cg * Rg * Zg + C * Cg * Rg + C * R + C * Rg + Cg * Zg, BWP * C * Cg * Rg + BWP * C * R + BWP * C * Rg + 1, BWP ]) sys = signal.lti([1], [(C * Rg) * Cg * Zg, C * R, 1]) simu = "spice_data/lowpass.csv" df = pd.read_csv(medicion) freq = df["freq"] amp = df["amp"] pha = df["pha"] if medicion == "meas_data/low_pass.csv": amp = -amp pha = -pha
def lti_nowarn(self, *args): with suppress_warnings() as sup: sup.filter(BadCoefficients) system = lti(*args) return system
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Thu Mar 14 03:42:46 2019 @author: adithya """ import numpy as np import scipy.signal as sp import matplotlib.pyplot as plt #Question 5 H = sp.lti(1, np.poly1d([1e-12, 1e-4, 1])) w, S, phi = H.bode() plt.figure(0) plt.subplot(211) plt.semilogx(w, S) plt.xlabel('$w$') plt.ylabel('$magnitude$') plt.title("Magnitude plot") plt.subplot(212) plt.semilogx(w, phi) plt.xlabel('$w$') plt.ylabel('$phase$') plt.title("Phase plot") plt.show() # Question 6 t = np.linspace(0, 30e-6, 1000)
from scipy import signal import matplotlib.pyplot as plt lp = signal.lti([1.0], [1.0, 1.0]) lp2 = signal.lti(*signal.lp2lp(lp.num, lp.den, 2)) w, mag_lp, p_lp = lp.bode() w, mag_lp2, p_lp2 = lp2.bode(w) plt.plot(w, mag_lp, label='Lowpass') plt.plot(w, mag_lp2, label='Transformed Lowpass') plt.semilogx() plt.grid() plt.xlabel('Frequency [rad/s]') plt.ylabel('Magnitude [dB]') plt.legend()
from scipy import signal import matplotlib.pyplot as plt s = signal.lti([1], [1, 1, 3]) w, mag, phase = signal.bode(s) plt.figure() plt.semilogx(w, mag) plt.xlabel('frequency in radians') plt.ylabel('gain in dB') # Bode magnitude plot plt.figure() plt.semilogx(w, phase) plt.xlabel('frequency in radians') plt.ylabel('phase in degrees') plt.show()
def test_error(self): # Raise an error for continuous-time systems system = lti([1], [1, 1]) assert_raises(AttributeError, dbode, system)
April 12,2020 Released under GNU GPL ''' #if using termux import subprocess import shlex #end if #Bode phase plot using scipy in python from scipy import signal import matplotlib.pyplot as plt from pylab import * #Defining the transfer function #Since the transfer function is 1/(s(1+2s)(s+1)) = 1/(2s^3 + 3s^2 + s) s1 = signal.lti([1], [2, 3, 1, 0]) #signal.bode takes transfer function as input and returns frequency,magnitude and phase arrays w, mag, phase = signal.bode(s1) subplot(2, 1, 1) #plt.xlabel('Frequency(rad/s)') plt.ylabel('Mag') plt.title('Magnitude plot') plt.plot(0.7, -3.5, 'o') plt.text(0.7, -3.5, '({}, {})'.format(0.7, -3.5)) plt.axvline(x=0.7, ymax=0.59, color='k', linestyle='dashed') plt.semilogx(w, mag, 'b') # Bode Magnitude plot plt.grid() subplot(2, 1, 2)
def test_dlsim(self): a = np.asarray([[0.9, 0.1], [-0.2, 0.9]]) b = np.asarray([[0.4, 0.1, -0.1], [0.0, 0.05, 0.0]]) c = np.asarray([[0.1, 0.3]]) d = np.asarray([[0.0, -0.1, 0.0]]) dt = 0.5 # Create an input matrix with inputs down the columns (3 cols) and its # respective time input vector u = np.hstack( (np.asmatrix(np.linspace(0, 4.0, num=5)).transpose(), 0.01 * np.ones( (5, 1)), -0.002 * np.ones((5, 1)))) t_in = np.linspace(0, 2.0, num=5) # Define the known result yout_truth = np.asmatrix( [-0.001, -0.00073, 0.039446, 0.0915387, 0.13195948]).transpose() xout_truth = np.asarray([[0, 0], [0.0012, 0.0005], [0.40233, 0.00071], [1.163368, -0.079327], [2.2402985, -0.3035679]]) tout, yout, xout = dlsim((a, b, c, d, dt), u, t_in) assert_array_almost_equal(yout_truth, yout) assert_array_almost_equal(xout_truth, xout) assert_array_almost_equal(t_in, tout) # Make sure input with single-dimension doesn't raise error dlsim((1, 2, 3), 4) # Interpolated control - inputs should have different time steps # than the discrete model uses internally u_sparse = u[[0, 4], :] t_sparse = np.asarray([0.0, 2.0]) tout, yout, xout = dlsim((a, b, c, d, dt), u_sparse, t_sparse) assert_array_almost_equal(yout_truth, yout) assert_array_almost_equal(xout_truth, xout) assert_equal(len(tout), yout.shape[0]) # Transfer functions (assume dt = 0.5) num = np.asarray([1.0, -0.1]) den = np.asarray([0.3, 1.0, 0.2]) yout_truth = np.asmatrix( [0.0, 0.0, 3.33333333333333, -4.77777777777778, 23.0370370370370]).transpose() # Assume use of the first column of the control input built earlier tout, yout = dlsim((num, den, 0.5), u[:, 0], t_in) assert_array_almost_equal(yout, yout_truth) assert_array_almost_equal(t_in, tout) # Retest the same with a 1-D input vector uflat = np.asarray(u[:, 0]) uflat = uflat.reshape((5, )) tout, yout = dlsim((num, den, 0.5), uflat, t_in) assert_array_almost_equal(yout, yout_truth) assert_array_almost_equal(t_in, tout) # zeros-poles-gain representation zd = np.array([0.5, -0.5]) pd = np.array([1.j / np.sqrt(2), -1.j / np.sqrt(2)]) k = 1.0 yout_truth = np.asmatrix([0.0, 1.0, 2.0, 2.25, 2.5]).transpose() tout, yout = dlsim((zd, pd, k, 0.5), u[:, 0], t_in) assert_array_almost_equal(yout, yout_truth) assert_array_almost_equal(t_in, tout) # Raise an error for continuous-time systems system = lti([1], [1, 1]) assert_raises(AttributeError, dlsim, system, u)
def test_07(self): # bode() should not fail on a system with pure imaginary poles. # The test passes if bode doesn't raise an exception. system = lti([1], [1, 0, 100]) w, mag, phase = bode(system, n=2)
print("H = ") print(factor(H)) #convierto a lti con Lm = 86uHy y Cp 2.3pF #num = [1.29e-16, 3.9e-11, 1] #den = [2.967e-28, 8.97e-23, 3.8e-12, 0] #convierto a lti con Lm = 86uHy y Cp 1.9pF numH = [1.29e-16, 3.9e-11, 1] denH = [2.451e-28, 7.41e-23, 3.4e-12, 0] #convierto a lti con Lm = 86nHy #num = [1.29e-19, 3.9e-11, 1] #den = [2.967e-31, 8.97e-23, 3.8e-12, 0] #convierto a lti con Lm = 86uHy y Cp 1.9pF numZ = [34704347.826087, 7826086956521.74, 2.58031221777835e+26] denZ = [7.982e-5, 18.0, 593906592697716.0, 0] sawZ = lti(numZ, denZ) wZ, magZ, phaseZ = bode(sawZ, freq) sawH = lti(numH, denH) wH, magH, phaseH = bode(sawH, freq) plt.figure(1) plt.semilogx(wH, magH, color="blue", linewidth="1") plt.semilogx(wZ, magZ, color="green", linewidth="1") plt.show()
def test_08(self): # Test that bode() return continuous phase, issues/2331. system = lti([], [-10, -30, -40, -60, -70], 1) w, mag, phase = system.bode(w=np.logspace(-3, 40, 100)) assert_almost_equal(min(phase), -450, decimal=15)
""" Caracterizacion circuito RC Analogica y Digital """ #Caracteristica del circuito R = 159.23 C = 1e-6 #Desde aca utilizo ceros y polos que entrego sympy num = [6280.22] #esto es b0 s^1 y b1 s^0 (orden descendente) den = [1, 6280.22] #esto es a0 s^1 y a1 s^0 planta = lti(num, den) print ('Ceros') print (planta.zeros) print ('Polos') print (planta.poles) freq = np.arange(100, 1e5, 1) w, mag, phase = bode(planta, freq) # wc, magc, phasec = bode(control, freq) # wo, mago, phaseo = bode(openl, freq) fig, (ax1, ax2) = plt.subplots(2,1) ax1.semilogx (w/6.28, mag, 'b-', linewidth="1")
def test_06(self): # Test that bode() 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, mag, phase = bode(system, n=2) assert_equal(w[0], 0.01) # a fail would give not-a-number
from scipy import * from pylab import * from scipy import signal T = 2.0 #T=10.0 fs = 100 dt = 1.0 / fs t = arange(0.0, T, dt) #create the time vector u = where(t > 0.5, 1, 0) #create the step input vector ylim([-0.1, 1.1]) #mysys=signal.lti(1,[1,0]) p = 4.0 * 2 * pi mysys = signal.lti(p, [1, p]) #this line defines a transfer function yo = signal.lsim2( mysys, u, t ) #this line simulates the output of the system based on input u and time t u = squeeze(u) figure(1) cla() plot(t, u, t, yo[1]) legend(['input', 'output'], 2) xlabel('Time (sec)') ylabel('Amplitude') title('Step Response') df = 1.0 / T #(t.max()-t.min()) f = arange(0, fs, df)
#import control as ctrl from scipy import signal import matplotlib.pyplot as plt import numpy as np # Programa que obtiene respuestas de lazo abierto y cerrado para # la funcion de transferencia obtenida #definir la funcion de transferencia num = [200, 0] den = [1, 102, 200] #G=ctrl.tf(num, den) #forma alternativa usando scipy G = signal.lti(num, den) #calcular la respuesta en frecuencia #mag, phase, omega = ctrl.bode(G) omega, mag, phase = signal.bode(G) #graficar la respuesta en frecuencia plt.subplot(211) l1, = plt.semilogx(omega, mag) plt.grid() plt.title('Respuesta en frecuencia') plt.ylabel('Magnitud') ## plt.subplot(212) l2, = plt.semilogx(omega, phase) plt.grid()
def _convertToStateSpace(sys, **kw): """Convert a system to state space form (if needed). If sys is already a state space, then it is returned. If sys is a transfer function object, then it is converted to a state space and returned. If sys is a scalar, then the number of inputs and outputs can be specified manually, as in: >>> sys = _convertToStateSpace(3.) # Assumes inputs = outputs = 1 >>> sys = _convertToStateSpace(1., inputs=3, outputs=2) In the latter example, A = B = C = 0 and D = [[1., 1., 1.] [1., 1., 1.]]. """ if isinstance(sys, StateSpace): if len(kw): raise TypeError("If sys is a StateSpace, _convertToStateSpace \ cannot take keywords.") # Already a state space system; just return it return sys elif isinstance(sys, xferfcn.TransferFunction): try: from slycot import td04ad if len(kw): raise TypeError("If sys is a TransferFunction, _convertToStateSpace \ cannot take keywords.") # Change the numerator and denominator arrays so that the transfer # function matrix has a common denominator. num, den = sys._common_den() # Make a list of the orders of the denominator polynomials. index = [len(den) - 1 for i in range(sys.outputs)] # Repeat the common denominator along the rows. den = array([den for i in range(sys.outputs)]) # TODO: transfer function to state space conversion is still buggy! #print num #print shape(num) ssout = td04ad('R',sys.inputs, sys.outputs, index, den, num,tol=0.0) states = ssout[0] return StateSpace(ssout[1][:states, :states], ssout[2][:states, :sys.inputs], ssout[3][:sys.outputs, :states], ssout[4]) except ImportError: lti_sys = lti(squeeze(sys.num), squeeze(sys.den))#<-- do we want to squeeze first # and check dimenations? I think # this will fail if num and den aren't 1-D # after the squeeze return StateSpace(lti_sys.A, lti_sys.B, lti_sys.C, lti_sys.D) elif isinstance(sys, (int, long, float, complex)): if "inputs" in kw: inputs = kw["inputs"] else: inputs = 1 if "outputs" in kw: outputs = kw["outputs"] else: outputs = 1 # Generate a simple state space system of the desired dimension # The following Doesn't work due to inconsistencies in ltisys: # return StateSpace([[]], [[]], [[]], eye(outputs, inputs)) return StateSpace(0., zeros((1, inputs)), zeros((outputs, 1)), sys * ones((outputs, inputs))) else: raise TypeError("Can't convert given type to StateSpace system.")
import math as mp import matplotlib.pyplot as plt from scipy import signal import control from control import tf import subprocess import shlex w1=[0.1,0.2,0.3,0.7,1.0,1.5,2.0,2.5,4.0,5.0,6.0,9.0,20.0,35.0,50.0,100.0] H_w=[34,28,24.6,14.2,8,1.5,-3.5,-7.2,-10,-12.5,-14.7,-16.0,-17.5,-17.5,-18,-18.5] m=np.array([]) for i in range(15): M=(H_w[i+1]-H_w[i])/(np.log10(w1[i+1]/w1[i])) m=np.append(m,M) print(m) plt.semilogx((w1),H_w,'b',label='Given Frequency response data') system = signal.lti([1,8.5,15], [1,0.8,0.07]) r = np.linspace(0.1, 100,1001) w, mag, phase = signal.bode(system, w=r) plt.semilogx(w,mag,'g',label='Bode plot of transfer function without gain') system = signal.lti([1*0.1778,8.5*0.1778,15*0.1778], [1,0.8,0.07]) r = np.linspace(0.1, 100,1001) w, mag, phase = signal.bode(system, w=r) plt.semilogx(w,mag,'r',label='Bode plot of final transfer function') plt.legend() plt.ylabel("[dB]") plt.xlabel("[rad/s]") # Bode magnitude plot plt.grid() #if using termux plt.savefig('./figs/ee18btech11006/ee18btech11006_3.pdf') plt.savefig('./figs/ee18btech11006/ee18btech11006_3.eps') subprocess.run(shlex.split("termux-open ./figs/ee18btech11006/ee18btech11006_3.pdf"))
f = datos[:,0] A = datos[:,1] simulacion = open("/Users/rodrigovazquez/Library/Mobile Documents/3L68KQB4HG~com~readdle~CommonDocuments/Documents/ADC/TP2019/Simulacion/PasaAlto.txt","r") datos = np.loadtxt(simulacion,delimiter='\t') print(datos) # Generador de transferencia en funcion de los coeficientes del numerador y denominador numI = [1,0,0] denI = [1,3510,1.004e7] numR = [1,0,0] denR = [1,(100000/33),9768868] hz = np.logspace(6.2, 8) rad_n = hz * 2 * np.pi / (1 / 5e-05) s1 = signal.lti(numI,denI) s2 = signal.lti(numR,denR) wI, amplitudI, faseI = signal.bode(s1, w=rad_n) wR, amplitudR, faseR = signal.bode(s2, w=rad_n) wI = wI / 2 / np.pi wR = wR / 2 / np.pi # Graficos plt.semilogx(wI,amplitudI,'-b',linewidth = 1.8,label = 'Curva ideal') # Grafica bode ideal plt.semilogx(wR,amplitudR,'--r',linewidth = 1.8, label = 'Curva real') plt.semilogx(f,A,'.g',linewidth = 1.8,label = 'Curva medida') # Grafica bode de modulo plt.title('Bode de modulo') plt.xlabel('Frecuencia [Hz]') plt.ylabel('Amplitud [dB]') plt.legend(loc='lower right', fontsize = 'large') plt.grid(which = 'major', color = 'gray', linestyle = '--')
dSlopes = Slopes[1:] - Slopes[:-1] Num = [] Den = [] for i in range(len(dSlopes)): if dSlopes[i] % 20 != 0: return None if dSlopes[i] >= 0: Num += [10**(i + 1)] * (dSlopes[i] // 20) else: Den += [10**(i + 1)] * (-dSlopes[i] // 20) return np.array(Num), np.array(Den) Num, Den = getTransferFunction(Slopes) s1 = signal.lti(Num, Den, 1e15) w, mag, phase = signal.bode(s1) plt.figure() plt.xlabel("f") plt.ylabel("H(f)") plt.title("Bode Plot") plt.semilogx(w, mag) # Bode magnitude plot plt.grid() x = np.array([1, 10, 100, 1000, 10000, 1e5, 1e6, 1e7]) y = [] k = 100 for i in range(len(x) - 1): y.append(k) k += Slopes[i]
@author: Hrithik """ import numpy as np from scipy import signal import matplotlib.pyplot as plt #if using termux import subprocess import shlex #end if G = 1 num = [0, -0.01, 0.05] #describing transfer function den = [0.0001, 0, 1] system = signal.lti(num, den) T, yout = signal.impulse(system) #oscillating response plt.plot(T, yout) plt.grid() plt.xlabel("time (t)") plt.title("Impulse system response ") #if using termux plt.savefig('./figs/es17btech11009/es17btech11009_imp.pdf') plt.savefig('./figs/es17btech11009/es17btech11009_imp.eps') subprocess.run( shlex.split("termux-open ./figs/es17btech11009/es17btech11009_imp.pdf")) #else #plt.show()
from pylab import * from scipy import signal # Define transfer function k = 1 # sensitivity wn = 546.72 # rad/s z = 0.467 # damping sys = signal.lti(k * wn**2, [1, 2 * z * wn, wn**2]) plot(arange(1000) / wn, sys.step(N=1000)[1]) title('Step response') xlabel('$t$ [sec]') ylabel('E [V]') show()