def test_step(self): """Test function ``step``.""" figure(); plot_shape = (1, 3) #Test SISO system A, B, C, D = self.make_SISO_mats() sys = ss(A, B, C, D) #print(sys) #print("gain:", dcgain(sys)) subplot2grid(plot_shape, (0, 0)) t, y = step(sys) plot(t, y) subplot2grid(plot_shape, (0, 1)) T = linspace(0, 2, 100) X0 = array([1, 1]) t, y = step(sys, T, X0) plot(t, y) #Test MIMO system A, B, C, D = self.make_MIMO_mats() sys = ss(A, B, C, D) subplot2grid(plot_shape, (0, 2)) t, y = step(sys) plot(t, y)
def testStep(self, siso): """Test step()""" t = np.linspace(0, 1, 10) # Test transfer function yout, tout = step(siso.tf1, T=t) youttrue = np.array([0, 0.0057, 0.0213, 0.0446, 0.0739, 0.1075, 0.1443, 0.1832, 0.2235, 0.2642]) np.testing.assert_array_almost_equal(yout, youttrue, decimal=4) np.testing.assert_array_almost_equal(tout, t) # Test SISO system with direct feedthrough sys = siso.ss1 youttrue = np.array([9., 17.6457, 24.7072, 30.4855, 35.2234, 39.1165, 42.3227, 44.9694, 47.1599, 48.9776]) yout, tout = step(sys, T=t) np.testing.assert_array_almost_equal(yout, youttrue, decimal=4) np.testing.assert_array_almost_equal(tout, t) # Play with arguments yout, tout = step(sys, T=t, X0=0) np.testing.assert_array_almost_equal(yout, youttrue, decimal=4) np.testing.assert_array_almost_equal(tout, t) X0 = np.array([0, 0]) yout, tout = step(sys, T=t, X0=X0) np.testing.assert_array_almost_equal(yout, youttrue, decimal=4) np.testing.assert_array_almost_equal(tout, t) yout, tout, xout = step(sys, T=t, X0=0, return_x=True) np.testing.assert_array_almost_equal(yout, youttrue, decimal=4) np.testing.assert_array_almost_equal(tout, t)
def test_step(self): """Test function ``step``.""" figure() plot_shape = (1, 3) #Test SISO system A, B, C, D = self.make_SISO_mats() sys = ss(A, B, C, D) #print(sys) #print("gain:", dcgain(sys)) subplot2grid(plot_shape, (0, 0)) t, y = step(sys) plot(t, y) subplot2grid(plot_shape, (0, 1)) T = linspace(0, 2, 100) X0 = array([1, 1]) t, y = step(sys, T, X0) plot(t, y) #Test MIMO system A, B, C, D = self.make_MIMO_mats() sys = ss(A, B, C, D) subplot2grid(plot_shape, (0, 2)) t, y = step(sys) plot(t, y)
def test_step(self, SISO_mats, MIMO_mats, mplcleanup): """Test function ``step``.""" figure() plot_shape = (1, 3) #Test SISO system A, B, C, D = SISO_mats sys = ss(A, B, C, D) #print(sys) #print("gain:", dcgain(sys)) subplot2grid(plot_shape, (0, 0)) y, t = step(sys) plot(t, y) subplot2grid(plot_shape, (0, 1)) T = linspace(0, 2, 100) X0 = array([1, 1]) y, t = step(sys, T, X0) plot(t, y) # Test output of state vector y, t, x = step(sys, return_x=True) #Test MIMO system A, B, C, D = MIMO_mats sys = ss(A, B, C, D) subplot2grid(plot_shape, (0, 2)) y, t = step(sys) plot(t, y[:, 0, 0])
def process_data(num11, den11, num21, den21): w11 = ctrl.tf(num11, den11) w21 = ctrl.tf(num21, den21) print('результат w11={} w21={}'.format(w11, w21)) TimeLine = [] for i in range(1, 3000): TimeLine.append(i / 1000) plt.figure(0, figsize=[7, 6]) [y11, x11] = ctrl.step(w11, TimeLine) [y21, x21] = ctrl.step(w21, TimeLine) plt.plot(x11, y11, "r", label='Исходная') plt.plot(x21, y21, "b", label='Увеличенная k и уменшенная Т') plt.title('Переходная функция звена') plt.ylabel('Амплитуда') plt.xlabel('Время(с)') plt.grid(True) plt.show() [y11, x11] = ctrl.impulse(w11, TimeLine) [y21, x21] = ctrl.impulse(w21, TimeLine) plt.plot(x11, y11, "r", label='Исходная') plt.plot(x21, y21, "b", label='Увеличенная k и уменшенная Т') plt.title('Импульсная функция звена') plt.ylabel('Амплитуда') plt.xlabel('Время(с)') plt.grid(True) plt.show() ctrl.mag, ctrl.phase, ctrl.omega = ctrl.bode(w11, w21, dB=False) plt.plot() plt.show() return w11, w21
def testStep_mimo(self, mimo): """Test step for MIMO system""" sys = mimo.ss1 t = np.linspace(0, 1, 10) youttrue = np.array([9., 17.6457, 24.7072, 30.4855, 35.2234, 39.1165, 42.3227, 44.9694, 47.1599, 48.9776]) y_00, _t = step(sys, T=t, input=0, output=0) y_11, _t = step(sys, T=t, input=1, output=1) np.testing.assert_array_almost_equal(y_00, youttrue, decimal=4) np.testing.assert_array_almost_equal(y_11, youttrue, decimal=4)
def BAGUVIX(GG1, name_gg1, GG2, name_gg2, t): # функция для построения графиков характеристик topic = { 'G1': 'безынерционного звена', 'G2': 'апериодического звена', 'G3': 'интегрирующего звена', 'G4': 'реального диф. звена', 'G5': 'идеального диф. звена', } # словарь для графика if name_gg1 in topic: # определяем какой именно строим, для графика k1 = topic[name_gg1] plt.figure(1) # Вывод графиков в отдельном окне y1, t1 = con.step(GG1, t) y2, t2 = con.step(GG2, t) lines = [y1, y2] # plt.subplot(1, 1, 1) # 1цифра - количество строк в графике, 2 -тьиьтиколичество графиков в строке, 3 -номер графика lines[0], lines[1] = plt.plot(t, y1, "r", t, y2, "b") plt.legend(lines, ['h(t) для 1', 'h(t) для 2'], loc='best', ncol=2, fontsize=10) plt.title('Переходная характеристика' + '\n для ' + k1, fontsize=10) plt.ylabel('h') plt.xlabel('t, c') plt.grid() plt.figure(2) y2, t2 = con.impulse(GG2, t) y1, t1 = con.impulse(GG1, t) lines[0], lines[1] = plt.plot(t, y1, "r", t, y2, "b") plt.legend(lines, ['w(t) для 1', 'w(t) для 2'], loc='best', ncol=2, fontsize=10) plt.title('Импульсная характеристика' + '\n для ' + k1, fontsize=10) plt.ylabel('w') plt.xlabel('t, c') plt.grid() plt.figure(3) mag1, phase1, omega1 = con.bode(GG1, dB=False) # plt.plot() plt.title('Частотные характеристики' + "\n для " + k1, fontsize=10, y=2.2) mag1, phase1, omega1 = con.bode(GG2, dB=False) plt.plot() plt.title('Частотные характеристики' + "\n для " + k1, fontsize=10, y=2.2) plt.show()
def stepResponse(Ts): num = Poly(Ts.as_numer_denom()[0],s).all_coeffs() den = Poly(Ts.as_numer_denom()[1],s).all_coeffs() tf = matlab.tf(map(float,num),map(float,den)) y,t = matlab.step(tf) plt.plot(t,y) plt.title("Step Response") plt.grid() plt.xlabel("time (s)") plt.ylabel("y(t)") info = "OS:%f%s"%(round((y.max()/y[-1]-1)*100,2),'%') try: i10 = next(i for i in range(0,len(y)-1) if y[i]>=y[-1]*.10) Tr = round(t[next(i for i in range(i10,len(y)-1) if y[i]>=y[-1]*.90)]-t[i10],2) except StopIteration: Tr = "unknown" try: Ts = round(t[next(len(y)-i for i in range(2,len(y)-1) if abs(y[-i]/y[-1])>1.02)]-t[0],2) except StopIteration: Ts = "unknown" info += "\nTr: %s"%(Tr) info +="\nTs: %s"%(Ts) print info plt.legend([info],loc=4) plt.show()
def second_var(): """ Второй способ релизации метода Зиглера-Никольса :return: время западнывания tet, постоянную времени T и коэффициент передачи k """ # получает передаточную функцию объекта управления w = SchemeBody().get_scheme_solving() t = np.linspace(0, stop=100, num=2000) y1, t1 = step(w, t) y1 = list(y1) max_dif = 0 # номер элемента в списке, имеющего максимальную разницу с предыдущим nmd = 0 for num, yy in enumerate(y1[1:]): if (yy - y1[num]) > max_dif: max_dif, nmd = (yy - y1[num]), (num + 1) if y1[num - 1] < y1[num] > y1[ num + 1]: # дошли до первого максимума, отбой break # находим время запаздывания и постоянную времени через уравенение прямой tet = -y1[nmd] / (y1[nmd] - y1[nmd - 1]) * (t[nmd] - t[nmd - 1]) + t[nmd] T = (y1[-1] - y1[nmd]) / (y1[nmd] - y1[nmd - 1]) * (t[nmd] - t[nmd - 1]) + t[nmd] return tet, T, y1[num]
def plot_Res(t, y, g): #%matplotlib qt Y, T = mt.step(g, t) plt.plot(T, Y) plt.plot(t, y) plt.grid() plt.show()
def create_Plot(var,name,num, den): W=ml.tf(num,den) if var!=5: #Переходная функция plt.figure().canvas.set_window_title(name) y,x=ml.step(W,timeVector) plt.plot(x,y,"b") plt.title('Переходная функция') plt.ylabel('Амплитуда, о.е.') plt.xlabel('Время, с.') plt.grid(True) #TimeLine=[] #for i in range(0;3000): # TimeLine = [i/1000] plt.show() #Импульсная функция plt.figure().canvas.set_window_title(name) y,x=ml.impulse(W, timeVector) plt.plot(x,y,"r") plt.title('Импульсная функция') plt.ylabel('Амплитуда, о.е.') plt.xlabel('Время, с.') plt.grid(True) plt.show() #Диаграмма Боде plt.figure().canvas.set_window_title(name) mag, phase, omega = ml.bode(W, dB=False) plt.plot() plt.xlabel('Частота, Гц') plt.show() return
def pidplot(num, den, Kp, Ki, Kd, desired_settle=1.): ''' Plot system step response when open loop system is subjected to feedback PID compensation. Also plots 2% settling lines, and a vertical line at a desired settling time. y, t =pidplot(num,den,Kp,Ki,Kd,desired_settle=1.) Parameters: :param num: [array-like], coefficients of numerator of open loop transfer function :param den: [array-like], coefficients of denominator of open loop transfer function :param Kp: [float] Proportional gain :param Ki: [float] Integral gain :param Kd: [float] Derivative gain :param desired_settle: [float] Desired settling time, for tuning PID controllers, default = 1.0 Returns: :return: y: [array-like] time step response :return: t: [array-like] time vector ''' numc = [Kd, Kp, Ki] denc = [0, 1, 0] numcg = convolve(numc, num) dencg = convolve(denc, den) Gfb = feedback(tf(numcg, dencg), 1) y, t = step(Gfb) yss = dcgain(Gfb) plot(t, y, 'r') plot(t, 1.02 * yss * ones(len(t)), 'k--') plot(t, 0.98 * yss * ones(len(t)), 'k--') plot(desired_settle * ones(15), linspace(0, yss + 0.25, 15), 'b-.') xlim(0) xlabel('Time [s]') ylabel('Magnitude') grid() show() return y, t
def test_dcgain_2(self): """Test function dcgain with different systems""" #Create different forms of a SISO system A, B, C, D = self.make_SISO_mats() num, den = scipy.signal.ss2tf(A, B, C, D) # numerator is only a constant here; pick it out to avoid numpy warning Z, P, k = scipy.signal.tf2zpk(num[0][-1], den) sys_ss = ss(A, B, C, D) #Compute the gain with ``dcgain`` gain_abcd = dcgain(A, B, C, D) gain_zpk = dcgain(Z, P, k) gain_numden = dcgain(np.squeeze(num), den) gain_sys_ss = dcgain(sys_ss) # print('gain_abcd:', gain_abcd, 'gain_zpk:', gain_zpk) # print('gain_numden:', gain_numden, 'gain_sys_ss:', gain_sys_ss) #Compute the gain with a long simulation t = linspace(0, 1000, 1000) y, _t = step(sys_ss, t) gain_sim = y[-1] # print('gain_sim:', gain_sim) #All gain values must be approximately equal to the known gain assert_array_almost_equal( [gain_abcd, gain_zpk, gain_numden, gain_sys_ss, gain_sim], [0.026948, 0.026948, 0.026948, 0.026948, 0.026948], decimal=6)
def step_sys(sys, final_time, setpoint): # open-loop system transfer function try: num, den = model(sys) except: # for error detection print("Err: system in not defined") return Gs = control.tf(num, den) #print(Gs) # closed-loop unity-feedback transfer function Ts = control.feedback(Gs, 1) # simulation time parameters initial_time = 0 nsteps = 40 * final_time # number of time steps t = np.linspace(initial_time, final_time, round(nsteps)) output, t = matlab.step(Ts, t) output = setpoint*output # covert numpy arrays to lists t = list(t) output = list(output) # round lists to 6 decimal digits ndigits = 6 t = [round(num, ndigits) for num in t] output = [round(num, ndigits) for num in output] return t, output
def assert_systems_behave_equal(self, sys1, sys2): ''' Test if the behavior of two LTI systems is equal. Raises ``AssertionError`` if the systems are not equal. Works only for SISO systems. Currently computes dcgain, and computes step response. ''' #gain of both systems must be the same assert_array_almost_equal(dcgain(sys1), dcgain(sys2)) #Results of ``step`` simulation must be the same too y1, t1 = step(sys1) y2, t2 = step(sys2, t1) assert_array_almost_equal(y1, y2)
def analysis(self, w, block, which): nume = [int(n) for n in block.nume_coef] if block.deno_coef == []: deno = [1] else: deno = [int(d) for d in block.deno_coef] nume.reverse() deno.reverse() print(nume) print(deno) system = matlab.tf(nume, deno) if which == 'bode': matlab.bode(system) plt.show() elif which == 'rlocus': matlab.rlocus(system) plt.show() elif which == 'nyquist': matlab.nyquist(sys) plt.show() elif which == 'impulse': t = np.linspace(0, 3, 1000) yout, T = matlab.impulse(system, t) plt.plot(T, yout) plt.axhline(0, color="b", linestyle="--") plt.xlim(0, 3) plt.show() elif which == 'step': t = np.linspace(0, 3, 1000) yout, T = matlab.step(system, t) plt.plot(T, yout) plt.axhline(1, color="b", linestyle="--") plt.xlim(0, 3) plt.show()
def assert_systems_behave_equal(self, sys1, sys2): ''' Test if the behavior of two Lti systems is equal. Raises ``AssertionError`` if the systems are not equal. Works only for SISO systems. Currently computes dcgain, and computes step response. ''' #gain of both systems must be the same assert_array_almost_equal(dcgain(sys1), dcgain(sys2)) #Results of ``step`` simulation must be the same too t, y1 = step(sys1) _t, y2 = step(sys2, t) assert_array_almost_equal(y1, y2)
def test_dcgain_2(self): """Test function dcgain with different systems""" #Create different forms of a SISO system A, B, C, D = self.make_SISO_mats() Z, P, k = scipy.signal.ss2zpk(A, B, C, D) num, den = scipy.signal.ss2tf(A, B, C, D) sys_ss = ss(A, B, C, D) #Compute the gain with ``dcgain`` gain_abcd = dcgain(A, B, C, D) gain_zpk = dcgain(Z, P, k) gain_numden = dcgain(np.squeeze(num), den) gain_sys_ss = dcgain(sys_ss) print('gain_abcd:', gain_abcd, 'gain_zpk:', gain_zpk) print('gain_numden:', gain_numden, 'gain_sys_ss:', gain_sys_ss) #Compute the gain with a long simulation t = linspace(0, 1000, 1000) y, _t = step(sys_ss, t) gain_sim = y[-1] print('gain_sim:', gain_sim) #All gain values must be approximately equal to the known gain assert_array_almost_equal([gain_abcd[0,0], gain_zpk[0,0], gain_numden[0,0], gain_sys_ss[0,0], gain_sim], [0.026948, 0.026948, 0.026948, 0.026948, 0.026948], decimal=6) #Test with MIMO system A, B, C, D = self.make_MIMO_mats() gain_mimo = dcgain(A, B, C, D) print('gain_mimo: \n', gain_mimo) assert_array_almost_equal(gain_mimo, [[0.026948, 0 ], [0, 0.026948]], decimal=6)
def test_dcgain_2(): """Test function dcgain with different systems""" #Create different forms of a SISO system A, B, C, D = make_SISO_mats() Z, P, k = scipy.signal.ss2zpk(A, B, C, D) num, den = scipy.signal.ss2tf(A, B, C, D) sys_ss = ss(A, B, C, D) #Compute the gain with ``dcgain`` gain_abcd = dcgain(A, B, C, D) gain_zpk = dcgain(Z, P, k) gain_numden = dcgain(np.squeeze(num), den) gain_sys_ss = dcgain(sys_ss) print 'gain_abcd:', gain_abcd, 'gain_zpk:', gain_zpk print 'gain_numden:', gain_numden, 'gain_sys_ss:', gain_sys_ss #Compute the gain with a long simulation t = linspace(0, 1000, 1000) _t, y = step(sys_ss, t) gain_sim = y[-1] print 'gain_sim:', gain_sim #All gain values must be approximately equal to the known gain assert_array_almost_equal([ gain_abcd[0, 0], gain_zpk[0, 0], gain_numden[0, 0], gain_sys_ss[0, 0], gain_sim ], [0.026948, 0.026948, 0.026948, 0.026948, 0.026948], decimal=6) #Test with MIMO system A, B, C, D = make_MIMO_mats() gain_mimo = dcgain(A, B, C, D) print 'gain_mimo: \n', gain_mimo assert_array_almost_equal(gain_mimo, [[0.026948, 0], [0, 0.026948]], decimal=6)
def test_dcgain_2(self): """Test function dcgain with different systems""" #Create different forms of a SISO system A, B, C, D = self.make_SISO_mats() num, den = scipy.signal.ss2tf(A, B, C, D) # numerator is only a constant here; pick it out to avoid numpy warning Z, P, k = scipy.signal.tf2zpk(num[0][-1], den) sys_ss = ss(A, B, C, D) #Compute the gain with ``dcgain`` gain_abcd = dcgain(A, B, C, D) gain_zpk = dcgain(Z, P, k) gain_numden = dcgain(np.squeeze(num), den) gain_sys_ss = dcgain(sys_ss) # print('gain_abcd:', gain_abcd, 'gain_zpk:', gain_zpk) # print('gain_numden:', gain_numden, 'gain_sys_ss:', gain_sys_ss) #Compute the gain with a long simulation t = linspace(0, 1000, 1000) y, _t = step(sys_ss, t) gain_sim = y[-1] # print('gain_sim:', gain_sim) #All gain values must be approximately equal to the known gain assert_array_almost_equal([gain_abcd[0,0], gain_zpk[0,0], gain_numden[0,0], gain_sys_ss[0,0], gain_sim], [0.026948, 0.026948, 0.026948, 0.026948, 0.026948], decimal=6)
def testDcgain(self, siso): """Test dcgain() for SISO system""" # Create different forms of a SISO system using scipy.signal A, B, C, D = siso.ss1.A, siso.ss1.B, siso.ss1.C, siso.ss1.D Z, P, k = sp.signal.ss2zpk(A, B, C, D) num, den = sp.signal.ss2tf(A, B, C, D) sys_ss = siso.ss1 # Compute the gain with ``dcgain`` gain_abcd = dcgain(A, B, C, D) gain_zpk = dcgain(Z, P, k) gain_numden = dcgain(np.squeeze(num), den) gain_sys_ss = dcgain(sys_ss) # print('\ngain_abcd:', gain_abcd, 'gain_zpk:', gain_zpk) # print('gain_numden:', gain_numden, 'gain_sys_ss:', gain_sys_ss) # Compute the gain with a long simulation t = linspace(0, 1000, 1000) y, _t = step(sys_ss, t) gain_sim = y[-1] # print('gain_sim:', gain_sim) # All gain values must be approximately equal to the known gain np.testing.assert_array_almost_equal( [gain_abcd, gain_zpk, gain_numden, gain_sys_ss, gain_sim], [59, 59, 59, 59, 59])
def plot_trans_func(w, toFindT=False, toPlotTrans=False): """ функция находит и возвращает период переходной характеристики """ t = np.linspace(0, stop=100, num=2000) y1, t1 = step(w, t) t = list(t) if toPlotTrans: plt.plot(t, y1, "r") plt.title('Step Response') plt.ylabel('Amplitude h(t)') plt.xlabel('Time(sec)') plt.grid(True) plt.show() if toFindT: two_maxes = [] for num in range(len(y1[1:-1])): if y1[num - 1] < y1[num] > y1[num + 1]: two_maxes.append(num) if len(two_maxes) == 2: break return t[two_maxes[1]] - t[two_maxes[0]]
def grafic_stepw(f, name): y1, x1 = cm.step(f, TimeLine) plt.plot(x1, y1, "b") plt.title('Переходная функция {}'.format(name)) plt.ylabel('Амплитудное значение') plt.xlabel('Время(c)') plt.grid(True, linewidth=1, alpha=0.5) plt.show()
def degrau(G): y1,t1 = co.step(co.feedback(G,1)) plt.figure() plt.plot(t1,y1) plt.title("Step") plt.xlabel("Tempo[s]") plt.ylabel("Amplitude") plt.grid() print( co.stepinfo(co.feedback(G,1)))
def residuals(p, y, t): [k,alpha] = p print(k, type(k)) alpha = p[1] print(alpha, type(alpha)) g = tf(k,[1,alpha,0]) Y,T = mt.step(g,t) err=y-Y return err
def pereh(W, t): plt.figure(1) # Вывод графиков в отдельном окне y1, t = con.step(W, t) lines = [y1] lines[0] = plt.plot(t, y1, "r") plt.legend(lines[0], ['h(t) для 1'], loc='best', fontsize=10) plt.title('Переходная характеристика', fontsize=10) plt.ylabel('h') plt.xlabel('t, c') plt.grid() plt.show()
def get_trans_func(self): print(self.w) y1, t1 = step(self.w, self.t) plt.plot(self.t, y1, "r") plt.title('Step Response') plt.ylabel('Amplitude h(t)') plt.xlabel('Time(sec)') plt.grid(True) plt.show() return
def step_response(self): if self._verbose: print("[PID Design] Calculating PID gains") pid_tf, closedLoop_tf = self.pid_design() end_time = 5 # [s] npts = int(old_div(end_time, self._dt)) + 1 T = np.linspace(0, end_time, npts) yout, T = cnt.step(closedLoop_tf, T) u, _, _ = cnt.lsim(pid_tf, 1 - yout, T) return T, u, yout
def action_pid(sys, final_time, setpoint, Kp, Ki, Kd): # open-loop system transfer function try: num, den = model(sys) except: # for error detection print("Err: system in not defined") return Gs = control.tf(num, den) s = matlab.tf('s') Ds = Kp + Ki/s + Kd*s # closed-loop unity-feedback transfer function Ts = control.feedback(Ds*Gs, 1) # simulation time parameters initial_time = 0 nsteps = 40 * int(final_time) # number of time steps t = np.linspace(initial_time, final_time, round(nsteps)) output, t = matlab.step(Ts, t) output = setpoint*output # calculate list of error setpoint_arr = setpoint * np.ones(nsteps) err = setpoint_arr - output action = [] sum = 0 for i in range(len(err)): if i == 0: action.append(Kp*err[i] + Kd*(err[i]-0)/t[1]) else: sum += t[1]*(err[i]+err[i-1])/2 action.append(Kp*err[i] + Kd*(err[i]-err[i - 1])/t[1] + Ki * sum) # round lists to 6 decimal digits ndigits = 6 t = [round(num, ndigits) for num in t] action = [round(num, ndigits) for num in action] # calculate maximum control action max_action = max(action) min_action = min(action) return t, action, min_action, max_action
def action_zpk(sys, final_time, setpoint, z, p, k): # open-loop system transfer function try: num, den = model(sys) except: # for error detection print("Err: system in not defined") return Gs = control.tf(num, den) z = np.array([z]) p = np.array([p]) num, den = matlab.zpk2tf(z, p, k) Ds = matlab.tf(num, den) # closed-loop unity-feedback transfer function Ts = control.feedback(Ds*Gs, 1) # simulation time parameters initial_time = 0 nsteps = 40 * int(final_time) # number of time steps t = np.linspace(initial_time, final_time, round(nsteps)) output, t = matlab.step(Ts, t) output = setpoint*output # calculate list of error setpoint_arr = setpoint * np.ones(nsteps) err = setpoint_arr - output # calculate control action action = matlab.lsim(Ds, err, t) # covert numpy arrays to lists t = list(t) action = list(action[0]) # round lists to 6 decimal digits ndigits = 6 t = [round(num, ndigits) for num in t] action = [round(num, ndigits) for num in action] # calculate maximum control action max_action = max(action) min_action = min(action) return t, action, min_action, max_action
def intergalnaya_Otsenka(W): a = 0 b = 100 n = 1000 h = (b - a) / n t = np.linspace(a, b, num=n) y, x = con.step(W, t) # х-время ПП func = 0 x0 = x[0] y0 = y[0] # нахождение площади методом трапеций for i in range(0, len(x), 1): xi = x[i] y1 = y[i] func += abs(1 * (xi - x0) - 0.5 * (y1 + y0) * (xi - x0)) x0 = xi y0 = y1 # print(func) print("Интегральная оценка за ", b, " c = ", func)
def control(s, Y, D): end = 10 G = 1 / (3 * s * (s + 1)) F = (3 * s * (s + 1)) KP, KD, KI = 16, 7, 4 H_pd = (KP + KD * s) H_pid = (KP + KD * s + KI / s) PD = cm.feedback((KP + KD * s) * G, 1) # PD controller PID = cm.feedback((KP + KD * s + KI / s) * G, 1) # PID controller PD_FF = cm.tf([1], [1]) PID_FF = cm.tf([1], [1]) # PID controller D_PD = (G) / (1 + (KP + KD * s) * (G)) D_PID = (G) / (1 + (KP + KD * s + KI / s) * (G)) # Now, according to the Example, we calculate the response of # the closed loop system to a step input of size 10: out_PD, t = cm.step(Y * PD, np.linspace(0, end, 200)) out_PID, t = cm.step(Y * PID, np.linspace(0, end, 200)) out_PD_FF, t = cm.step(Y * PD_FF, np.linspace(0, end, 200)) out_PID_FF, t = cm.step(Y * PID_FF, np.linspace(0, end, 200)) out_PD_D, t = cm.step(-D * D_PD, np.linspace(0, end, 200)) out_PID_D, t = cm.step(-D * D_PID, np.linspace(0, end, 200)) theta_PD = out_PD + out_PD_D theta_PID = out_PID + out_PID_D theta_PD_FF = out_PD_FF + out_PD_D theta_PID_FF = out_PID_FF + out_PID_D y_out, t = cm.step(Y, np.linspace(0, end, 200)) plt.plot(t, theta_PD, lw=2, label="PD") plt.plot(t, theta_PID, lw=2, label="PID") if D != 0: plt.plot(t, theta_PD_FF, lw=2, label="PD_FF") plt.plot(t, theta_PID_FF, lw=2, label="PID_FF") plt.plot(t, y_out, lw=1, label="Reference") plt.xlabel('Time') plt.ylabel('Position') plt.legend()
def step_zpk(sys, final_time, setpoint, z, p, k): # open-loop system transfer function try: num, den = model(sys) except: # for error detection print("Err: system in not defined") return Gs = control.tf(num, den) # define compensator transfer function # convert zero and pole to numpy arrays z = np.array([z]) p = np.array([p]) num, den = matlab.zpk2tf(z, p, k) Ds = matlab.tf(num, den) # Compensated open-loop transfer function DsGs = Ds*Gs # closed-loop unity-feedback transfer function Ts = control.feedback(DsGs, 1) # simulation time parameters initial_time = 0 nsteps = 40 * final_time # number of time steps t = np.linspace(initial_time, final_time, round(nsteps)) output, t = matlab.step(Ts, t) output = setpoint*output # covert numpy arrays to lists t = list(t) output = list(output) # round lists to 6 decimal digits ndigits = 6 t = [round(num, ndigits) for num in t] output = [round(num, ndigits) for num in output] return t, output
def do_direct_method(w): """ definition for analyzing regulator quality by step responce. parameters in research: - regulation time - hesistation - overshoot - degree of attenuation :return: keys for handle changing regulator quality """ def get_degree(ideal, actual): """ функция оценивает полученное значение по пятибальной шкале :param ideal: идеальное значение :param actual: реальное значение :return: оценка """ mas = [0, 1, 1.2, 1.4, 1.6, 1.8, 2] for i in range(len(mas) - 1): if mas[i] * ideal <= actual < mas[i + 1] * ideal: return len(mas) - 2 - i elif actual > mas[-1] * ideal: return 0 t = np.linspace(0, stop=100, num=2000) counter = regulation_time = t_vr_reg = integral_mean = 0 y1, t1 = step(w, t) y1 = list(y1) max_y = max(y1) last_y = y1[-1] """перерегулирование и его оценка""" overshoot = (max_y - last_y) / last_y key_per = get_degree(27, overshoot) """величина и время достижения первого максимума и их оценка""" key_vel_max = get_degree(1.1, max(y1)) key_vr_max = get_degree(1, t[y1.index(max(y1))]) two_maxes = [] for num in range(len(y1[1:-1])): if y1[num - 1] < y1[num] > y1[num + 1]: two_maxes.append(y1[num]) if len(two_maxes) == 10: break """степень затухания и ее оценка""" if len(two_maxes) <= 1: key_deg = 5.0 else: degree_of_attenuation = (1 - two_maxes[1] / two_maxes[0]) * 100 if degree_of_attenuation <= 0: key_deg = -1 else: key_deg = get_degree(1 / 6.6, 1 / degree_of_attenuation) for i in range(len(y1)): if 0.95 * last_y < y1[i] < 1.05 * last_y: """ counter - счетчик входящих в диапазон установившегося значения точек устраняет вероятность ошибки попадания условия в нулевой промежуток колебательной функции """ counter += 1 if counter == 20: # функция внутри диапазона, удовл. достаточности уст. режима. regulation_time = t[i] # номер нахождения в массиве t значения времени регулирования t_vr_reg = i break else: # функция еще не в установившемся значении counter = 0 """оценка времени регулирования""" key_reg = get_degree(15, regulation_time) """оценка показателя колебательности""" if len(two_maxes) <= 1: key_koleb = 5.0 else: koleb = two_maxes[1] / two_maxes[0] * 100 key_koleb = get_degree(1.19, koleb) """интеграл и его оценка""" for i in range(0, t_vr_reg): integral_mean = integral_mean + abs(y1[t_vr_reg] - y1[i]) * t[1] key_int = get_degree(0.3, integral_mean) # проверка системы на устойчивость poles, zeros = pzmap(w, Plot=False) if not is_sustainable(poles): return [-100] return [ key_koleb, key_reg, key_per, key_deg, key_vel_max, key_vr_max, key_int ]
#print_c2d_matlablike(syst_fake_dis) # Python: # zero order hold by default # 4.96670866519e-05 z 4.93370716897e-05 # ----------------------- # z^2 1.0 z^2 -1.97990166083 z 0.980198673307 # # Sample time: 0.01 seconds # Discrete-time transfer function. # MATLAB: # [output,t]=step(syst_fake_dis) ### OLD scipy.signal.step way! ###output, t = step(syst_fake_dis[0][0], syst_fake_dis[1])# ,T=200) # MATLAB calculates the T size automatically based on black magic different than python one, see [MATLAB]/toolbox/shared/controllib/engine/@DynamicSystem/step.m: output, t = step(syst_fake_dis) # MATLAB: # plot(output) plot(output[0]) show() # out_len = len(output) out_len = len(output[0]) print "out_len is:" print out_len print "output is:" print output[0] # input=1:650; # input(:)=1; input_ = np.ones(out_len) # [num,den]=stmcb(output,input,0,2)
8., 0., 0., 0.; \ 0., 4., 0., 0.; \ 0., 0., 1., 0.') B = np.matrix('2.; 0.; 0.; 0.') C = np.matrix('0.5, 0.6875, 0.7031, 0.5') D = np.matrix('0.') # The full system fsys = StateSpace(A,B,C,D) # The reduced system, truncating the order by 1 ord = 3 rsys = msimp.balred(fsys,ord, method = 'truncate') # Comparison of the step responses of the full and reduced systems plt.figure(1) y, t = mt.step(fsys) yr, tr = mt.step(rsys) plt.plot(t.T, y.T) plt.plot(tr.T, yr.T) # Repeat balanced reduction, now with 100-dimensional random state space sysrand = mt.rss(100, 1, 1) rsysrand = msimp.balred(sysrand,10,method ='truncate') # Comparison of the impulse responses of the full and reduced random systems plt.figure(2) yrand, trand = mt.impulse(sysrand) yrandr, trandr = mt.impulse(rsysrand) plt.plot(trand.T, yrand.T, trandr.T, yrandr.T)
def plot_sys(sys): ys, ts = step(sys) plot(ts, ys)