def plot_step(analog_system, discrete_system, num_samples=100, sample_rate=48e3, plot_error=False): n = np.arange(num_samples) _, ya = signal.step2(analog_system, T=n / sample_rate) _, yd = signal.dstep((*discrete_system, 1 / sample_rate), t=n / sample_rate) fig, ax1 = plt.subplots() ax1.set_title('Invariância ao degrau') ax1.plot(n, ya, 'b') ax1.plot(n, np.ravel(yd), 'k.') ax1.set_ylabel('Amplitude', color='b') ax1.set_xlabel('Amostras') ax1.grid(True) ax1.legend(['Analógico', 'Discreto']) if plot_error: ax2 = ax1.twinx() ax2.plot(n, np.abs(ya - np.ravel(yd)), 'r') ax2.set_ylabel('Erro', color='r') ax2.axis('tight') pass
def stepmodel2(num, den): import matplotlib.pyplot as plt from scipy import signal t, y = signal.step2((num, den)) #TODO: Note this messes up for unstable or oscillatory systems get_last_value = y[-1] dcgain = [get_last_value] * len(t) plt.figure("Step Response") plt.ion() plt.rc('font', family='serif') plt.rc('xtick', labelsize='x-small') plt.rc('ytick', labelsize='x-small') plt.plot(t, y, 'black', label='Model') plt.plot(t, dcgain, 'k:', label='Command') plt.fill_between(t, y, dcgain, color='lightgrey', alpha=0.3) plt.xlabel('Time (seconds)') plt.ylabel('Amplitude') plt.title('Step Response') plt.legend(loc='lower right') return plt.show()
def continuous(): k2 = 3 k1 = 5 Ds = lti([k2, k1, 0], [1, k2, k1]) Fs = lti([k2, k1], [1, k2, k1]) timeFs, stepFs = step2(Fs) f, ax = plt.subplots(1, 1, sharex='col', sharey='row') ax.plot(timeFs, stepFs, 'b') plt.show()
def create_abaque_tr(): m_vect = np.logspace(-1, 1, num=150) tr_vect = [] for m in m_vect: sys = signal.lti(1, [1, 2 * m, 1]) t, s = signal.step2(sys) index = np.where((s < 0.95) | (s > 1.05))[0] last_index = index[-1] + 1 tr_vect.append(t[last_index]) return m_vect, tr_vect
def step(num, den, time, label): """ Draws output for a step input :param num: [a_n, a_n-1, ..., a_], numerator of transfer function :param den: idem, denominator of transfer function :param time: :return: """ F = signal.TransferFunction(num, den) ts, yout = signal.step2(F, T=time) plt.plot(ts, yout, label=label)
def stepSig_demo(): from scipy.signal import lti, step2, impulse2 import matplotlib.pyplot as plt s1 = lti([3], [1, 2, 10]) # 以分子分母的最高次幂降序的系数构建传递函数,s1=3/(s^2+2s+10) s2 = lti([1], [1, 0.4, 1]) # s2=1/(s^2+0.4s+1) s3 = lti([5], [1, 2, 5]) # s3=5/(s^2+2s+5) t1, y1 = step2(s1) # 计算阶跃输出,y1是Step response of system. t2, y2 = step2(s2) t3, y3 = step2(s3) t11, y11 = impulse2(s1) t22, y22 = impulse2(s2) t33, y33 = impulse2(s3) f, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = plt.subplots(2, 3, sharex='col', sharey='row') # 开启subplots模式 ax1.plot(t1, y1, 'r', label='s1 Step Response', linewidth=0.5) ax1.set_title('s1 Step Response', fontsize=9) ax2.plot(t2, y2, 'g', label='s2 Step Response', linewidth=0.5) ax2.set_title('s2 Step Response', fontsize=9) ax3.plot(t3, y3, 'b', label='s3 Step Response', linewidth=0.5) ax3.set_title('s3 Step Response', fontsize=9) ax4.plot(t11, y11, 'm', label='s1 Impulse Response', linewidth=0.5) ax4.set_title('s1 Impulse Response', fontsize=9) ax5.plot(t22, y22, 'y', label='s2 Impulse Response', linewidth=0.5) ax5.set_title('s2 Impulse Response', fontsize=9) ax6.plot(t33, y33, 'k', label='s3 Impulse Response', linewidth=0.5) ax6.set_title('s3 Impulse Response', fontsize=9) ##plt.xlabel('Times') ##plt.ylabel('Amplitude') # plt.legend() plt.show()
def step_response_BF_cor(num1, den1, num2, den2, feedback=1, t=None): if t == None: t = np.linspace(0, 10, 101) sys1 = ctl.tf(num1, den1) sys2 = ctl.tf(num2, den2) sys_BO = ctl.series(sys1, sys2) sys_BF = g = ctl.feedback(sys_BO, feedback) lti_BF = sys_BF.returnScipySignalLti()[0][0] t, s = signal.step2(lti_BF, None, t) return t, s
def stepmodel(self, num, den): t, y = signal.step2((num, den)) #TODO: Note this messes up for unstable or oscillatory systems get_last_value = y[-1] dcgain = [get_last_value] * len(t) upper_limit_error = get_last_value + 0.02 * get_last_value lower_limit_error = get_last_value - 0.02 * get_last_value plt.figure("Step Response") plt.ion() plt.plot(t, y, 'dodgerblue', t, dcgain, 'k:') plt.xlabel('Time (seconds)') plt.ylabel('Amplitude') plt.title('Step Response') return plt.show()
def stepmodel(num, den): import matplotlib.pyplot as plt from scipy import signal t, y = signal.step2((num, den)) #TODO: Note this messes up for unstable or oscillatory systems get_last_value = y[-1] dcgain = [get_last_value] * len(t) plt.figure("Step Response") plt.ion() plt.plot(t, y, 'dodgerblue', t, dcgain, 'k:') plt.xlabel('Time (seconds)') plt.ylabel('Amplitude') plt.title('Step Response') return plt.show()
def step_response_BF_pert(num1, den1, num2, den2, feedback=1, pert=0.25, pert_time=1, t=None): if t == None: t = np.linspace(0, 10, 101) sys1 = ctl.tf(num1, den1) sys2 = ctl.tf(num2, den2) sys_BO1 = ctl.series(sys1, sys2) sys_BF1 = g = ctl.feedback(sys_BO1, feedback) lti_BF1 = sys_BF1.returnScipySignalLti()[0][0] sys_BF2 = g = ctl.feedback(sys2, sys1) lti_BF2 = sys_BF2.returnScipySignalLti()[0][0] u = pert * (t > pert_time) t, s1 = signal.step2(lti_BF1, None, t) t, s2, trash = signal.lsim2(lti_BF2, u, t) s = s1 + s2 return t, s
def plot_time(analog_system, discrete_system, response='step', num_samples=100, sample_rate=48e3, plot_error=False): n = np.arange(num_samples) t = n/sample_rate fig, ax1 = plt.subplots() if response == 'impulse': ta, ya = signal.impulse2(analog_system, T=t) _, yd = signal.dimpulse((*discrete_system,1/sample_rate), t=t) ax1.set_title('Resposta ao impulso') elif response == 'step': ta, ya = signal.step2(analog_system, T=t) _, yd = signal.dstep((*discrete_system,1/sample_rate), t=t) ax1.set_title('Resposta ao degrau') elif response == 'ramp': ramp_factor = 1 ta = np.arange(int(num_samples*ramp_factor))/(ramp_factor*sample_rate) print(ta.shape) ta, ya, xa = signal.lsim2(analog_system, U=ta, T=ta, printmessg=True) _, yd = signal.dlsim((*discrete_system,1/sample_rate), u=t, t=t, x0=None) ax1.set_title('Resposta a rampa') ax1.plot(ta*sample_rate,ya,'b') ax1.plot(n,np.ravel(yd),'k.') ax1.set_ylabel('Amplitude', color='b') ax1.set_xlabel('Amostras') ax1.grid(True) ax1.legend(['Analógico', 'Discreto']) if plot_error: ax2 = ax1.twinx() ax2.plot(n, np.abs(ya-np.ravel(yd)), 'r') ax2.set_ylabel('Erro', color='r') ax2.axis('tight')
##################################################### # Desde aca utilizo ceros y polos que entrego sympy # ##################################################### planta = sympy_to_lti(Plant_out_sim) sensado = sympy_to_lti(Plant_out_sim * sense_probe_alpha) print ("planta con sympy:") print (planta) ############################################### # Respuesta escalon de la planta y el sensado # ############################################### tiempo_de_simulacion = 0.1 t = np.linspace(0, tiempo_de_simulacion, num=2000) t, y = step2(planta, T=t) yp = y * Input_step_value t, y = step2(sensado, T=t) ys = y * Input_step_value fig, ax = plt.subplots() ax.set_title('Respuesta Escalon Planta [yellow] Sensado [Blue]') ax.set_ylabel('Vout') ax.set_xlabel('Tiempo [s]') ax.grid() ax.plot(t, yp, 'y') ax.plot(t, ys, 'b') plt.tight_layout() plt.show()
def pulse(S, tp=(0., 1.), dt=1., tfinal=10., nosum=False): """Calculate the sampled pulse response of a CT system. ``tp`` may be an array of pulse timings, one for each input, or even a simple 2-elements tuple. **Parameters:** S : sequence A sequence of LTI objects specifying the system. The sequence S should be assembled so that ``S[i][j]`` returns the LTI system description from input ``i`` to the output ``j``. In the case of a MISO system, a unidimensional sequence ``S[i]`` is also acceptable. tp : array-like An (n, 2) array of pulse timings dt : scalar The time increment tfinal : scalar The time of the last desired sample nosum : bool A flag indicating that the responses are not to be summed **Returns:** y : ndarray The pulse response """ tp = np.asarray(tp) if len(tp.shape) == 1: if not tp.shape[0] == 2: raise ValueError("tp is not (n, 2)-shaped") tp = tp.reshape((1, tp.shape[0])) if len(tp.shape) == 2: if not tp.shape[1] == 2: raise ValueError("tp is not (n, 2)-shaped") # Compute the time increment dd = 1 for tpi in np.nditer(tp.T.copy(order='C')): _, di = rat(tpi, 1e-3) dd = lcm(di, dd) _, ddt = rat(dt, 1e-3) _, df = rat(tfinal, 1e-3) delta_t = 1./lcm(dd, lcm(ddt, df)) delta_t = max(1e-3, delta_t) # Put a lower limit on delta_t if (isinstance(S, collections.Iterable) and len(S)) \ and (isinstance(S[0], collections.Iterable) and len(S[0])) \ and (isinstance(S[0][0], lti) or _is_zpk(S[0][0]) or _is_num_den(S[0][0]) \ or _is_A_B_C_D(S[0][0])): pass else: S = list(zip(S)) #S[input][output] y1 = None for Si in S: y2 = None for So in Si: _, y2i = step2(So, T=np.arange(0., tfinal + delta_t, delta_t)) if y2 is None: y2 = y2i.reshape((y2i.shape[0], 1, 1)) else: y2 = np.concatenate((y2, y2i.reshape((y2i.shape[0], 1, 1))), axis=1) if y1 is None: y1 = y2 else: y1 = np.concatenate((y1, y2), axis=2) nd = int(np.round(dt/delta_t, 0)) nf = int(np.round(tfinal/delta_t, 0)) ndac = tp.shape[0] ni = len(S) # number of inputs if ni % ndac != 0: raise ValueError('The number of inputs must be divisible by the number of dac timings.') # Original comment from the MATLAB sources: # This requirement comes from the complex case, where the number of inputs # is 2 times the number of dac timings. I think this could be tidied up. # nis: Number of inputs grouped together with a common DAC timing # (2 for the complex case) nis = int(ni/ndac) # notice len(S[0]) is the number of outputs for us if not nosum: # Sum the responses due to each input set y = np.zeros((np.ceil(tfinal/float(dt)) + 1, len(S[0]), nis)) else: y = np.zeros((np.ceil(tfinal/float(dt)) + 1, len(S[0]), ni)) for i in range(ndac): n1 = int(np.round(tp[i, 0]/delta_t, 0)) n2 = int(np.round(tp[i, 1]/delta_t, 0)) z1 = (n1, y1.shape[1], nis) z2 = (n2, y1.shape[1], nis) yy = + np.concatenate((np.zeros(z1), y1[:nf-n1+1, :, i*nis:(i + 1)*nis]), axis=0) \ - np.concatenate((np.zeros(z2), y1[:nf-n2+1, :, i*nis:(i + 1)*nis]), axis=0) yy = yy[::nd, :, :] if not nosum: # Sum the responses due to each input set y = y + yy else: y[:, :, i] = yy.reshape(yy.shape[0:2]) return y
def updateUI(self): get_num = self.lineEdit_3.text() get_den = self.lineEdit_7.text() num = get_num.split(",") num = map(float, num) den = get_den.split(",") den = map(float, den) system = (num, den) t, y = step2(system) w, mag, phase = bode(system) TF = tf(num, den) OS_TS = tfchar(TF) os = str(OS_TS[0]) ts = str(OS_TS[1]) size = len(t) dcgain = y[size - 1] x = np.linspace(dcgain, dcgain, size) self.Plant_tf_textBrowser.insertPlainText(TF) if self.checkBox_2.isChecked(): self.plot.axes.plot(t, x, 'k--') self.plot.axes.plot(t, y, 'k') self.plot.axes.fill_between(t, y, dcgain, color='b', alpha=0.5) self.plot.axes.set_title('Step Response') self.plot.axes.set_xlabel('Time (sec)') self.plot.axes.set_ylabel('Amplitude') self.plot.axes.grid() self.plot.show() self.plot.draw() if self.checkBox_3.isChecked(): self.plot2.axes.semilogx(w, mag, 'k') self.plot2.axes.set_title('Bode Magnitude Plot') self.plot2.axes.set_xlabel('Magnitude') self.plot2.axes.set_ylabel('Omega (w)') self.plot2.axes.grid() self.plot2.draw() self.plot2.show() self.plot3.axes.semilogx(w, phase, 'k') self.plot3.axes.set_title('Bode Phase Plot') self.plot3.axes.set_xlabel('Phase Angle') self.plot3.axes.set_ylabel('Omega (w)') self.plot3.axes.grid() self.plot3.draw() self.plot3.show() if self.checkBox.isChecked(): self.root() if self.checkBox_4.isChecked(): z1 = self.lineEdit.text() z2 = self.lineEdit_2.text() p1 = self.lineEdit_4.text() p2 = self.lineEdit_5.text() K = self.lineEdit_6.text() z1 = float(z1) z2 = float(z2) p1 = float(p1) p2 = float(p2) K = float(K) selection = self.comboBox.currentText() selection = str(selection) if K == 0.0: return_error = 'K = 0' + '\n' + 'The gain of the system is 0' + '\n' + 'Can not step response' self.textBrowser.insertPlainText(return_error) if selection == 'Proportional': num_P = [] for i in num: num_P.append(K * i) den_P = np.polyadd(den, num_P) system_P = (num_P, den_P) t_P, y_P = step2(system_P) w_P, mag_P, phase_P = bode(system_P) # %OverShoot & Settling time a_max = np.amax(y_P) size_P = len(t_P) dcgain_P = y_P[size_P - 1] OS = (a_max - dcgain_P) * 100 OS = format(OS, '.2f') OS = str(OS + '%') if y_P[0] == 0: dcgain_P = 0.0 count = 0 count2 = -1 for i in y_P: count = count + 1 if i == a_max: stop_value = count - 1 break for j in t_P: count2 = count2 + 1 OS_x = np.linspace(0, t_P[stop_value], size_P) OS_y = np.linspace(a_max, a_max, size_P) OS_x1 = np.linspace(t_P[stop_value], t_P[stop_value], size_P) OS_y2 = np.linspace(dcgain_P, a_max, size_P) x_P = np.linspace(dcgain_P, dcgain_P, size_P) if self.checkBox_OS.isChecked(): OS_x = np.linspace(0, t_P[stop_value], size_P) OS_y = np.linspace(a_max, a_max, size_P) OS_x1 = np.linspace(t_P[stop_value], t_P[stop_value], size_P) OS_y2 = np.linspace(dcgain_P, a_max, size_P) else: OS_x = np.linspace(0, 0, size_P) OS_y = np.linspace(0, 0, size_P) OS_x1 = np.linspace(0, 0, size_P) OS_y2 = np.linspace(0, 0, size_P) if self.checkBox_Error.isChecked(): e_t = 0.02 * (dcgain_P) + dcgain_P e_b = dcgain_P - 0.02 * (dcgain_P) error_t_x = np.linspace(0, t_P[count2], size_P) error_t_y = np.linspace(e_t, e_t, size_P) error_b_x = np.linspace(0, t_P[count2], size_P) error_b_y = np.linspace(e_b, e_b, size_P) else: e_t = 0.02 * (dcgain_P) + dcgain_P e_b = dcgain_P - 0.02 * (dcgain_P) error_t_x = np.linspace(0, 0, size_P) error_t_y = np.linspace(0, 0, size_P) error_b_x = np.linspace(0, 0, size_P) error_b_y = np.linspace(0, 0, size_P) flag = -1 for i in reversed(y_P): flag = flag + 1 if (i > e_t or i < e_b): break new_t = [] for j in reversed(t_P): new_t.append(j) Ts = new_t[flag] if self.checkBox_Ts.isChecked(): t_s_x = np.linspace(Ts, Ts, size_P) t_s_y = np.linspace(0, dcgain_P, size_P) else: t_s_x = np.linspace(0, 0, size_P) t_s_y = np.linspace(0, 0, size_P) self.plot4.axes.plot(t_P, y_P, 'k', t_P, x_P, 'k--', OS_x, OS_y, 'k-.', OS_x1, OS_y2, 'k-.', error_t_x, error_t_y, 'r--', error_b_x, error_b_y, 'r--', t_s_x, t_s_y, 'k--') if self.checkBox_Fill.isChecked(): self.plot4.axes.fill_between(t_P, y_P, dcgain_P, color='b', alpha=0.5) else: pass self.plot4.axes.set_title('Step Response (P)') self.plot4.axes.set_xlabel('Time (sec)') self.plot4.axes.set_ylabel('Amplitude') self.plot4.axes.grid() self.plot4.draw() self.plot4.show() Ts = format(Ts, '.2f') Ts = str(Ts + 's') K = str(K) return_P = 'K = ' + ' ' + K self.textBrowser.insertPlainText(return_P) return_char = 'Overshoot = ' + ' ' + OS + '\n' + 'Settling Time =' + ' ' + Ts self.System_Characteristics_textBrowser.insertPlainText( return_char) if self.checkBox_3.isChecked(): self.plot2.axes.semilogx(w_P, mag_P, 'k') self.plot2.axes.set_title('Bode Magnitude Plot (P)') self.plot2.axes.set_xlabel('Magnitude') self.plot2.axes.set_ylabel('Omega (w)') self.plot2.axes.grid() self.plot2.draw() self.plot2.show() self.plot3.axes.semilogx(w_P, phase_P, 'k') self.plot3.axes.set_title('Bode Phase Plot (P)') self.plot3.axes.set_xlabel('Phase Angle') self.plot3.axes.set_ylabel('Omega (w)') self.plot3.axes.grid() self.plot3.draw() self.plot3.show() if selection == 'PID': N_c = [K, K * (z1 + z2), K * z1 * z2] D_c = [1, 0] Numerator = np.convolve(num, N_c) DgDc = np.convolve(den, D_c) Denominator = np.polyadd(DgDc, Numerator) system_PID = (Numerator, Denominator) t_PID, y_PID = step2(system_PID) w_PID, mag_PID, phase_PID = bode(system_PID) # %OverShoot & Settling time a_max = np.amax(y_PID) size_PID = len(t_PID) dcgain_PID = y_PID[size_PID - 1] OS = (a_max - dcgain_PID) * 100 OS = format(OS, '.2f') OS = str(OS + '%') if y_PID[0] == 0: dcgain_PID = 0.0 count = 0 count2 = -1 for i in y_PID: count = count + 1 if i == a_max: stop_value = count - 1 break for j in t_PID: count2 = count2 + 1 x_PID = np.linspace(dcgain_PID, dcgain_PID, size_PID) if self.checkBox_OS.isChecked(): OS_x = np.linspace(0, t_PID[stop_value], size_PID) OS_y = np.linspace(a_max, a_max, size_PID) OS_x1 = np.linspace(t_PID[stop_value], t_PID[stop_value], size_PID) OS_y2 = np.linspace(dcgain_PID, a_max, size_PID) else: OS_x = np.linspace(0, 0, size_PID) OS_y = np.linspace(0, 0, size_PID) OS_x1 = np.linspace(0, 0, size_PID) OS_y2 = np.linspace(0, 0, size_PID) if self.checkBox_Error.isChecked(): e_t = 0.02 * (dcgain_PID) + dcgain_PID e_b = dcgain_PID - 0.02 * (dcgain_PID) error_t_x = np.linspace(0, t_PID[count2], size_PID) error_t_y = np.linspace(e_t, e_t, size_PID) error_b_x = np.linspace(0, t_PID[count2], size_PID) error_b_y = np.linspace(e_b, e_b, size_PID) else: e_t = 0.02 * (dcgain_PID) + dcgain_PID e_b = dcgain_PID - 0.02 * (dcgain_PID) error_t_x = np.linspace(0, 0, size_PID) error_t_y = np.linspace(0, 0, size_PID) error_b_x = np.linspace(0, 0, size_PID) error_b_y = np.linspace(0, 0, size_PID) flag = -1 for i in reversed(y_PID): flag = flag + 1 if (i > e_t or i < e_b): break new_t = [] for j in reversed(t_PID): new_t.append(j) Ts = new_t[flag] if self.checkBox_Ts.isChecked(): t_s_x = np.linspace(Ts, Ts, size_PID) t_s_y = np.linspace(0, dcgain_PID, size_PID) else: t_s_x = np.linspace(0, 0, size_PID) t_s_y = np.linspace(0, 0, size_PID) self.plot4.axes.plot(t_PID, y_PID, 'k', t_PID, x_PID, 'k--', OS_x, OS_y, 'k-.', OS_x1, OS_y2, 'k-.', error_t_x, error_t_y, 'r--', error_b_x, error_b_y, 'r--', t_s_x, t_s_y, 'k--') if self.checkBox_Fill.isChecked(): self.plot4.axes.fill_between(t_PID, y_PID, dcgain_PID, color='b', alpha=0.5) else: pass self.plot4.axes.set_title('Step Response (PID)') self.plot4.axes.set_xlabel('Time (sec)') self.plot4.axes.set_ylabel('Amplitude') self.plot4.axes.grid() self.plot4.draw() self.plot4.show() z1_dis = str(z1) z2_dis = str(z2) Ts = format(Ts, '.2f') Ts = str(Ts + 's') return_char = 'Overshoot = ' + ' ' + OS + '\n' + 'Settling Time =' + ' ' + Ts return_PID = '(s' + ' ' + '+' + ' ' + z1_dis + ')' + ' ' + '(s' + ' ' + '+' + ' ' + z2_dis + ')' + '\n' + '-----------------------' + '\n' + ' ' + 's' self.textBrowser.insertPlainText(return_PID) self.System_Characteristics_textBrowser.insertPlainText( return_char) if self.checkBox_3.isChecked(): self.plot2.axes.semilogx(w_PID, mag_PID, 'k') self.plot2.axes.set_title('Bode Magnitude Plot (PID)') self.plot2.axes.set_xlabel('Magnitude') self.plot2.axes.set_ylabel('Omega (w)') self.plot2.axes.grid() self.plot2.draw() self.plot2.show() self.plot3.axes.semilogx(w_PID, phase_PID, 'k') self.plot3.axes.set_title('Bode Phase Plot (PID)') self.plot3.axes.set_xlabel('Phase Angle') self.plot3.axes.set_ylabel('Omega (w)') self.plot3.axes.grid() self.plot3.draw() self.plot3.show() if selection == 'PI-Lead': N_c = [K, K * (z1 + z2), K * z1 * z2] D_c = [1, p1, 0] Numerator = np.convolve(num, N_c) DgDc = np.convolve(den, D_c) Denominator = np.polyadd(DgDc, Numerator) system_PI_Lead = (Numerator, Denominator) t_PI_Lead, y_PI_Lead = step2(system_PI_Lead) w_PI_Lead, mag_PI_Lead, phase_PI_Lead = bode(system_PI_Lead) # %OverShoot & Settling time a_max = np.amax(y_PI_Lead) size_PI_Lead = len(t_PI_Lead) dcgain_PI_Lead = y_PI_Lead[size_PI_Lead - 1] OS = (a_max - dcgain_PI_Lead) * 100 OS = format(OS, '.2f') OS = str(OS + '%') if y_PI_Lead[0] == 0: dcgain_PI_Lead = 0.0 count = 0 count2 = -1 for i in y_PI_Lead: count = count + 1 if i == a_max: stop_value = count - 1 break for j in t_PI_Lead: count2 = count2 + 1 x_PI_Lead = np.linspace(dcgain_PI_Lead, dcgain_PI_Lead, size_PI_Lead) if self.checkBox_OS.isChecked(): OS_x = np.linspace(0, t_PI_Lead[stop_value], size_PI_Lead) OS_y = np.linspace(a_max, a_max, size_PI_Lead) OS_x1 = np.linspace(t_PI_Lead[stop_value], t_PI_Lead[stop_value], size_PI_Lead) OS_y2 = np.linspace(dcgain_PI_Lead, a_max, size_PI_Lead) else: OS_x = np.linspace(0, 0, size_PI_Lead) OS_y = np.linspace(0, 0, size_PI_Lead) OS_x1 = np.linspace(0, 0, size_PI_Lead) OS_y2 = np.linspace(0, 0, size_PI_Lead) if self.checkBox_Error.isChecked(): e_t = 0.02 * (dcgain_PI_Lead) + dcgain_PI_Lead e_b = dcgain_PI_Lead - 0.02 * (dcgain_PI_Lead) error_t_x = np.linspace(0, t_PI_Lead[count2], size_PI_Lead) error_t_y = np.linspace(e_t, e_t, size_PI_Lead) error_b_x = np.linspace(0, t_PI_Lead[count2], size_PI_Lead) error_b_y = np.linspace(e_b, e_b, size_PI_Lead) else: e_t = 0.02 * (dcgain_PI_Lead) + dcgain_PI_Lead e_b = dcgain_PI_Lead - 0.02 * (dcgain_PI_Lead) error_t_x = np.linspace(0, 0, size_PI_Lead) error_t_y = np.linspace(0, 0, size_PI_Lead) error_b_x = np.linspace(0, 0, size_PI_Lead) error_b_y = np.linspace(0, 0, size_PI_Lead) flag = -1 for i in reversed(y_PI_Lead): flag = flag + 1 if (i > e_t or i < e_b): break new_t = [] for j in reversed(t_PI_Lead): new_t.append(j) Ts = new_t[flag] if self.checkBox_Ts.isChecked(): t_s_x = np.linspace(Ts, Ts, size_PI_Lead) t_s_y = np.linspace(0, dcgain_PI_Lead, size_PI_Lead) else: t_s_x = np.linspace(0, 0, size_PI_Lead) t_s_y = np.linspace(0, 0, size_PI_Lead) self.plot4.axes.plot(t_PI_Lead, y_PI_Lead, 'k', t_PI_Lead, x_PI_Lead, 'k--', OS_x, OS_y, 'k-.', OS_x1, OS_y2, 'k-.', error_t_x, error_t_y, 'r--', error_b_x, error_b_y, 'r--', t_s_x, t_s_y, 'k--') if self.checkBox_Fill.isChecked(): self.plot4.axes.fill_between(t_PI_Lead, y_PI_Lead, dcgain_PI_Lead, color='b', alpha=0.5) else: pass self.plot4.axes.set_title('Step Response (PI-Lead)') self.plot4.axes.set_xlabel('Time (sec)') self.plot4.axes.set_ylabel('Amplitude') self.plot4.axes.grid() self.plot4.draw() self.plot4.show() z1_dis = str(z1) z2_dis = str(z2) p1_dis = str(p1) p2_dis = str(p2) Ts = format(Ts, '.2f') Ts = str(Ts + 's') return_PI_Lead = '(s' + ' ' + '+' + ' ' + z1_dis + ')' + ' ' + '(s' + ' ' + '+' + ' ' + z2_dis + ')' + '\n' + '-----------------------' + '\n' + ' ' + 's' + '(s' + ' ' + '+' + ' ' + p1_dis + ')' return_char = 'Overshoot = ' + ' ' + OS + '\n' + 'Settling Time =' + ' ' + Ts self.textBrowser.insertPlainText(return_PI_Lead) self.System_Characteristics_textBrowser.insertPlainText( return_char) if self.checkBox_3.isChecked(): self.plot2.axes.semilogx(w_PI_Lead, mag_PI_Lead, 'k') self.plot2.axes.set_title('Bode Magnitude Plot (PI-Lead)') self.plot2.axes.set_xlabel('Magnitude') self.plot2.axes.set_ylabel('Omega (w)') self.plot2.axes.grid() self.plot2.draw() self.plot2.show() self.plot3.axes.semilogx(w_PI_Lead, phase_PI_Lead, 'k') self.plot3.axes.set_title('Bode Phase Plot (PI-Lead)') self.plot3.axes.set_xlabel('Phase Angle') self.plot3.axes.set_ylabel('Omega (w)') self.plot3.axes.grid() self.plot3.draw() self.plot3.show() if selection == 'PD': N_c = [K, K * z1] Numerator = np.convolve(num, N_c) Denominator = np.polyadd(den, Numerator) system_PD = (Numerator, Denominator) t_PID, y_PID = step2(system_PD) w_PD, mag_PD, phase_PD = bode(system_PD) # %OverShoot & Settling time a_max = np.amax(y_PID) size_PID = len(t_PID) dcgain_PID = y_PID[size_PID - 1] OS = (a_max - dcgain_PID) * 100 OS = format(OS, '.2f') OS = str(OS + '%') if y_PID[0] == 0: dcgain_PID = 0.0 count = 0 count2 = -1 for i in y_PID: count = count + 1 if i == a_max: stop_value = count - 1 break for j in t_PID: count2 = count2 + 1 x_PID = np.linspace(dcgain_PID, dcgain_PID, size_PID) if self.checkBox_OS.isChecked(): OS_x = np.linspace(0, t_PID[stop_value], size_PID) OS_y = np.linspace(a_max, a_max, size_PID) OS_x1 = np.linspace(t_PID[stop_value], t_PID[stop_value], size_PID) OS_y2 = np.linspace(dcgain_PID, a_max, size_PID) else: OS_x = np.linspace(0, 0, size_PID) OS_y = np.linspace(0, 0, size_PID) OS_x1 = np.linspace(0, 0, size_PID) OS_y2 = np.linspace(0, 0, size_PID) if self.checkBox_Error.isChecked(): e_t = 0.02 * (dcgain_PID) + dcgain_PID e_b = dcgain_PID - 0.02 * (dcgain_PID) error_t_x = np.linspace(0, t_PID[count2], size_PID) error_t_y = np.linspace(e_t, e_t, size_PID) error_b_x = np.linspace(0, t_PID[count2], size_PID) error_b_y = np.linspace(e_b, e_b, size_PID) else: e_t = 0.02 * (dcgain_PID) + dcgain_PID e_b = dcgain_PID - 0.02 * (dcgain_PID) error_t_x = np.linspace(0, 0, size_PID) error_t_y = np.linspace(0, 0, size_PID) error_b_x = np.linspace(0, 0, size_PID) error_b_y = np.linspace(0, 0, size_PID) flag = -1 for i in reversed(y_PID): flag = flag + 1 if (i > e_t or i < e_b): break new_t = [] for j in reversed(t_PID): new_t.append(j) Ts = new_t[flag] if self.checkBox_Ts.isChecked(): t_s_x = np.linspace(Ts, Ts, size_PID) t_s_y = np.linspace(0, dcgain_PID, size_PID) else: t_s_x = np.linspace(0, 0, size_PID) t_s_y = np.linspace(0, 0, size_PID) self.plot4.axes.plot(t_PID, y_PID, 'k', t_PID, x_PID, 'k--', OS_x, OS_y, 'k-.', OS_x1, OS_y2, 'k-.', error_t_x, error_t_y, 'r--', error_b_x, error_b_y, 'r--', t_s_x, t_s_y, 'k--') if self.checkBox_Fill.isChecked(): self.plot4.axes.fill_between(t_PID, y_PID, dcgain_PID, color='b', alpha=0.5) else: pass self.plot4.axes.set_title('Step Response (PD)') self.plot4.axes.set_xlabel('Time (sec)') self.plot4.axes.set_ylabel('Amplitude') self.plot4.axes.grid() self.plot4.draw() self.plot4.show() z1_dis = str(z1) Ts = format(Ts, '.2f') Ts = str(Ts + 's') return_char = 'Overshoot = ' + ' ' + OS + '\n' + 'Settling Time =' + ' ' + Ts return_P = '(s' + ' ' + '+' + ' ' + z1_dis + ')' self.textBrowser.insertPlainText(return_P) self.System_Characteristics_textBrowser.insertPlainText( return_char) if self.checkBox_3.isChecked(): self.plot2.axes.semilogx(w_PD, mag_PD, 'k') self.plot2.axes.set_title('Bode Magnitude Plot (PD)') self.plot2.axes.set_xlabel('Magnitude') self.plot2.axes.set_ylabel('Omega (w)') self.plot2.axes.grid() self.plot2.draw() self.plot2.show() self.plot3.axes.semilogx(w_PD, phase_PD, 'k') self.plot3.axes.set_title('Bode Phase Plot (PD)') self.plot3.axes.set_xlabel('Phase Angle') self.plot3.axes.set_ylabel('Omega (w)') self.plot3.axes.grid() self.plot3.draw() self.plot3.show()
def step_response(num, den, amp=1, t=None): sys = signal.lti(num * amp, den) t, s = signal.step2(sys, None, t) return t, s
w, mag, phase = bode(planta, freq) fig, (ax1, ax2) = plt.subplots(2, 1) ax1.semilogx(w / 6.28, mag, 'b-', linewidth="1") ax1.set_title('Magnitude') ax2.semilogx(w / 6.28, phase, 'r-', linewidth="1") ax2.set_title('Phase') plt.tight_layout() plt.show() ### Desde aca hago pruebas temporales t = np.linspace(0, 0.1, num=2000) t, y = step2(planta, T=t) fig.clear() fig, ax = plt.subplots() ax.set_title('Respuesta escalon solo planta') ax.set_ylabel('Corriente') ax.set_xlabel('Tiempo [s]') ax.grid() ax.plot(t, y) plt.tight_layout() plt.show() ### Desde aca sistema Digital ### Convierto Forward Euler Fsampling = 1500
def test_step_invariant(self, sys, sample_time, samples_number): time = np.arange(samples_number) * sample_time _, yout_cont = step2(sys, T=time, **self.tolerances) _, yout_disc = dstep(c2d(sys, sample_time, method='zoh'), n=len(time)) assert_allclose(yout_cont.ravel(), yout_disc[0].ravel())
def get_step(self): a=signal.step(self.denorm_sys) return signal.step2(self.denorm_sys)
# -*- coding: utf-8 -*- """ Created on Fri Sep 22 17:07:26 2017 @author: Administrador """ from scipy import signal import matplotlib.pyplot as plt sys = signal.lti(3, [1, 4, 3]) # Creamos el sistema t, y = signal.step2(sys) plt.figure() plt.plot(t, y) plt.title('Respuesta al escalon') plt.xlabel('Tiempo(s)') plt.ylabel('Voltaje(V)') plt.figure() plt.plot(sys.zeros.real, sys.zeros.imag, 'o', sys.poles.real, sys.poles.imag, 'x') plt.title('Mapa de polos y ceros') plt.show()
def plot_step_response(self): t, y = signal.step2(self.transfer_function) plt.plot(t, y) plt.show()
def pulse(S, tp=(0., 1.), dt=1., tfinal=10., nosum=False): """Calculate the sampled pulse response of a CT system. ``tp`` may be an array of pulse timings, one for each input, or even a simple 2-elements tuple. **Parameters:** S : sequence A sequence of LTI objects specifying the system. The sequence S should be assembled so that ``S[i][j]`` returns the LTI system description from input ``i`` to the output ``j``. In the case of a MISO system, a unidimensional sequence ``S[i]`` is also acceptable. tp : array-like An (n, 2) array of pulse timings dt : scalar The time increment tfinal : scalar The time of the last desired sample nosum : bool A flag indicating that the responses are not to be summed **Returns:** y : ndarray The pulse response """ tp = np.asarray(tp) if len(tp.shape) == 1: if not tp.shape[0] == 2: raise ValueError("tp is not (n, 2)-shaped") tp = tp.reshape((1, tp.shape[0])) if len(tp.shape) == 2: if not tp.shape[1] == 2: raise ValueError("tp is not (n, 2)-shaped") # Compute the time increment dd = 1 for tpi in np.nditer(tp.T.copy(order='C')): _, di = rat(tpi, 1e-3) dd = lcm(di, dd) _, ddt = rat(dt, 1e-3) _, df = rat(tfinal, 1e-3) delta_t = 1. / lcm(dd, lcm(ddt, df)) delta_t = max(1e-3, delta_t) # Put a lower limit on delta_t if (isinstance(S, collections.abc.Iterable) and len(S)) \ and (isinstance(S[0], collections.abc.Iterable) and len(S[0])) \ and (isinstance(S[0][0], lti) or _is_zpk(S[0][0]) or _is_num_den(S[0][0]) \ or _is_A_B_C_D(S[0][0])): pass else: S = list(zip(S)) #S[input][output] y1 = None for Si in S: y2 = None for So in Si: _, y2i = step2(So, T=np.arange(0., tfinal + delta_t, delta_t)) if y2 is None: y2 = y2i.reshape((y2i.shape[0], 1, 1)) else: y2 = np.concatenate((y2, y2i.reshape((y2i.shape[0], 1, 1))), axis=1) if y1 is None: y1 = y2 else: y1 = np.concatenate((y1, y2), axis=2) nd = int(np.round(dt / delta_t, 0)) nf = int(np.round(tfinal / delta_t, 0)) ndac = tp.shape[0] ni = len(S) # number of inputs if ni % ndac != 0: raise ValueError( 'The number of inputs must be divisible by the number of dac timings.' ) # Original comment from the MATLAB sources: # This requirement comes from the complex case, where the number of inputs # is 2 times the number of dac timings. I think this could be tidied up. # nis: Number of inputs grouped together with a common DAC timing # (2 for the complex case) nis = int(ni / ndac) # notice len(S[0]) is the number of outputs for us tceil = int(np.ceil(tfinal / float(dt))) + 1 if not nosum: # Sum the responses due to each input set y = np.zeros((tceil, len(S[0]), nis)) else: y = np.zeros((tceil, len(S[0]), ni)) for i in range(ndac): n1 = int(np.round(tp[i, 0] / delta_t, 0)) n2 = int(np.round(tp[i, 1] / delta_t, 0)) z1 = (n1, y1.shape[1], nis) z2 = (n2, y1.shape[1], nis) yy = + np.concatenate((np.zeros(z1), y1[:nf-n1+1, :, i*nis:(i + 1)*nis]), axis=0) \ - np.concatenate((np.zeros(z2), y1[:nf-n2+1, :, i*nis:(i + 1)*nis]), axis=0) yy = yy[::nd, :, :] if not nosum: # Sum the responses due to each input set y = y + yy else: y[:, :, i] = yy.reshape(yy.shape[0:2]) return y
fig4 = figure(4) ax41 = fig4.add_subplot(111) tau_g, w_g = dsp.grp_delay_ana(bb, aa, W) tau_g2, w_g2 = dsp.grpdelay(bb, aa, analog=True, Fs=max(W)) l41, = ax41.plot(w_g, tau_g, label=zeta_label) l42, = ax41.plot(w_g2, tau_g2) ax41.set_xlabel(r'$\omega\,/\, \omega_{3dB} \; \rightarrow$') ax41.set_ylabel(r'$\tau_g (j \omega)\; \rightarrow$') ax41.set_title(r'$\mathrm{Group \, Delay \, of}\, H(j \omega) $') plt.xlim(0, 2 * W_c) ax41.legend(loc='best') # ax31.legend((l31),(r'$\tau_g \{H(j \omega)\}$')) plt.tight_layout() #=============================================================== ## Step Response #=============================================================== figure(5) sys = sig.lti(bb, aa) T = arange(0, 5, 0.05) t, y = sig.step2(sys, T=T, N=1024) plot(t, y, label=zeta_label) title(r'Step Response $h_{\epsilon}(t)$') xlabel(r'$t \,/ \, \tau \,\; \rightarrow$') plt.legend(loc='best') plt.show()
ax1.semilogx(w / (2 * np.pi), mag_cl, 'y') ax1.set_title('Analog OpenLoop Blue, CloseLoop Yellow') ax1.set_ylabel('Amplitude P D2 [dB]', color='b') ax1.set_xlabel('Frequency [Hz]') ax1.set_ylim([-40, 40]) ax2.semilogx(w / (2 * np.pi), phase_ol, 'b') ax2.semilogx(w / (2 * np.pi), phase_cl, 'y') ax2.set_ylabel('Phase', color='r') ax2.set_xlabel('Frequency [Hz]') plt.tight_layout() plt.show() ###################################### # Realimento y veo Respuesta escalon # ###################################### t = np.linspace(0, 0.2, num=2000) t, y = step2(close_loop, T=t) fig.clear() fig, ax = plt.subplots() ax.set_title('Respuesta escalon Close Loop') ax.set_ylabel('Vout') ax.set_xlabel('Tiempo [s]') ax.grid() ax.plot(t, y) plt.tight_layout() plt.show()
numC = [0.5, 1] denC = [1, 0] polynumC = np.poly1d(numC) polydenC = np.poly1d(denC) numG1 = [1] denG1 = [0.5, 1] polynumG1 = np.poly1d(numG1) polydenG1 = np.poly1d(denG1) numG2 = [1] denG2 = [1] polynumG2 = np.poly1d(numG2) polydenG2 = np.poly1d(denG2) numH = [1] denH = [1] polynumH = np.poly1d(numH) polydenH = np.poly1d(denH) #FTR: numFTR = K * polynumC * polynumG1 * polynumG2 * polynumH denFTR = (polydenC * polydenG1 * polydenG2 * polydenH) + numFTR sysFTR = signal.lti(numFTR.coeffs, denFTR.coeffs) t, y = signal.step2(sysFTR) plt.plot(t, y) plt.grid() plt.show()
print('Plant_sense: Vsense in opamp: ') print(Plant_sense_sim) planta = sympy_to_lti(Plant_out_sim) print('Numerador Planta Sympy: ' + str(planta.num)) print('Denominador Planta Sympy: ' + str(planta.den)) z, p, k = tf2zpk(planta.num, planta.den) print('Planta Ceros: ' + str(planta.zeros)) print('Planta Polos: ' + str(planta.poles)) print('Planta K: ' + str(k)) # ### Muestro la respuesta escalon de la planta a lazo abierto # t = np.linspace(0, 0.1, num=2000) t, y = step2(planta, T=t) fig, ax = plt.subplots() ax.set_title('Respuesta de la Planta') ax.set_ylabel('Corriente') ax.set_xlabel('Tiempo [s]') ax.grid() ax.plot(t, y) # ax.show() ### Desde aca utilizo ceros y polos que entrego sympy freq = np.arange(1, 10000, 0.01) w, mag, phase = bode(planta, freq) # wc, magc, phasec = bode(control, freq) # wo, mago, phaseo = bode(openl, freq)
l31, = ax31.plot(W,angle(H)/pi,'g') l32, = ax32.plot(w_g, tau_g) ax31.set_xlabel(r'$\omega\, / \,\omega_n \; \rightarrow$') ax32.set_ylabel(r'$\tau_g \{H(j \omega)\} \; \rightarrow$') ax31.set_ylabel(r'$\angle H(j \omega)/\pi \; \rightarrow$') ax31.set_title(r'$\mathrm{Phase \, and \, Group \, Delay \, of}\, H(j \omega) $') ax31.legend((l31,l32),(r'$\angle H(j \omega) $', r'$\tau_g \{H(j \omega)\}$')) plt.tight_layout() #=============================================================== ## Step Response #=============================================================== figure(4) sys = sig.lti(bb,aa) t, y = sig.step2(sys, N=1024) plot(t, y) title(r'Step Response $h_{\epsilon}(t)$') xlabel(r'$t \; \rightarrow$') #=============================================================== ## 3D-Plots #=============================================================== xmin = -max(f); xmax = 1e-6; # cartesian range definition ymin = 0 #-max(f); ymax = max(f); # if OPT_3D_FORCE_ZMAX == True: thresh = zmax
def step_response_BF(num, den, feedback=1, t=None): sys = ctl.tf(num, den) sys_BF = g = ctl.feedback(sys, feedback) lti_BF = sys_BF.returnScipySignalLti()[0][0] t, s = signal.step2(lti_BF, None, t) return t, s
from scipy.signal import lti, step2, impulse2 import matplotlib.pyplot as plt from pylab import mpl b = [1] a = [1, 1] sys = lti(b, a) t, y = step2(sys) plt.plot(t, y) plt.hlines(0, 0, 7) plt.vlines(0, 0, 1) mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体 mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题 plt.xlabel('时间(t)') plt.ylabel('y(t)') plt.title('单位阶跃响应') plt.show()
from scipy import signal import matplotlib.pyplot as plt lti = signal.lti([1.0], [1.0, 1.0]) t, y = signal.step2(lti) plt.plot(t, y) plt.xlabel('Time [s]') plt.ylabel('Amplitude') plt.title('Step response for 1. Order Lowpass') plt.grid()
ax41 = fig4.add_subplot(111) tau_g, w_g = dsp.grp_delay_ana(bb, aa, W) tau_g2, w_g2 = dsp.grpdelay(bb, aa, analog = True, Fs = max(W)) l41, = ax41.plot(w_g, tau_g, label = zeta_label) l42, = ax41.plot(w_g2, tau_g2) ax41.set_xlabel(r'$\omega\,/\, \omega_{3dB} \; \rightarrow$') ax41.set_ylabel(r'$\tau_g (j \omega)\; \rightarrow$') ax41.set_title(r'$\mathrm{Group \, Delay \, of}\, H(j \omega) $') plt.xlim(0,2*W_c) ax41.legend(loc='best') # ax31.legend((l31),(r'$\tau_g \{H(j \omega)\}$')) plt.tight_layout() #=============================================================== ## Step Response #=============================================================== figure(5) sys = sig.lti(bb,aa) T = arange(0,5,0.05) t, y = sig.step2(sys, T = T, N=1024) plot(t, y, label = zeta_label) title(r'Step Response $h_{\epsilon}(t)$') xlabel(r'$t \,/ \, \tau \,\; \rightarrow$') plt.legend(loc='best') plt.show()
#Respuesta temporal from scipy import signal import matplotlib.pyplot as plt m = 1200 b = 75 sys_car = signal.lti(1,[m,b]) t,y = signal.step2(sys_car) plt.plot(t,2250*y) plt.grid(True) plt.xlabel("Tiempo(s)") plt.ylabel("v(m/s)") plt.title("Respuesta a escalon unitario",fontsize=13) plt.text(5,7,"Hola") plt.show()
from matplotlib import pyplot as p #Rocket League physics (using unreal units (uu)) gravity = 650 #uu/s^2 #State Space matrix coefficients mass = 14.2 M = 1 / 14.2 A = np.array([[0.0, 1.0], [0.0, 0.0]]) B = np.array([[0.0], [1.0]]) C = np.array([[1.0, 0.0], [0.0, 0.0]]) D = np.array([[0.0], [0.0]]) system = control.ss(A, B, C, D, None) #print(B) poles = np.array([-1.1, -1.0]) K = control.place(A, B, poles) k1 = K[0, 0] k2 = K[0, 1] kr = 1.33333333 #u = (-k1*(z)) + (-k2 * vz) + (kr * desz) #add desz here since equation considers xequilibrium point as center #print('u:', int(u), '/', 'z:', int(z), '/', 'vz:', int(vz), '/', int(k1), '/', int(k2)) #boostPercent = u from scipy.signal import lti, step2 sys = control.ss(A, B, C, D, None) t, y = step2(system) p.plot(t, y) time.sleep(10)
def feedback(plant, sensor=None): 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 m = 1200 b = 75 sys_car = signal.lti(1, [m, b]) k = 1200 sys_pc = series(([k], [1]), sys_car) sys_prop = feedback(sys_pc) t = np.linspace(0, 60, num=200) t, y = signal.step2(sys_prop, T=t) plt.plot(t, y) plt.plot([0, t[-1]], [1] * 2, 'k--') plt.grid(True) plt.xlabel("Tiempo(s)") plt.ylabel("(m/s)") plt.title("Control proporcional: entrada escalon (K=1200)") plt.show()
import numpy as np import sympy as sp from sympy.abc import s, t from sympy.integrals import inverse_laplace_transform from scipy import signal import matplotlib.pyplot as plt A = np.array([[0, 1], [-2, -3]]) B = np.array([[0], [1]]) C = np.array([[1, 0]]) D = 0 sys = signal.StateSpace(A, B, C, D) #State space to time domain conversion t1, y1 = signal.step2( sys) # time and output axis for natural(impulse) response Hs = 1 / (s**2 + 3 * s + 2) Us = 1 / s Ys = Hs * Us #print(Ys) y = inverse_laplace_transform(Ys, s, t) print("Unit step response =", y) # Note: "Heaviside(t)" is nothing but u(t):unit step plt.plot(t1, y1, label='Unit step response') plt.legend()
denC = [1,0] polynumC = np.poly1d(numC) polydenC = np.poly1d(denC) numG1 = [1] denG1 = [0.5, 1] polynumG1 = np.poly1d(numG1) polydenG1 = np.poly1d(denG1) numG2 = [1] denG2 = [1] polynumG2 = np.poly1d(numG2) polydenG2 = np.poly1d(denG2) numH = [1] denH = [1] polynumH = np.poly1d(numH) polydenH = np.poly1d(denH) #FTR: numFTR = K*polynumC*polynumG1*polynumG2*polynumH denFTR = (polydenC*polydenG1*polydenG2*polydenH) + numFTR sysFTR = signal.lti(numFTR.coeffs,denFTR.coeffs) t,y = signal.step2(sysFTR) plt.plot(t,y) plt.grid() plt.show()